大白話講 第一個參數 就是給this 這個東西 賦值,剩下的參數的意思是 用於bind 生成的新函數的參數,新函數的參數就等於 bind傳入的除了第一個參數的剩下參數,而後再加上新函數本身傳入的參數。瀏覽器
if (!Function.prototype.bind) { //若是瀏覽器不兼容 咱們就本身搞一個唄
Function.prototype.bind = function(oThis){ // oThis 就是傳入的第一個參數 目標 讓它變成this的指向
if(typeof this != 'function'){
throw new TypeError("這東西是函數的方法,別的就別用了哈~")
}
var aArgs = Array.prototype.slice.call(arguments,1), // 第一個參數不是指this嘛,咱們把剩下的參數淺拷貝一份
fToBind = this, // 這就是咱們的 this , 咱們要把這個this 改一改
fBound = function() { // 這東西 就是咱們最後返出去的 新函數 咱們要把它的 1. this改一改 2. 參數改一改
//this instanceof fBound === true時,說明返回的fBound被當作new的構造函數調用
//== false的時候說明當作了普通函數來調用,this爲bind的第一個參數
return fToBind.apply(this instanceof fBound?this:oThis,aArgs.concat(Array.prototype.slice.call(arguments)));
}
//原型鏈 再指向 原來this的原型鏈
fBound.prototype = this.prototype;
//返回咱們整的這個新函數
return fBound;
}
}
複製代碼
這樣看起來 貌似是搞定了,this也改變了,參數也搞定了,原型鏈也搞定了,是否是整完了???實際上 還有個坑app
function fn() {};
var bFn = fn.bind(null);
fn.prototype.value = 1;
console.log(bFn.prototype.value) //1
複製代碼
這是什麼鬼,這怎麼 產生新函數 還把原函數給改了 原型鏈 傳遞的明顯有問題啊 對象按引用傳遞 這樣 咱們用一箇中專的函數來處理這個問題函數
if(!Function.prototype.bind){
Function.prototype.bind = function(){
if(typeof this != "function"){
throw new TypeError("這裏報錯提示")
}
var aArgs = Array.prototype.slice.call(arguments,1),
fToBind = this,
fNOP = function() {},
fBound = function() {
return fToBind.apply(this instanceof fBound?this:oThis,aArgs.concat(Array.prototype.slice(arguments)));
}
if(this.prototype){
fNOP.prototype = this.prototype;
}
// 下行的代碼使fBound.prototype是fNOP的實例,所以
// 返回的fBound若做爲new的構造函數,new生成的新對象做爲this傳入fBound,新對象的__proto__就是fNOP的實例
fBound.prototype = new fNOP();
//搞定!~
return fBound;
}
}
複製代碼