本文代码参考的是《前端开发核心知识进阶 从夯实基础到突破瓶颈》——作者 侯策
/*
初版,如果对返回的绑定函数传参,存在丢失参数的问题
*/
Function.prototype.badBindFn = function (context) {
var me = this
var argsArray = Array.prototype.slice.call(arguments)
/* 返回绑定函数 */
return function () {
return me.apply(context, argsArray.slice(1))
}
}
/*
改进版,如果对返回的绑定函数传参,也会拼接到bind()的参数数组中
*/
Function.prototype.bindFn = function (context) {
var meFn = this
var args = Array.prototype.slice.call(arguments, 1)
/* 返回绑定函数 */
return function () {
var innerArgs = Array.prototype.slice.call(arguments)
var finalArgs = args.concat(innerArgs)
return meFn.apply(context, finalArgs)
}
}
function foo(paramsA, paramsB) {
this.a = paramsA
this.b = paramsB
}
const objZhuGe = {}
const objWang = {}
window.onload = function () {
var badFooFunc = foo.badBindFn(objZhuGe, '诸葛亮')
badFooFunc("诸葛孔明")
console.log(objZhuGe) //诸葛亮 undefined
var fooFunc = foo.bindFn(objWang, '王朗')
fooFunc('王司徒')
console.log(objWang) //王朗 王司徒
}
运行结果:
第三个版本个人领悟能力低下,暂时啃不动,先贴在下面:
Function.prototype.bind = function(context) {
var me = this
var args = Array.prototype.slice.call(arguments, 1)
var F = function(){}
F.prototype = this.prototype //???
var bound = function(){
var innerArgs = Array.prototype.slice.call(arguments)
var finalArgs = args.concat(innerArgs)
return me.apply(this instance of F ? this : context || this, finalArgs) //???
}
bound.prototype = new F() //????
return bound
}
在MDN上也列举了polyfill两种实现方式,点击这里可以参考