手撸实现 call apply bind 原型函数

韩小韩
2021-06-23 / 4 评论 / 192 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2021年06月23日,已超过1043天没有更新,若内容或图片失效,请留言反馈。

实现call

/* 随便定义一个对象,待会将函数内的this指向指向倒这个对象 */
const obj = { name: '我是需要被绑定改变this指向的对象' }
/* 需要改变this指向的函数,没有使用call时,this指向window */
function fn(a, b) {
    console.log(`This 现在指向  ${this}`);
    console.log(`传入的 a 是 ${a} -------  b 是 ${b}`);
}
/* 
 * 
 * 重写call方法
 * _this 需要把this改变到哪个目标
 * vvhan_com 传递进来的参数
 */
Function.prototype.call = function (_this, ...vvhan_com) {
    /* 创建一个 Symbol call */
    const call = Symbol();
    /* 给传入的对象 _this 添加call元素为 this(此处this为 fn 函数体) */
    _this[call] = this
    /* 执行 _this对象 中的 call 函数,并传入参数 vvhan_com */
    _this[call](...vvhan_com);
    /* 最后删除 _this对象 中的call元素 */
    delete _this[call];
}
fn.call(obj, 1,2);

实现apply

/* 随便定义一个对象,待会将函数内的this指向指向倒这个对象 */
const obj = { name: '我是需要被绑定改变this指向的对象' }
/* 需要改变this指向的函数,没有使用apply时,this指向window */
function fn(a, b) {
    console.log(`This 现在指向  ${this}`);
    console.log(`传入的 a 是 ${a} -------  b 是 ${b}`);
}
/* 
 * 
 * 重写apply方法
 * _this 需要把this改变到哪个目标
 * vvhan_com 传递进来的参数
 */
Function.prototype.apply = function (_this, vvhan_com) {
    /* 创建一个 Symbol apply */
    const apply = Symbol();
    /* 给传入的对象 _this 添加apply元素为 this(此处this为 fn 函数体) */
    _this[apply] = this
    /* 执行 _this对象 中的 apply 函数,并传入参数 vvhan_com */
    _this[apply](...vvhan_com);
    /* 最后删除 _this对象 中的apply元素 */
    delete _this[apply];
}
fn.apply(obj, [1, 2]);

实现bind

/* 随便定义一个对象,待会将函数内的this指向指向倒这个对象 */
const obj = { name: '我是需要被绑定改变this指向的对象' }
/* 需要改变this指向的函数,没有使用bind时,this指向window */
function fn(a, b) {
    console.log(`This 现在指向  ${this}`);
    console.log(`传入的 a 是 ${a} -------  b 是 ${b}`);
}
/* 
 * 
 * 重写bind方法
 * _this 需要把this改变到哪个目标
 * vvhan_com 传递进来的参数
 */
Function.prototype.bind = function (_this, ...vvhan_com) {
    /* 创建一个 Symbol bind */
    const bind = Symbol();
    /* 给传入的对象 _this 添加bind元素为 this(此处this为 fn 函数体) */
    _this[bind] = this
    /* 返回函数 并传入参数 这里使用高阶函数接收参数 */
    return function (...vvhan_com_) {
        /* 判断参数传入点 并执行 */
        _this[bind](...vvhan_com_.length > 0 ? vvhan_com_ : vvhan_com);
        /* 最后删除 _this对象 中的bind元素 */
        delete _this[bind];
    }
}
fn.bind(obj, 1, 2);

fn.bind(obj)(1, 2);

最后总结

相同点

区别点

0

评论 (4)

取消
  1. 头像
    小白笨
    Windows 10 Windows 10 / Firefox Firefox 中国河南省郑州市河南移动郑州分公司

    画图

    回复
    1. 头像
      韩小韩 作者
      Mac OS X 10.15.7 Mac OS X 10.15.7 / Google Chrome Google Chrome 中国江苏省南京市联通
      @ 小白笨

      画图

      回复
  2. 头像
    大头爸爸
    Windows 10 Windows 10 / Google Chrome Google Chrome 中国江苏省南京市移动

    无情哈拉少 666

    回复
    1. 头像
      韩小韩 作者
      Mac OS X 10.15.7 Mac OS X 10.15.7 / Google Chrome Google Chrome 中国江苏省南京市联通
      @ 大头爸爸

      无情韩阿伟!

      回复