• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
邹天得
博客园    首页    新随笔    联系   管理    订阅  订阅
es5的bind实现

模拟实现:

if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== "function") {
      // 与 ECMAScript 5 最接近的
      // 内部 IsCallable 函数
      throw new TypeError(
        "Function.prototype.bind - what is trying " +
          "to be bound is not callable"
      );
    }

    var aArgs = Array.prototype.slice.call( arguments, 1 ),
      fToBind = this,
      fNOP = function(){},
      fBound = function(){
        return fToBind.apply(
            (
              this instanceof fNOP && oThis ? this : oThis
            ),
            aArgs.concat(
              Array.prototype.slice.call( arguments )
            )

        );
    };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
    return fBound;
  };
}

function foo(something) {
  this.a = something;
}
var obj1 = {};
var bar = foo.bind( obj1 );
bar( 2 );
console.log( obj1.a ); // 2
var baz = new bar(3);
console.log( obj1.a ); // 2
console.log( baz.a ); // 3

 =======================================

分析:

this instanceof fNOP &&
oThis ? this : oThis
// ... 以及:
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
这段代码会判断硬绑定函数是否是被new 调用,如果是的话就会使用新创建的this 替换硬绑定的this。

之所以要在new 中使用硬绑定函数,主要目的是预先设置函数的一些参数,这样在使用new 进行初始化时就可以只传入其余的参数。bind(..) 的功能之一就是可以把除了第一个参数(第一个参数用于绑定this)之外的其他参数都传给下层的函数(这种技术称为“部分应用”,是“柯里化”的一种)。举例来说:
function foo(p1,p2) {
  this.val = p1 + p2;
}
// 之所以使用null 是因为在本例中我们并不关心硬绑定的this 是什么
// 反正使用new 时this 会被修改
var bar = foo.bind( null, "p1" );
var baz = new bar( "p2" );
baz.val; // p1p2

posted on 2017-04-13 10:57  邹天得  阅读(148)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3