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”