美文网首页1000天日更计划
Day33:this的绑定规则

Day33:this的绑定规则

作者: 钱塘风华 | 来源:发表于2019-04-26 23:56 被阅读3次

【书名】:你不知道的JavaScript(上卷)

【作者】:Kyle Simpson

【本书总页码】:213

【已读页码】:106

1. 默认绑定(独立函数调用时)

非严格模式下,默认绑定到全局对象;严格模式下,全局对象将无法使用默认绑定,因此 this 会绑定到 undefined。

2. 隐式绑定

调用位置是否有上下文对象。

function foo() {

    console.log( this.a );

}

var obj = {

    a: 2,

    foo: foo

};

obj.foo(); // 2,this指向obj

对象属性引用链中只有最顶层或者说最后一层会影响调用位置。

function foo() {

    console.log( this.a );

}

var obj2 = {

    a: 42,

    foo: foo

};

var obj1 = {

    a: 2,

    obj2: obj2

};

obj1.obj2.foo(); // 42 this指向的是obj2

隐式绑定的特殊情况——隐式丢失

function foo() {

    console.log( this.a );

}

var obj = {

    a: 2,

    foo: foo

};

var bar = obj.foo; // 函数别名!

var a = "oops, global"; // a 是全局对象的属性

bar(); // "oops, global"

虽然 bar 是 obj.foo 的一个引用,但是实际上,它引用的是 foo 函数本身,因此此时的bar() 其实是一个不带任何修饰的函数调用,因此应用了默认绑定。

一种更微妙、更常见并且更出乎意料的情况发生在传入回调函数时:

function foo() {

    console.log( this.a );

}

function doFoo(fn) {

    // fn 其实引用的是 foo

    fn(); // <-- 调用位置!

}

var obj = {

    a: 2,

    foo: foo

};

var a = "oops, global"; // a 是全局对象的属性

doFoo( obj.foo ); // "oops, global"

参数传递其实就是一种隐式赋值,因此我们传入函数时也会被隐式赋值,所以this隐式绑定隐式丢失。

3. 显式绑定——call(..) 和 apply(..)

它们的第一个参数是一个对象,它们会把这个对象绑定到this,接着在调用函数时指定这个 this。

function foo() {

    console.log( this.a );

}

var obj = {

    a:2

 };

foo.call( obj ); // 2 this显式绑定到obj

如果传入了一个原始值(字符串类型、布尔类型或者数字类型)来当作 this 的绑定对象,这个原始值会被转换成它的对象形式(也就是new String(..)、new Boolean(..)或者new Number(..))。这通常被称为“装箱”。

function foo () {

    console.log(this.toString());

}

foo.apply('hello'); // hello 

显式绑定依然无法解决绑定丢失问题。

3.1. 硬绑定解决绑定丢失

function foo() {

    console.log( this.a );

}

var obj = {

    a:2

};

var bar = function() {

    foo.call( obj );

};

bar(); // 2

setTimeout( bar, 100 ); // 2

// 硬绑定的 bar 不可能再修改它的 this

bar.call( window ); // 2

硬绑定的典型应用场景就是创建一个包裹函数,传入所有的参数并返回接收到的所有值:

另一种使用方法是创建一个可以重复使用的辅助函数:

由于硬绑定是一种非常常用的模式,所以在 ES5 中提供了内置的方法 Function.prototype.bind,它的用法如下:

bind(..) 会返回一个硬编码的新函数,它会把参数设置为 this 的上下文并调用原始函数。

3.2. API调用的“上下文”

第三方库的许多函数,以及 JavaScript 语言和宿主环境中许多新的内置函数,都提供了一个可选的参数,通常被称为“上下文”(context),其作用和 bind(..) 一样,确保你的回调函数使用指定的 this。

这些函数实际上就是通过 call(..) 或者 apply(..) 实现了显式绑定。

4. new绑定

使用 new 来调用函数,或者说发生构造函数调用时,会自动执行下面的操作。

1. 创建(或者说构造)一个全新的对象。

2. 这个新对象会被执行[[原型]]连接。

3. 这个新对象会绑定到函数调用的this。

4. 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象。

使用 new 来调用 Foo(..) 时,会构造一个新对象并把它绑定到 Foo(..) 调用中的 this上。

相关文章

  • Day33:this的绑定规则

    【书名】:你不知道的JavaScript(上卷) 【作者】:Kyle Simpson 【本书总页码】:213 【已...

  • JS this机制

    目录 this 是什么 this 的四种绑定规则 绑定规则的优先级 绑定例外 扩展:箭头函数 this 是什么 理...

  • js中的this详细介绍

    目录this 是什么this 的四种绑定规则绑定规则的优先级绑定例外扩展:箭头函数this 是什么理解this之前...

  • Element-UI表单验证

    校验规则 表单通过rules属性绑定校验规则对象,表单项通过prop属性绑定具体校验规则 注意校验的字段必须和表单...

  • 如何正确的判断this? 箭头函数的this是什么?

    this的绑定规则有四种:默认绑定,隐式绑定,显式绑定,new绑定 。 函数是否在 new 中调用(new绑定),...

  • this

    绑定4规则: 调用new:this绑定到新创建的对象 显示绑定:使用call、apply、bind等方法 调用绑定...

  • this 的绑定规则一

    this 的第一个绑定规则是默认绑定, 即指向全局对象. 在无法应用其它三个规则时, 就会默认使用这个规则. 如果...

  • this对象

    绑定规则: 默认绑定 隐式绑定 显示绑定 new绑定 判断this 现在我们可以根据优先级来判断函数在某个调用位置...

  • JavaScript中的this关键字

    目录 一、是什么 二、为什么 三、调用位置与调用栈 四、绑定规则:默认绑定,隐性绑定,显现绑定,new绑定 五、判...

  • this的绑定规则

    首先声明,this是在运行时绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件。常见的this绑定规...

网友评论

    本文标题:Day33:this的绑定规则

    本文链接:https://www.haomeiwen.com/subject/sfvcnqtx.html