热门
如果你把 null 或者 undefined 作为 this 的绑定对象传入 call、apply 或者 bind,这些值在调用时会被忽略,实际应用的是默认绑定规则:
function foo() { console.log( this.a ); } var a = 2; foo.call( null ); // 2
一种非常常见的做法是使用 apply(..) 来“展开”一个数组,并当作参数传入一个函数。
function foo(a,b) { console.log( "a:" + a + ", b:" + b ); } // 把数组“展开”成参数 foo.apply( null, [2, 3] ); // a:2, b:3 // 使用 bind(..) 进行柯里化 var bar = foo.bind( null, 2 ); bar( 3 ); // a:2, b:3
在 JavaScript 中创建一个空对象最简单的方法都是 Object.create(null)。Object.create(null) 和 {} 很 像, 但 是 并 不 会 创 建 Object.prototype 这个委托,所以它比 {}“更空”:
function foo(a,b) { console.log( "a:" + a + ", b:" + b ); } // 我们的 DMZ 空对象 var ø = Object.create( null ); // 把数组展开成参数 foo.apply( ø, [2, 3] ); // a:2, b:3 // 使用 bind(..) 进行柯里化 var bar = foo.bind( ø, 2 ); bar( 3 ); // a:2, b:3
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
注意:对于默认绑定来说,决定 this 绑定对象的并不是调用位置是否处于严格模式,而是函数体是否处于严格模式。如果函数体处于严格模式,this 会被绑定到 undefined,否则this 会被绑定到全局对象。
if (!Function.prototype.softBind) { Function.prototype.softBind = function(obj) { var fn = this; // 捕获所有 curried 参数 var curried = [].slice.call( arguments, 1 ); var bound = function() { return fn.apply( (!this || this === (window || global)) ? obj : this curried.concat.apply( curried, arguments ) ); }; bound.prototype = Object.create( fn.prototype ); return bound; }; }
function foo() { console.log("name: " + this.name); } var obj = { name: "obj" }, obj2 = { name: "obj2" }, obj3 = { name: "obj3" }; var fooOBJ = foo.softBind( obj ); fooOBJ(); // name: obj obj2.foo = foo.softBind(obj); obj2.foo(); // name: obj2 <---- 看!!! fooOBJ.call( obj3 ); // name: obj3 <---- 看! setTimeout( obj2.foo, 10 ); // name: obj <---- 应用了软绑定
箭头函数
箭头函数不适用 this 的四种标准规则,而是根据外层(函数或全局)的作用域来决定 this
function foo() { // 返回一个箭头函数 return (a) => { //this 继承自 foo() console.log( this.a ); }; } var obj1 = { a:2 }; var obj2 = { a:3 }; var bar = foo.call( obj1 ); bar.call( obj2 ); // 2, 不是 3 !
function foo() { var self = this; // this 快照 setTimeout( function(){ console.log( self.a ); }, 100 ); } var obj = { a: 2 }; foo.call( obj ); // 2
•问题标注 Q:(question)•答案标注 R:(result)•注意事项标准:A:(attention matters)•详情描述标注:D:(detail info)•总结标注:S:(summary)•分析标注:Ana:(analysis)•提示标注:T:(tips)
Q:(question)
R:(result)
A:(attention matters)
D:(detail info)
S:(summary)
Ana:(analysis)
T:(tips)