闭包中自由变量的查找,是在函数定义的地方,向上级作用域查找,不是在函数执行的地方。
this的调用情景:
1.作为普通函数被调用。
2.使用call apply bind被调用。
3.作为对象方法被调用。
4.在class方法中被调用。
5.作为箭头函数被调用。
this取什么值是在函数被调用的时候确定的。箭头函数里的this永远指向函数定义的地方的this值。

细分之后,可以分为四种:
1.箭头函数绑定
2.关键字new绑定
3.显式绑定
4.隐式绑定
5.默认绑定
以上绑定优先级由高到低,JS引擎同时刻只会向this绑定此时存在的优先级最高的绑定。
另外,settimeout和setInterval此类函数的回调函数的this指向window,因为这两种方法是在全局环境执行的,因此执行window。

以下是绑定方式的简单例子:

function foo() { 
    console.log(this.bar); 
} 
var bar = "bar1"; 
var o2 = {bar: "bar2", foo: foo}; 
var o3 = {bar: "bar3", foo: foo}; 
foo();            // "bar1" – 默认绑定
o2.foo();          // "bar2" – 隐式绑定
o3.call({bar: "bar4"});     // "bar4"  显式绑定,使用{bar: "bar4"}作为"this" 


function foo() { 
    this.test = "test"; 
    console.log(this.bar + " " + this.test + " " + test); 
} 
var bar = "bar"; 
var test = new foo(); // "undefined test undefined"  关键字new绑定,默认返回函数foo的this。

function Person(){
  this.age = 0;
  setTimeout(function () {
    console.log(this.age);     // 输出undefined
  }, 1000);
}
var p = new Person();

function Person(){
  this.age = 10;
  setTimeout(()=> {
    console.log(this.age);     // 输出10
  }, 1000);
}
var p = new Person();
//以上是箭头函数带来的效果,本应该执行window的this,强行指向了定义时的Person函数内部,输出10。

如果把new这个关键字放在一个函数调用的前面,JS编译器会做这四件事情

1.创建一个新的空的对象
2.把这个对象链接到原型对象上
3.这个对象被绑定为this
4.如果这个函数不返回任何东西,那么就会默认return this

再举一个看似是new关键字绑定,实际上是隐式绑定的例子:

function Person() {
  this.name = "Smiley";
  this.sayName = function(){
    console.log(this);
    console.log(this.name); 
  };
}

let person = new Person();
let sayNameCopy = person.sayName;
sayNameCopy();    //结果为window  undefined

//此时的person.sayName相当于function(){
//    console.log(this);
//    console.log(this.name); 
//  };
//则let sayNameCopy = person.sayName;相当于在全局window上定义了sayNameCopy,由于window内没有name,所以this和this.name输出window和undefined

再举一个看似显示绑定,实则是箭头函数绑定的例子:

function Person() {
  this.name = "Smiley";
  this.sayName = () => {
    console.log(this);
    console.log(this.name); 
  };
}

let person = new Person();
person.sayName.call({name: "Nicolas"}); 
//结果为{name: 'Smiley', sayName: ƒ}  "Smiley"
//由于函数Person内this.name为箭头函数,所以this指向sayName被定义的函数Person内部。

爱吃鸡蛋饼
55 声望8 粉丝