1.为什么要用this
this提供了一种更优雅的方式来隐式“传递”一个对象引用,更加简洁并且易于复用。
2.this两种误解
2.1 指向自身
console.log()打印了4次,说明foo()被调用了4次,但是为啥foo.count === 0? 执行foo.count = 0时候,向函数对象foo添加了一个属性count。但是函数内部代码this.count中的this并不是指向函数对象,所以虽然属性名相同,根对象并不相同。其实this.count无意中创建了一个全局变量count,它的值为NaN。
如果要从函数对象内部引用它自身,有下面两种方法:
2.2 它的作用域
在某种情况下,它是正确的,但是在其他情况下他却是错误的。但是需要明确的是,this在任何情况下都不指向函数的词法作用域。 这段代码试图通过this.bar()来引用bar函数。这是不可能成功;此外还试图使用this联通foo()和bar()的词法作用域,从而让bar()可以访问foo()作用域里的变量a,这也是不可能实现的,不能使用this来引用一个词法作用域内部的东西。
3.this到底是什么?到底是一种什么样的机制?
this是在运行的时候进行绑定的,并不是编写时候绑定的。this的绑定和函数声明的位置没有任何关系,this的指向完全取决于函数的“调用位置”。
4.调用位置
“调用位置”就是函数在代码中被调用的位置,而不是声明位置。如何找到“函数被调用的位置”?需要分析“调用栈”(就是为了到达当前执行位置所调用的所有函数),“调用位置”就是在当前正在执行的函数的前一个调用中。
5.绑定规则
函数在执行过程中调用位置如何决定this的绑定对象?首先需要找到调用位置,然后判断符合下面四条规则中的那一条(如果符合多条规则,那么是有优先级的,后面会谈到这点)。
5.1 默认绑定
在本例中,函数调用时应用了this的默认绑定,因此this指向全局对象。通过分析调用位置来看,foo()是直接使用不带任何修饰的函数引用进行调用的,因此只能使用默认绑定。
5.2 隐式绑定
隐式绑定需要考虑调用位置是否有上下文对象。
当foo()被调用时,函数引用有上下文对象obj,根据隐式绑定规则,会把函数调用中的this绑定到这个上下文对象,因此this.a 等价于 obj.a。
隐式丢失:被隐式绑定的函数会丢失绑定对象,从而应用默认绑定,因此this绑定到了全局对象或undefined(严格模式)
在本例中,虽然bar()是obj.foo的一个引用,但是它引用的是foo函数本身,因此此时bar()其实是一个不带任何修饰的函数调用,因此应用了默认绑定。
5.3显示绑定
call(...)和apply(...)方法,它们的第一个参数是一个对象,它们会把这个对象绑定到this,接着在调用函数时指定这个this。(它们的区别自行百度)
但是,显示绑定仍然无法解决前面说的丢失绑定问题,因此有下面这种方式:
5.3.1硬绑定
应用场景:创建一个包裹函数,传入所有参数并返回接收到的所有值
5.4new 绑定
前言:在Js中,构造函数只是一些使用new操作符时被调用的函数。他们并不属于某个类,也不会实例化一个类,它们只是被new操作符调用的普通函数而已。(实际上并不存在所谓"构造函数",只有对于函数的"构造调用")。
使用new来调用函数,或说发生构造函数调用时候,会执行下面操作:
. 创建一个全新的对象
. 新对象会被执行[[原型]]连接
. 这个新对象会被绑定到函数调用的this
. 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象
6 优先级
6.1 默认绑定的优先级最低
6.2 显示绑定 > 隐式绑定
6.3 new绑定 > 隐式绑定
6.4 new绑定 > 显示绑定
new 和 call/apply无法一起使用,不能通过new foo.call(obj)来直接测试,这里使用硬绑定来测试他们的优先级。
总结:new绑定 > 显示绑定 > 隐式绑定 > 默认绑定
7.规则总有例外
7.1被忽略的this
如果把null或undefined作为this的绑定对象传入call,apply,bind,这些值在调用时会被忽略,实际应用默认绑定规则:
7.2间接引用
创建一个函数的“间接引用”,在这种情况下会应用默认绑定规则
8.ES6中的箭头函数
箭头函数不使用this的四种规则标准,而是根据外层(函数或全局)作用域来决定this
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!