一步一步来理解“软绑定”

1. WHAT-概念

  • 所谓软绑定,是和硬绑定相对应的一个词
  • 绑定规则有默认绑定、隐式绑定、显式绑定、new绑定等
  • 硬绑定是显式绑定中的一种,通常情况下是通过调用函数的apply()、call()或者ES5里提供的bind()方法来实现硬绑定的
  • 硬绑定之后无法再使用隐式绑定或者显式绑定来修改this的指向(使用new绑定改变硬绑定除外)
  • 软绑定让 this在默认情况下不再指向全局对象(非严格模式)或undefined(严格模式),而是指向两者之外的一个对象(这点和硬绑定的效果相同),但是同时又保留了隐式绑定和显式绑定在之后可以修改this指向的能力

2. HOW-实现

  • 《你不知道的JavaScript 上》中的软绑定的代码实现如下:
//step 1: if "softBind" property does not exist on `Function.prototye`
// 1. 判断Function原型上是否有softBind属性
if (!Function.prototype.softBind) {

    //step 2: create a property named "softBind" on "Function.prototype" and assign to "softBind" the following function 
    // 给softBind赋值一个函数

    Function.prototype.softBind = function(obj) {

        //step 3: what is the point of assigning "this" to the variable "fn"?
        //what does "this" represent at this point in time?
        // this 保存一个指向当前执行的函数对象的指针,且只能保存函数对象
        // 这对于对外部对象的引用传递到其创建的内部对象很有用

        var fn = this,

            //step 4: I understand that "arguments" is an array-like object, i.e. "arguments" is not a true array. 
            //And what is the purpose of "curried" variable? 
            // 第一个参数是绑定的对象,故需要删除

            curried = [].slice.call( arguments, 1 ),

            bound = function bound() {

                //step 5: I understand what "apply" function does

                return fn.apply(

                    //step 6: I dont really understand how "!this" works.
                    // !this 检查 this 是否已经定义,未定义则 !this 值为 true
                    // 否则,this 为一个对象,!this 值为 false

                    (!this || 
                    
					//step 7: utterly confused... 
					// !this 值为 false,则执行该语句
					// 检查this是否等于window或global

					this === (window || global)

                    //step 8: if the above statements evaluates to "true", then use "obj", 
                    //otherwise, use "this"

                    ) ? obj : this,
                    
                    // (!this || this === (window || global)) ? obj : this
                    // 该三元表达式完整含义:this 未定义则绑定到 obj 参数
                    // this 已定义,且指向全局对象,则 this obj 参数
                    // this 已定义,不指向全局对象,则 this 指向不变

                    //step 9: can't I write "curried.concat(arguments)" instead?
                    //why the convoluted syntax?
                    // 合并两组参数

                    curried.concat.apply( curried, arguments )
                );
            };

        //step 10: Why assign the "fn.prototype" as the prototype to "bound.prototype"?
        // ???

        bound.prototype = Object.create( fn.prototype );
        return bound;
    };
}
  • bound.prototype = Object.create( fn.prototype );
  • 暂时不太理解为什么将“ fn.prototype”作为原型分配给“ bound.prototype”

参考资料

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值