1. 程式人生 > >javascript中bind()函式實現和應用以及多次bind的結果和引數位置的思考

javascript中bind()函式實現和應用以及多次bind的結果和引數位置的思考

  • 改變物件方法裡this的值
var ob = {
	name: 'joe',
	getName: function () {
		alert(this.name);
	}
};
// 改變getName方法裡原本的this物件為新物件{name: 'haha'}
var app = ob.getName.bind({name: 'haha'});
app();
  • 改變事件處理函式裡的this值,因為在事件處理函式中的this指向的是dom元素,在某些情況下我們需要改變這個this值
$(function () {
	// 這裡的e是定義為原函式裡的引數,但是返回的新函式沒有定義引數
	// 因此相當於function(e) {}
	$('.btn').on('click', function(e) {
		alert(this.name);
	}.bind({name: 'joe'}));
});

多次繫結bind方法

那麼你有沒有想過,如果使用bind()方法多次繫結,最終得到的this會是哪個繫結的呢?
function say() {
	alert(this.x);
};
var a = say.bind({x: 1});
var b = a.bind({x: 2});
b(); // 這裡會輸出1還是2呢?
這裡我對這手機想了好久也沒繞出來,最後程式碼一些就明白了。。。那你想到結果了嗎?

那麼我們不妨先分析一下

say函式使用bind方法,穿進去了一個物件,相當於
var a = function() {
	return say.apply({x: 1});
};
如果我們對得到的函式a再進行繫結,則相當於
var b = function() {
	return a.apply({x: 2});
};
var b = function() {
	return function() {
		return say.apply({x: 1});
	}.apply({x: 2});
};
這樣雖然我們改變了函式a裡this的值,但是最後函式say裡的this的值還是由第一次繫結時的引數決定,而與函式a中的this值無關

多次繫結的結果

所以無論使用bind繫結多少次,最終原函式的this值是由第一次繫結傳的引數決定的。

多次繫結引數的順序

function say() {
	alert(this.x);
};
var a = say.bind({x: 1},1,2,3);
var b = a.bind({x: 2},4,5,6);
a(7,8,9);
b(7,8,9); 
// 此時原函式say引數的順序的怎樣的呢?
// 是[4,5,6,1,2,3,7,8,9]還是[1,2,3,4,5,6,7,8,9]
首先對say使用bind方法,會改變函式say的this值,和“內建”引數。所以
a(7,8,9)
的引數組成是:內建的引數 + 呼叫時傳入的引數 = 最終函式,即[1,2,3]+ [7,8,9] = [1,2,3,7,8,9] 而對函式a使用bind方法,只會改變函式a的this值,和往函式a裡“內建”引數。所以
b(7,8,9)
的引數組成是:[1,2,3](在函式say內建的引數) + [4,5,6](在函式a內建的引數) + [7,8,9] = [1,2,3,4,5,6,7,8,9]

總結

對哪個函式使用bind()方法即改變這個函式的this值,和內建其引數,或者說像克里化一樣理解,先預置好引數
var a = say.bind({x:1},1,2,3); // 是改變函式say的this值,和在函式say上預置引數1,2,3
var b = a.bind({x: 2}, 4,5,6); // 是改變函式a的this,和在函式a上預置預置引數4,5,6