博客
关于我
简单模拟实现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中的call、apply和bind方法,探讨了隐式丢失问题以及硬绑定解决方案的原理。通过实际代码示例,验证了不同方法在不同场景下的表现。

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

你可能感兴趣的文章
Python3中提示:no module named 'wxpy'
查看>>
python3中选择文件对话框的格式打开和保存图片
查看>>
python3为什么print永远都是地址_Python3 print 函数用法总结
查看>>
Python3之uuid模块
查看>>
Python3之写入Excel文档(xlsxwriter)
查看>>
Python3之打印操作打印流重定向(下)
查看>>
python3判断字典、列表、元组为空以及字典是否存在某个key的方法
查看>>
Python3利用pymysql操作 MySQL
查看>>
python3处理json文件中含有中文dumps的应用
查看>>
Python3子进程输出
查看>>
Python3学习笔记3,变量、运算符
查看>>
Python3学习笔记(urllib模块的使用)
查看>>
python3安装scapy_Linux下安装scapy-python3
查看>>
python3实现socket通信
查看>>
Python关于numpy.transpose函数详细解析附代码
查看>>
Python3导入自定义模块的3种方式
查看>>
python3打开txt文件_使用Python 3从文本文件读取句子并添加到列表中
查看>>
python3爬虫抓取智联招聘职位信息代码
查看>>
Python3爬虫数据入数据库---把爬取到的数据存到数据库,带数据库去重功能
查看>>
python3的 pymysql把mysqldb库取代了,让python 3支持mysqldb的解决方法
查看>>