一、什么是this?

this是JavaScript语言的一个关键字,它是函数运行时在函数体内部自动生成的一个对象,只能在函数体内部使用。函数的不同使用场合,this的指向不同。

在ES5中,this永远指向最终调用它的对象。

例1:
这里最终调用函数a的对象是全局window,相当于window.a()。
所以this指向window,this.name的值为全局变量name的值 'windowsName'。var name = "windowsName";
function a () {var name = "Cherry";console.log(this.name); // windowsNameconsole.log(this); // [object Window]
}
a();
console.log(this) // [object Window]
例2:
a.fn()调用函数fn的最终对象是a,this指向对象a,所以最终的name值是'skillnull'。
window.a.fn()调用函数fn的最终对象是a,this指向a,所以最终的name值是'skillnull'。
注:由于window下的变量和方法访问和调用的时候可以省略window,所以a.fn() === window.a.fn()。
b()调用函数fn的最终对象是window,this指向window,所以最终的name值是'windowsName'。这里将a.fn赋值给变量b的时候并没有调用fn。  var name = "windowsName";
var a = {name: "skillnull",fn: function () {console.log(this.name);}
}
a.fn();  // skillnull
window.a.fn(); // skillnullvar b = a.fn;
b(); // windowsName

二、如何改变this的指向?

  • 使用 ES6 的箭头函数
    箭头函数的 this 始终指向函数定义时的 this,而非执行时。

    例3:
    注:若setTimeout推迟执行的函数是某个对象的方法,那么该方法中的this关键字将指向全局环境。
    由此可以看出a.fn2()中被setTimeout推迟执行的函数的最终调用对象是window,this指向window,
    而window中没有fn1方法,所以最终结果为错误信息:this.fn1 is not a function。
    a.fn3()中被setTimeout推迟执行的函数使用了箭头函数,此时的this指向函数定义时的this,即a,所以最终结果为:skillnull。
    a.fn4()中的函数没有被setTimeout推迟执行,最终对象仍为a,此时的this指向a,所以最终结果为:skillnull。var name = "windowsName";
    var a = {name: "skillnull",fn1: function () {console.log(this.name)},fn2: function () {// console.log(this) // asetTimeout(function () {// console.log(this) // [object Window]this.fn1()}, 100);},fn3: function () {setTimeout(() => {// console.log(this) // athis.fn1()}, 100);},fn4: function () {this.fn1()}
    };
    a.fn2() // this.fn1 is not a function
    a.fn3() // skillnull
    a.fn4() // skillnull
  • 在函数内部使用 that = this
    如果上面例子中的fn2中使用that = this改变一下this的指向,此时that属于fn2的内部变量,指向a,所以最终结果为:skillnull
    fn2: function () {var that = this;setTimeout(function () {// console.log(that) // athat.fn1()}, 100);
    }
  • new 实例化一个对象

    如果函数调用前使用了 new 关键字, 则是调用了构造函数。这看起来就像创建了新的函数,但实际上 JavaScript 函数是重新创建的对象。

    new实例化一个对象的过程如下:
    1.创建一个空对象 obj;
    2.将新创建的空对象的隐式原型指向其构造函数的显示原型。
    3.使用 call 改变 this 的指向
    4.如果无返回值或者返回一个非对象值,则将 obj 返回作为新对象;如果返回值是一个新对象的话那么直接直接返回该对象。

    伪代码表示:
    var a = new myFunction("Li", "Yafei");
    new myFunction {var obj = {};obj.__proto__ = myFunction.prototype;var result = myFunction.call(obj, "Li", "Yafei");return typeof result === 'obj' ? result : obj;
    }
  • 使用 apply、call、bind
    例4:
    call、apply、bind都可以更改this的指向,三者作用相同。
    由于a.fn赋值给全局变量b的时候没有执行,上面已经说过,此时的this指向widnow,调用b('skill', 'null')的结果为:i am skillnull
    而在调用方法b的时候使用call、apply或bind,将此时的this指向a,所以最终结果是:i am not skillnull
    var name = 'i am '
    var a = {name: "i am not ",fn: function (a, b) {console.log(this.name + a + b)}
    }var b = a.fn;
    b('skill', 'null') // i am skillnull
    b.call(a, 'skill', 'null') // i am not skillnull
    b.apply(a, ['skill', 'null']) // i am not skillnull
    b.bind(a, 'skill', 'null')() // i am not skillnull

三、call、apply、bind 和 this 的关系

从上面的文章可以看出来,其实call、apply、bind最常用的用途是更改this指向。

四、call、apply、bind三者的区别

call和apply不同之处主要在于参数的形式,call参数是一个列表,apply参数是一个数组。
       而bind会创建一个新函数,需要手动调用,bind的参数形式和call相同。

注:如果当前函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象)。

转载于:https://www.cnblogs.com/Man-Dream-Necessary/p/9995784.html

简述this,call,apply,bind之间的关系相关推荐

  1. 简述机器指令与微指令之间的关系_技术动态 | 跨句多元关系抽取

    第一部分 概述 关系抽取简介 关系抽取是从自由文本中获取实体间所具有的语义关系.这种语义关系常以三元组 <E1,R,E2> 的形式表达,其中,E1 和E2 表示实体,R 表示实体间所具有的 ...

  2. 构架、框架、设计模式之间的关系简述

    一.软件体系结构和框架的定义 软件体系结构的英文单词是"architecture". Architecture的基本词义是建筑.建筑学.建筑风格. 软件体系结构虽然根植于软件工程, ...

  3. 简述CPU,内存,硬盘,指令之间的关系

    几年前记录在云笔记上的东西,整理过来. 1.基础介绍 CPU:中央处理器(Central Processing Unit),是用来表示计算机内部元件功能的术语,CPU内部由数百万至数亿个晶体管构成. ...

  4. 通过构建城市来解释HTML,CSS和JavaScript之间的关系

    by Kevin Kononenko 凯文·科诺年科(Kevin Kononenko) 通过构建城市来解释HTML,CSS和JavaScript之间的关系 (The relationship betw ...

  5. android 如何获得activity的view对象,Android的Activity 、 Window 、 View之间的关系

    什么是Activity .View . Window? Activity:是Android 四大组件之一, 是存放View对象的容器,也是我们界面的载体,可以用来展示一个界面.它有一个SetConte ...

  6. WSGI、Flask及Werkzeug三者之间的关系

    目录 一.WSGI是什么? 二.Werkzeug是什么 三.Flask的WSGI实现 一.WSGI是什么? WSGI是一套接口规范.一个WSGI程序用以接受客户端请求,传递给应用,再返回服务器的响应给 ...

  7. 日志信息jar包 slf4j-api、slf4j-log4j12、log4j 之间的关系和使用

    slf4j-api.slf4j-log4j12.log4j 之间的关系: 首先系统包含slf4j-api作为日志接入的接口:编译时slf4j-api中public final class Logger ...

  8. 复习javascript中call,apply,bind的用法

    一直很难理解js中的call apply bind,在w3schools,mdn阅读了,也看了很多相关的文章,今天我来写下我理解的call apply bind 首先创建一个函数 function m ...

  9. React学习:组件之间的关系、参数传递-学习笔记

    文章目录 React学习:组件之间的关系.参数传递-学习笔记 父到子传递参数 子-父 父-孙 兄弟组件传参 React学习:组件之间的关系.参数传递-学习笔记 父到子传递参数 <!DOCTYPE ...

  10. call / apply / bind

    对于 call / apply / bind 来说,他们的首要目的是用于改变执行上下文的 this 指针. call / apply 对 call / apply 的使用,一般都如下,用于改变执行环境 ...

最新文章

  1. 在node.js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查
  2. SIFT 特征检测及匹配
  3. Nginx配置文件粗解
  4. [UWP小白日记-14]正则表达式
  5. QT中个数据类型的转换
  6. Windows服务二:测试新建的服务、调试Windows服务
  7. 揭秘神仙高校的课堂!网友跪了:这就是差距啊!
  8. 前端学习(2137):webpack的介绍和安装
  9. 爬虫——————爬取中金所,深交所,上交所期权数据
  10. windos dos命令
  11. C++---动态内存管理
  12. QuickBI助你成为分析师-仪表板钻取的实现
  13. 分布式服务-DUBBOX(五):集成服务生产者
  14. 准备学习研究一下语音识别 请问有哪些值得推荐的书籍 论文 及开源库?
  15. Activity、View、Window的理解一篇文章就够了
  16. 黄聪:基于jQuery+JSON的省市区三级地区联动
  17. PASCAL VOC2012数据集下载地址
  18. 计算机操作系统(第3版)课后习题答案(完整版)
  19. ios 边录音边放_iOS 录音、音频的拼接剪切以及边录边压缩转码
  20. java的学习--第一章 java基础入门

热门文章

  1. AspSpider再次开放asp.net2.0 免费空间注册
  2. 重新认识Java包的命名规则
  3. IDEA右键新建时没有Java Class选项
  4. js统计字符串中特定字符出现的个数
  5. 解决jQuery中dbclick事件触发两次click事件
  6. 28. 字符串的排列(C++版本)
  7. java实现【国密SM4】加密解密-CBC模式
  8. mac搜索不到wifi wtg_如何设置隐藏wifi 防止蹭网隐藏wifi方法【详解】
  9. mysql 5.1 开启慢查询_mysql开启慢查询
  10. python123词频统计之哈姆雷特_基于Yarn的Spark环境,统计哈姆雷特词频(1)-阿里云开发者社区...