每一个函数的this是在函数执行时绑定的,彻底取决于函数的调用位置(函数执行时地方)。 我把js中的this指向分为如下5大类数组
默认绑定时是把this绑定在window上; 若是使用严格模式,则会绑定到undefined上bash
function foo(){
console.log(this.a)
}
var a = 2
foo() // 2
复制代码
这里的this就绑定在window上,若是使用严格模式,则this指向的是undefinedapp
function foo(){
'use strict'
console.log(this.a) // typeError:this is undefined
}
var a = 2
foo() // 2
复制代码
隐式绑定指的是在调用的位置是否有上下文关系(是否被某个对象所包含),这种状况下谁调用指向谁函数
function foo(){
console.log(this.a)
}
var obj = {
a:2,
foo: foo
}
obj.foo() // 2
// 因为调用者是obj这个对象,因此foo中的this.a指向obj.a
复制代码
一个多级对象在调用方法时,this绑定在离他最近的那个对象上ui
function foo(){
console.log(this.a)
}
var obj = {
a:2,
foo: foo
}
var obj1 = {
a:3,
obj:obj
}
obj1.obj.foo() // 2
复制代码
此外,隐式绑定有一种特殊状况,就是隐式丢失 当并非直接调用某个函数或方法时,这时候会出现this绑定丢失的状况。 如下是几种绑定丢失的状况this
function foo(){
console.log(this.a)
}
var obj = {
a:2,
foo: foo
}
var baz = obj.foo
var a = 'baz'
baz() // baz
// baz函数实际上引用的是foo函数自己,所以这时候使用了默认绑定
复制代码
function foo(){
console.log(this.a)
}
var obj = {
a:2,
foo: foo
}
function doFoo(fn){
fn()
}
var a = 'baz'
doFoo(obj.foo) // baz
复制代码
显示绑定是指经过call/apply/bind绑定的this。spa
他们的区别主要以下:prototype
经过 new 构造的函数实例,this绑定在当前实例上code
function Foo(a){
this.a = a
}
var foo = new Foo(2)
console.log(foo.a) // 2
复制代码
关于构造函数new的过程,主要分为如下四步: 1.建立一个对象 2.构造这个对象的prototype等属性 3.将这个对象绑定到this 4.返回这个对象对象
箭头函数没有本身的 this,当在内部使用了 this时,它会指向最近一层做用域内的 this,箭头函数的this在定义时就肯定了。
var name = 'xiaohong';
var obj = {
name: 'xm',
sayName: () => {
console.log(this.name)
}
}
obj.sayName() // xiaohong
复制代码
此时的箭头函数和sayName是同级的,它属于obj,因为箭头函数没有this,因此它的this指向离它最近的做用域的this,即指向window。
var obj = {
name: 'xm',
sayName: function(){
return () => {
console.log(this.name);
}
}
}
obj.sayName()() //xm
复制代码
因为箭头函数没有本身的 this,当在内部使用了 this时,它会指向最近一层做用域内的 this,箭头函数的最近一层的做用域为obj内,因此它的this指向obj
var obj = {
name: 'xm',
sayName: function(){
return () => {
return () => {
return () => {
console.log(this.name);
};
};
};
}
}
obj.sayName()()()() // xm
复制代码
以上函数定义了三个箭头函数,因为三个箭头函数都不存在this,因此它的this指向了离箭头函数最近的obj.