this的使用

1.this的默认绑定指向问题

1 .1默认绑定(非严格模式)

function foo() {
console.log( this.a );
}
var a = 2;
foo(); // 2

我们怎么知道这里应用了默认绑定呢?可以通过分析调用位置来看看 foo() 是如何调 用的。在代码中,foo() 是直接使用不带任何修饰的函数引用进行调用的,因此只能使用 默认绑定,无法应用其他规则。

1.2 使用严格模式(strict mode),那么全局对象将无法使用默认绑定,因此 this 会绑定 到 undefined:

function foo() {
"use strict";
console.log( this.a );
}
var a = 2;
foo(); // TypeError: this is undefined

1.3 这里有一个微妙但是非常重要的细节,虽然 this 的绑定规则完全取决于调用位置,但是只 有 foo() 运行在非 strict mode 下时,默认绑定才能绑定到全局对象;严格模式下与 foo() 的调用位置无关:

function foo() {
console.log( this.a );
}
var a = 2;
(function(){
"use strict";
foo(); // 2
})();

2.隐式绑定

2.1(没有隐藏上下文)

需要考虑的规则是调用位置是否有上下文对象,或者说是否被某个对象拥有或者包 含

function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
obj.foo(); // 2

function foo() {
console.log( this.a );
}
var obj2 = {
a: 42,
foo: foo
};
var obj1 = {
a: 2,
obj2: obj2
};
obj1.obj2.foo(); // 42

首先需要注意的是 foo() 的声明方式,及其之后是如何被当作引用属性添加到 obj 中的。 但是无论是直接在 obj 中定义还是先定义再添加为引用属性,这个函数严格来说都不属于 obj 对象。

2.2(有隐藏上下文)隐式丢失

function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
var bar = obj.foo; // 函数别名!
var a = "oops, global"; // a 是全局对象的属性
bar(); // "oops, global"

3.显式绑定

apply(),call()硬绑定。

function foo() {
console.log( this.a );
}
var obj = {
a:2
};
foo.call( obj ); // 2

4.new 绑定比隐式绑定优先级高,new 和 call/apply 无法一起使用,因此无法通过 new foo.call(obj1) 来直接 进行测试。

总结:

1. 函数是否在 new 中调用(new 绑定)?如果是的话 this 绑定的是新创建的对象。 var bar = new foo()

2. 函数是否通过 call、apply(显式绑定)或者硬绑定调用?如果是的话,this 绑定的是 指定的对象。 var bar = foo.call(obj2)

3. 函数是否在某个上下文对象中调用(隐式绑定)?如果是的话,this 绑定的是那个上 下文对象。 var bar = obj1.foo()

4. 如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到 undefined,否则绑定到 全局对象。 var bar = foo()

5.箭头函数不使用 this 的四种标准规则,而是根据外层(函数或者全局)作用域来决 定 this

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值