JS bind()方法、JS原生實現bind()

1、arguments的含義
// arguments 是一個對應於傳遞給函數的參數的類數組對象 function a(){ console.log(arguments); } a(); // Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ] a(1,2,3); // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ] 
2、Function.prototype.bind()

       bind()方法主要就是將函數綁定到某個對象,bind()會建立一個函數,函數體內的this對象的值會被綁定到傳入bind()中的第一個參數的值,例如:f.bind(obj),實際上能夠理解爲obj.f(),這時f函數體內的this天然指向的是obj;javascript

var a = { b: function() { var func = function() { console.log(this.c); } func(); }, c: 'hello' } a.b(); // undefined 這裏的this指向的是全局做用域 console.log(a.c); // hello 
var a = { b: function() { var _this = this; // 經過賦值的方式將this賦值給that var func = function() { console.log(_this.c); } func(); }, c: 'hello' } a.b(); // hello console.log(a.c); // hello 
// 使用bind方法一 var a = { b: function() { var func = function() { console.log(this.c); }.bind(this); func(); }, c: 'hello' } a.b(); // hello console.log(a.c); // hello // 使用bind方法二 var a = { b: function() { var func = function() { console.log(this.c); } func.bind(this)(); }, c: 'hello' } a.b(); // hello console.log(a.c); // hello 
// 分析:這裏的bind方法會把它的第一個實參綁定給f函數體內的this,因此裏的this即指向{x:1}對象; // 從第二個參數起,會依次傳遞給原始函數,這裏的第二個參數2便是f函數的y參數; // 最後調用m(3)的時候,這裏的3即是最後一個參數z了,因此執行結果爲1+2+3=6 // 分步處理參數的過程實際上是一個典型的函數柯里化的過程(Curry) function f(y,z){ return this.x+y+z; } var m = f.bind({x:1},2); console.log(m(3)); // 6 
// 分析:直接調用a的話,this指向的是global或window對象,因此會報錯; // 經過bind或者call方式綁定this至document對象便可正常調用 var a = document.write; a('hello'); // error a.bind(document)('hello'); // hello a.call(document,'hello'); // hello 
// 實現預約義參數 // 分析:Array.prototype.slice.call(arguments)是用來將參數由類數組轉換爲真正的數組; function list() { return Array.prototype.slice.call(arguments); } var list1 = list(1, 2, 3); // [1,2,3] // 第一個參數undefined表示this的指向,第二個參數10即表示list中真正的第一個參數,依次類推 var a = list.bind(undefined, 10); var list2 = a(); // [10] var list3 = a(1, 2, 3); // [10,1,2,3] 
3、原生js實現bind方法
// 方法一,只可綁定,不可傳參 Function.prototype.my_bind = function(context){ var self = this; return function(){ self.apply(context,arguments); } } function a(){ console.log(this.name); } a(); // '' var b = { name: 'apple' }; a.bind(b)(); // apple a.my_bind(b)(); // apple 
Function.prototype.my_bind = function() { var self = this, // 保存原函數 context = Array.prototype.shift.call(arguments), // 保存須要綁定的this上下文 // 上一行等價於 context = [].shift.call(arguments); args = Array.prototype.slice.call(arguments); // 剩餘的參數轉爲數組 return function() { // 返回一個新函數 self.apply(context, Array.prototype.concat.call(args, Array.prototype.slice.call(arguments))); } } function a(m, n, o) { console.log(this.name + ' ' + m + ' ' + n + ' ' + o); } var b = { name: 'kong' }; a.my_bind(b, 7, 8)(9); // kong 7 8 9
相關文章
相關標籤/搜索