本文共 2699 字,大约阅读时间需要 8 分钟。
在JavaScript中,函数的this指针在某些情况下会经历隐式丢失。这种现象通常发生在以下场景:
var a = 'window';function foo() { console.log(this.a);}var obj = { a: 'obj', foo: foo};obj.foo(); // 输出: 'obj',此时`this`指向`obj`var lose = obj.foo; // lose() 的`this`指向`window`lose(); // 输出: 'window' var a = 'window';function foo() { console.log(this.a);}var obj = { a: 'obj', foo: foo};function lose(callback) { callback();}lose(obj.foo); // 输出: 'window',此时`this`指向`window` 无论函数如何被传递,只要它没有被显式绑定,最后一次调用都会应用默认绑定规则。因此,在处理隐式丢失问题时,我们需要找到一种方法,确保函数在被调用时this指向正确的上下文。
硬绑定是一种解决隐式丢失问题的方法。它允许我们在函数被定义时,明确指定其this指针的上下文。这种绑定方式一旦建立后,无论函数如何被调用,其this指针都不会改变。
var a = 'window';function foo() { console.log(this.a);}var obj = { a: 'obj', foo: foo};lose(obj.foo); // 输出: 'window',此时`this`指向`window`// 通过硬绑定解决问题var fixTheProblem = obj.foo.bind(obj);lose(fixTheProblem); // 输出: 'obj',此时`this`指向`obj` call方法Function.prototype._call = function($this, ...parms) { var funcCaller = this; $this['caller'] = funcCaller; $this['caller'](...parms); delete $this['caller'];}; apply方法Function.prototype._apply = function($this, parmsArr) { var funcCaller = this; $this['caller'] = funcCaller; $this['caller'](...parmsArr); delete $this['caller'];}; bind方法Function.prototype._bind = function($this, ...parms) { var bindCaller = this; return function() { return bindCaller._apply($this, parms); };}; function interface4CallAndApply(caller, $this, parmsOrParmArr) { $this['caller'] = caller; $this['caller'](...parmsOrParmArr); delete $this['caller'];}Function.prototype._call = function($this, ...parms) { var funcCaller = this; interface4CallAndApply(funcCaller, $this, parms);};Function.prototype._apply = function($this, parmsArr) { var funcCaller = this; interface4CallAndApply(funcCaller, $this, parmsArr);};Function.prototype._bind = function($this, ...parms) { var bindCaller = this; return function() { return bindCaller._apply($this, parms); };}; var foo = { name: 'foo', sayHello: function(a, b) { console.log(`hello, get the parms: ${a} and ${b}`); }};var bar = { name: 'bar'};foo.sayHello._call(bar, 'Fitz', 'smart');foo.sayHello._apply(bar, ['Fitz', 'smart']);var baz = foo.sayHello._bind(bar, 'Fitz', 'smart');baz();// 测试硬绑定的应用var testHardBind = foo.sayHello._bind(bar, 'hard', 'bind');testHardBind._call(Object.create(null));// 输出: 'hello, get the parms: hard and bind' 本文通过模拟实现JavaScript中的call、apply和bind方法,探讨了隐式丢失问题以及硬绑定解决方案的原理。通过实际代码示例,验证了不同方法在不同场景下的表现。
转载地址:http://mcnuz.baihongyu.com/