Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

javascript中的this #2

Open
yangrenmu opened this issue Mar 10, 2019 · 0 comments
Open

javascript中的this #2

yangrenmu opened this issue Mar 10, 2019 · 0 comments

Comments

@yangrenmu
Copy link
Owner

引子

本文是看完《你不知道的js》这本书中关于this的介绍后写的,相当于是读书笔记,把书中的重点总结了出来。如果你看完本文还有什么不懂的话,可以直接看《你不知道的js》这本书,写的灰常好。

概要

  • 函数被new调用,this是新构建的对象;
  • 函数被硬绑定(call、apply、bind)后调用,this是指定绑定的对象;
  • 函数被持有自己的环境对象调用,this是该环境对象;
  • 函数直接被调用,this是全局对象windowstrict mode下是undefined

如果上面说的四种情况你都懂的话,本文就不太适合你了;

this是什么

this是函数执行时建立的一个绑定,指向什么是由函数执行时确定的;
所以判断this指向什么,要先看函数在哪执行,然后再判断this的指向。

判断this指向的四种规则

  • 默认绑定

函数被直接执行,this默认绑定的是window对象,严格模式下是undefined。例如:

function foo() {
  console.log(this) // window
}
foo() // 函数在直接执行,this 指向 window
  • 隐式绑定

隐式绑定需要考虑函数执行时是否有拥有者对象,this一般指向该对象。例如:

let obj = {
  foo: function () {
    console.log(this) // obj
  }
}
obj.foo() // 函数执行时有个拥有者对象 obj,所以 this 指向 obj

需要注意的是,隐式绑定会丢失它的绑定。一般会退回到默认绑定。例如:

let obj = {
  foo: function () {
    console.log(this)
  }
};
let baz = obj.foo
baz() // window,函数执行时才绑定 this,相当于直接执行,this 绑定到 window 上
obj.foo() // obj,隐式绑定,this 指向 obj

当我们传递回调函数时,隐式绑定也会丢失它的绑定。比如:

let obj = {
  foo: function () {
    console.log(this)
  }
};
function doFoo(fn) {
  fn()
}
doFoo(obj.foo) // window
// 参数传递相当于一种赋值,
// 这里是 obj.foo 赋值给 fn,fn 函数执行时,this 绑定到 window
obj.foo() // obj , 隐式绑定,this 指向 obj
  • 明确绑定

有隐式绑定就有明确绑定,它是使用call、apply、bind这些方法强行改变this的指向。比如:

function foo() {
    console.log( this.a )
}

let obj = {
    a: 2
};

foo.call( obj ); // 2, 通过 call 方法强行让 this 指向 obj
  • new 绑定

通过new生成的对象,this指向的是新生成的对象。例如:

function foo(a) {
    this.a = a
}
let bar = new foo( 2 )
console.log( bar.a ) // 2, 
// new 构建的对象,this 指向新构建出来的对象,
// 至于为什么会这样,跟 new 干了啥有关;

一些特例

  • 间接引用

看个栗子:

function foo() {
  console.log( this )
}
let o = { foo: foo }
let p = { }

o.foo() // o
(p.foo = o.foo)() // window

赋值表达式p.foo = o.foo的结果是指向函数的引用,在执行时相当于foo()this指向window

  • 箭头函数

从上面我们可以看出,this是函数执行时,才绑定的。但是箭头函数不同,箭头函数的this是编写时,被绑定到调用者的外层;比如:

function foo() {
  let fn = () => {
    console.log( this )
  }
  return fn()
}
foo() // window
@yangrenmu yangrenmu changed the title JavaScript中的this javascript中的this Mar 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant