一些ES6语法之blind函数源代码分析
摘要:一些ES6语法之blind函数源代码
bind()是在ES5中加入的新特性,所以无法在所用浏览器上运行,例如IE6、7、8都不支持,因此需要手动的实现bind()函数
##### 贴出polyfill官方文档上的实现:
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1), //(1)
fToBind = this, //(3)
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP? this: oThis ||this,
aArgs.concat(Array.prototype.slice.call(arguments))); //(2)
}; //this instanceof fNOP设置一个函数只能调用bind一次,多次调用无效
fNOP.prototype = this.prototype; //(4)
fBound.prototype = new fNOP(); //(5)
return fBound;
};
}
理解:
举个例子:
var copy = function(){
var args = Array.prototype.slice.call(arguments);
console.log(args.join());
}
copy("hi","friends") //输出 hi,friends
var after = copy.bind(null,"hi","welcome");
after("dear","friend"); //输出 hi,welcome,dear,friends
(1) 'aArgs'是定义bind函数时传入的除第一个参数oThis之外的预设参数,在例子中为["hi","welcome"]
(2) 这里的'arguments'是bind绑定后返回的函数'after'调用时传入的参数,其是类数组对象,调用Array.prototype.slice.call(arguments)后转化为数组。
(3) 这里的fToBind就是被绑定的原来的函数"copy"
(4) 本来'fBound.prototype = fToBind.prototype'就可以让新函数'after'继承原来函数'copy'的所有属性,但这样新函数和原来被绑定的函数指向同一个地方,对新函数的任何修改会影响到原来被绑定的那个函数,不符合要求,所以引入fNOP这个函数作为中转,让bind绑定后返回的函数fBound指向继承了被绑定的函数fToBind的所有属性的一个新的函数fNOP,此时之后对fBound函数做的修改只会影响fNOP这个函数,而与fToBind没有任何关系
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。