this绑定

四种绑定

默认绑定

  • 默认绑定一般是绑定到 window 上,严格模式下是 undefined
  • 下面这个例子使用了 let  定义变量,属于严格模式,打印出 "undefined"
function mfoo () {
    let a = 1;
    console.log(this.a);
}
let a = 10;
mfoo();    // undefined
  • 下面这个例子使用 var 定义变量,打印出 "10"
 function mfoo () {
    var a = 1;
    console.log(this.a);
 }
 var a = 10;
 mfoo();    // 10

 

隐性绑定

 

function yfoo() {
    console.log(this.a);
}
let obj = {
    a: 10,
    yfoo: yfoo
}
yfoo();        // undefined  默认绑定 等价于window.a
obj.yfoo();    // 10 隐性绑定 函数yfoo执行的时候有了上下文对象,即obj。

 

显性绑定

  • 使用call、apply或者bind进行显性绑定
  • call 、apply 和 bind 这三者的区别
    • call 从第二个参数开始所有的参数都是原函数的参数
    • apply 只接受两个参数,且第二个参数必须是数组,这个数组代表原函数的参数列表
    • bind 只有一个参数,且不会立即执行,知识将一个值绑定到函数的 this 上,并将绑定好的函数返回。

 

function bfoo () {
    console.log(this.a);
}

let bobj = { a: 10 };
bfoo = bfoo.bind(bobj);
 
bfoo();    // 10
function xfoo () {
    console.log(this.a);
}
let xobj = {
    a: 888
}
xfoo.call(xobj);

xfoo.apply(xobj);

 

new绑定

  • 使用 new 调用函数后,函数会以自己的名字名字命名和创建一个新的对象,并返回
function nfoo () {
    this.a = 10;
    console.log(this);
}
nfoo();  // window
console.log(window.a);  // 10
let nobj = new nfoo();  // nfoo
console.log(nobj.a);  // 10
  • 如果原函数返回一个对象类型,那么将无法返回新对象,将失去绑定 this 的新对象
function nnfoo () {
    this.a = 10;
    return new String("新对象");
}
let nnobj = new nnfoo(); 
console.log(nnobj.a); // undefined
console.log(nnobj);   // 新对象

 

 

this 绑定的优先级

new 绑定 > 显式绑定 > 隐式绑定 > 默认绑定

 

总结

  • 如果函数被 new 修饰,this 绑定的是新创建的对象,例如 var bar = new foo();函数 foo 中的 this 就是一个叫 foo 新创建的对象,然后将这个对象赋给 bar,这样的绑定叫做 new 绑定。
  • 如果函数是使用 call,apply,bind 来调用的,this 绑定的 是 call,apply,bind 中的第一个参数,例如 foo.call( obj ),foo 中的 this 就是 obj,这样的绑定方式叫 显式绑定。
  • 如果函数是在某个上下文下被调用,this 绑定的就是那个上下文对象,例如 var obj = { foo: foo }; obj.foo;  foo 中的 this 就是 obj,这样的绑定叫 隐性绑定。
  • 如果都不是,即使用默认绑定。一般 this 绑定的是 this,严格模式下绑定到 undefined。

 

posted @ 2018-12-14 23:18  木瓜袋子  阅读(194)  评论(0)    收藏  举报