5、如何正确判断this的指向

5. this的指向
  • this既不指向函数自身也不指向函数的词法作用域。this是在函数被调用时发生的绑定取决于函数在哪里被调用。
5.1 this绑定有四条规则。
  • 1. 默认绑定
    this的默认绑定,指向全局对象。严格模式的this会绑定到undefined
function foo() {
  console.log(this.a)
}
var a = 2
foo()  //2
  • 2. 隐式绑定
    把函数调用中的this绑定到这个对象的上下文对象,this.aobj.a一样
function foo() {
  console.log(this.a)
}
var obj = {
  a: 2,
  foo: foo
}
obj.foo() //2
  • 3. 显示绑定
    使用callapply方法,第一个参数是一个对象即this
function foo() {
  console.log(this.a)
}
var obj = {
  a: 2
}
foo.call(obj) //2
  • 硬绑定:在callapply方法外包裹函数,ES5的内置方法Function.prototype.bind就是硬绑定
// 硬绑定
function foo(something) {
  console.log(this.a, something)
  return this.a + something
}
var obj = {
  a: 2
}
var bar = foo.bind(obj)
var b = bar(3) // 2 3
console.log(b) //5
  • 4. new绑定
    JS中的构造函数是new操作符调用普通函数,新对象会绑定到函数调用的this
function foo(a) {
  this.a = a
}
var bar = new foo(2)
console.log(bar.a) //2
5.2 判断this的方法

规则优先级从高到低

• 1. 函数是否在new中调用(new绑定)? 是,this绑定的是新创建的对象bar

var bar = new foo()

• 2. 函数是否通过call、apply(显示绑定)或者硬绑定bind? 是,this绑定的是指定的对象obj2

var bar = foo.call(obj2)

• 3. 函数是否在某个上下文对象中调用(隐式调用)? 是,this绑定的是obj1

var bar = obj1.foo()

• 4. 都不是的情况下,使用默认绑定。 严格模式下,this绑定到undefined,否则绑定到全局对象

var bar = foo()

综上:

  • 对于直接调用 foo 来说,不管 foo 函数被放在了什么地方。在非严格模式下,this 一定是window
  • 对于 obj.foo() 来说,我们只需要记住,谁调用了函数,谁就是 this,所以在这个场景下 foo 函数中的 this 就是 obj 对象
  • 对于 new 的方式来说,this 被永远绑定在了新对象上面,不会被任何方式改变 this
  • 当出现多种规则时,根据规则间的优先级来决定this的最终指向
5.3 绑定例外
  • 被忽略的this:把nullundefined作为this的绑定,传入call、apply、bind,则在这些方法调用时,会被忽略,实际应用的是默认绑定规则,绑定到全局对象(window,global

方法传入null的情况:
• 当使用apply来“展开”一个数组,并当做参数传入一个函数。
• 或bind对参数进行柯里化(预先设置一些参数)

function foo(a,b) {
  console.log("a:" + a + ", b:" + b)
}
//把数组“展开”成参数
foo.apply(null, [2,3])  //a:2, b:3
//使用bind进行柯里化
var bar = foo.bind(null, 2)
bar(3) //a:2, b:3
//使用更安全的this,
//使用Object.create(null)替代null
var= Object.create(null)
foo.bind(, 2)
  • 间接引用:容易发生在赋值的时候,会应用默认绑定
function foo() {
  console.log(this.a)
}
var a = 2
var o = {a: 3, foo: foo}
var p = {a: 4}
o.foo() //3
(p.foo() = o.foo())() //2

赋值表达式p.foo() = o.foo()的返回值是对目标函数的引用,调用位置是foo(),会应用默认绑定。

  • 软绑定:解决硬绑定不能使用隐式绑定或显式绑定修改this的问题
5.4 箭头函数
  • 不使用this的四种标准规则,根据声明时函数的外层(函数或全局)作用域来决定this
  • 箭头函数的this绑定无法被修改
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值