博客
关于我
简单模拟实现javascript中的call、apply、bind方法
阅读量:432 次
发布时间:2019-03-06

本文共 2618 字,大约阅读时间需要 8 分钟。

模拟实现JavaScript中的call、apply、bind方法

隐式丢失问题

在JavaScript中,函数的this指针在某些情况下会经历隐式丢失。这种现象通常发生在以下场景:

场景1:引用传递

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'

场景2:作为回调函数传入

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中的callapplybind方法,探讨了隐式丢失问题以及硬绑定解决方案的原理。通过实际代码示例,验证了不同方法在不同场景下的表现。

转载地址:http://mcnuz.baihongyu.com/

你可能感兴趣的文章
php一句话图片运行,【后端开发】php一句话图片木马怎么解析
查看>>
PHP三方登录,移动端与服务端交互
查看>>
Redis事务深入解析和使用
查看>>
PHP上传文件大小限制的调整 Nginx 413 Request Entity Too Large
查看>>
php上传文件找不到临时文件夹
查看>>
PHP下curl用法分析
查看>>
php与web服务器关系
查看>>
redis事务操作
查看>>
php中0,空,null和false的区别
查看>>
PHP中array_merge和array相加的区别分析
查看>>
PHP中Closure::bindTo的用法分析
查看>>
php中curl得使用
查看>>
PHP中curl特性
查看>>
PHP中date时间不对
查看>>
PHP中dirname(__FILE__)的意思
查看>>
PHP中extract()函数的妙用
查看>>
PHP中fileinfo的作用以及怎么开启fileinfo
查看>>
PHP中file_get_contents如何带上cookies
查看>>
PHP中header的作用
查看>>
PHP中implode()和explode()
查看>>