JavaScript难点系列(二):this
来源:互联网 发布:中金智德 知乎 编辑:程序博客网 时间:2024/05/29 19:06
深入了解js这门语言后,才发现它有着诸多众所周知的难点(例如:闭包、原型链、内存空间等)。有的是因为js的设计缺陷导致的,而有的则是js的优点。不管如何,总需要去学会它们,在学习过程中我觉得只看别人的文章并不能做到深刻理解,所以我决定写这一系列的文章来记录我所学习到的知识点,也方便自己以后回顾,如有写错的地方欢迎指正。
废话不多说,马上进入正题!
一、默认绑定
在看过很多种的this解读思路后,我觉得《你不知道的JavaScript(上卷)》中对this的讲解比较有操作性,即有个很明确的标准让你去判断。
默认绑定指的是在没有new绑定和显示绑定(后面会提到)的前提下解析器会运行的绑定逻辑,它的思路是:this是由调用者提供的,每个函数的this取决于函数的调用位置(也就是调用方法)。
具体的判断标准是:如果函数被一个对象所拥有,那么该函数在调用时内部的this指向该对象。如果函数是独立调用(直接不带任何修饰的函数引用进行调用),那么函数内部的this指向undefined(严格模式下)。
// 独立调用function foo() { console.log(this.a)}var a = 2foo() // undefined
独立调用中有些情况属于比较隐蔽且容易让人混淆的:
// 隐式丢失(也是属于独立调用的情况)function foo() { console.log(this.a)}var obj = { a: 2, foo: foo}var bar = obj.foo // bar引用的是foo函数本身,即相当于bar=foovar a = "global"bar() // undefined // 这里和上面的foo()独立调用同理
// 回调中的独立调用var a = 20;function foo () { console.log(this.a)}var obj = { a: 2, foo: foo}function doFoo (fn) { fn() // 相当于在此处直接调用foo()}doFoo(obj.foo)
// 被某个对象拥有function foo() { console.log(this.a)}var obj = { a: 2, foo: foo}obj.foo(); // 2
// 如果被多个对象调用,this绑定到离函数调用最近的对象function foo() { console.log(this.a)}var obj2 = { a: 42, foo: foo}var obj1 = { a: 2, obj2: obj2}obj1.obj2.foo() // 42// 离foo()最近的是obj2,所以this绑定到obj2
二、显式绑定
显式绑定是指使用函数的call()、apply()和bind()方法强制地让函数的this绑定到我们想要的对象。显式绑定的优先级比默认绑定优先级高,即如果有显式绑定出现,默认绑定的规则失效。
// call()和apply()方法的第一个参数是一样的,都是this的绑定对象。function foo() { console.log(this.a)}var obj = { a: 42}foo.call(obj) // 42foo.apply(obj) // 42
// bind()方法会返回一个新函数,新函数内部的this绑定到bind()方法的第一个参数var obj = { a: 2, foo: function() { return this.a }}var bar = obj.foobar() // undefinedvar new_bar = bar.bind(obj)new_bar() // 2
三、new绑定
new绑定是优先级最高的。使用new来调用函数时,会创建一个全新的对象,并把函数的this绑定到新对象上。
function foo(a) { this.a = a}var bar = new foo(2)console.log(bar.a) // 2
四、ES6箭头函数
ES6的最好用的新特性之一就是箭头函数了。箭头函数中的this和我们上述说的规则都没有关系,它是根据箭头函数的外层作用域来决定this(JS中只有函数作用域和全局作用域)
function foo() { setTimeout(() => { // 这里的this继承自外层作用域的this,即foo的this console.log(this.a) }, 100)}var obj = { a: 2}foo.call(obj) // 2
五、总结
以上三种绑定规则的优先级是:new绑定 > 显式绑定 > 默认绑定。所以我们在判断this时,只要按照优先级来一步一步判断就没有问题了。
- JavaScript难点系列(二):this
- JavaScript难点(二)
- JavaScript难点系列(一):内存空间
- JavaScript难点系列(三):异步编程
- JavaScript难点系列(四):作用域
- JavaScript难点系列(五):执行上下文
- Javascript 难点易错点总结(二)
- JavaScript难点系列(六):原型链与继承
- C/C++重难点总结系列(二)
- 【转载】谈谈javascript语法里一些难点问题(二)
- 谈谈javascript语法里一些难点问题(二)
- JavaScript难点——立即执行函数(二)
- JavaScript难点(一)
- 【转载】javascript技术难点(三)之this、new、apply和call详解
- javascript技术难点(三)之this、new、apply和call详解
- javascript技术难点(三)之this、new、apply和call详解
- javascript技术难点(三)之this、new、apply和call详解
- javascript技术难点(三)之this、new、apply和call详解
- 机器学习(三)决策树算法ID3的实现
- Save MySQL query results into a text or CSV file
- 离开人工智能谈共享汽车就是耍流氓
- 怪盗基德的挑战书
- BZOJ 2038 小Z的袜子 (莫队算法)
- JavaScript难点系列(二):this
- 机器学习(四)最邻近规则分类
- 唯一性约束
- 蓝桥杯_算法训练_关联矩阵
- const关键字的使用
- 蓝桥杯_算法训练_Torry的困惑(基本型)
- HDU 4474 Yet Another Multiple Problem BFS
- 【MySQL】20个经典面试题,全部答对月薪10k+
- TensorFlow入门—1