被忽略的this和更安全的this用法

被忽略的this

如果你把 null 或者 undefined 作为 this 的绑定对象传入 call ,apply 或者 bind ,这些值在调用的时候会被忽略,实际应用的是默认绑定规则:

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

var a = 2;

foo.call( null ); //2

一种非常常见的做法是使用 apply(..)来“展开”一个数组,并当作参数传入一个参数,类似的,bind(..)可以对参数进行柯里化。

function foo(a,b){
    console.log("a:"+a,",b:"+b;
}

//将数组“展开”成参数
foo.apply( null ,[2,3]);//a:2,b:3

//使用bind(..)进行柯里化
let bar = foo.bind( null,2 );
bar( 3 ); //a:2,b:3

总是使用 null 来忽略 this 绑定可能会产生一些副作用。默认绑定会把this绑定到全局对象,如果某个函数确实使用了this,这将导致不可预计的后果(比如修改全局对象)。

更安全的this

一种"更安全"的做法是传入一个特殊的对象,把this绑定到这个对象不会对你的程序产生任何副作用,就像网络一样,我们可以创建一个"DMZ"(非军事区)对象--它就是一个空的非委托的对象。

如果我们在忽略this绑定的时总是传入一个DMZ对象,那就什么都不用担心了,因为任何对于this的使用都会被限制在这个空对象中,不会对全局对象产生任何影响。

间接引用

你可能创建一个函数的“间接引用”,在这种情况下,调用这个函数会应用默认绑定规则。

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绑定对象的并不是调用位置是否处于严格模式,而是函数体是否处于严格模式。如果函数体处于严格模式,this会被绑定到undefined,否则this会被绑定到全局对象。

Last updated