標籤:javascript call apply bind slice
1. 首先,我們都理解在js中改變this引用有三種方法,call(), apply(), bind();
2. bind方法是改變函數內this引用,簡單不再描述;
3. 至於 call() 和 apply() 兩個方法,區別在於,前者是不定長的入參,後者是一個數組;下邊重點說apply方法使用;
原理:
我們知道js中存在一種類數組對象,比如 {0:1,length:1} 或者 DOM 對象,或者 arguments 對象;
數組只是一種特殊的對象,數組的特殊性體現在,它的鍵預設是按次序排列的整數(0,1,2...),所以數組不用為每個元素指定鍵名,而對象的每個成員都必須指定鍵名。
所以 JavaScript中的數組也可以看成是這樣的對象
var array = [1, 2, 3]; var obj = { 0: 1, 1: 2, 2: 3, length:3 }
注意了,這個length屬性很重要,有了length就可以像數組一樣遍曆這個對象了。
再來實現一個簡單的slice方法,
function slice(start, end) { var array = []; start = start ? start : 0; end = end ? end : this.length; for (var i = start, j = 0; i < end; i++, j++) { array[j] = this[i]; } return array;}
舉例:Array.prototype.slice.apply({0:1,length:1});
通過apply,將slice方法中的this指向該對象,遍曆產生新的數組對象。
注意點:
1. 使用apply 時要注意:apply或call 只是切換了函數內部 this 的調用,但是執行的方法依然是原始對象上的方法, 即使你在 Array.prototype.slice.call(obj)的 obj 上 覆蓋了slice 方法 ,依然會執行 Array 上的 slice 方法;
2. 由於apply方法(或者call方法)也可以綁定函數執行時所在的對象,但是會立即執行函數,因此不得不把綁定語句寫在一個函數體內。建議使用函數改變this指向時使用 bind 方法。
3.
bind方法每運行一次,就返回一個新函數,這會產生一些問題。比如,監聽事件的時候,不能寫成下面這樣。
element.addEventListener(‘click‘, o.m.bind(o));
上面代碼錶示,click事件綁定bind方法產生的一個匿名函數。這樣會導致無法取消綁定,所以,下面的代碼是無效的。
element.removeEventListener(‘click‘, o.m.bind(o));
正確的方法是寫成下面這樣:
var listener = o.m.bind(o);element.addEventListener(‘click‘, listener);// ...element.removeEventListener(‘click‘, listener);
理解 Array.prototype.slice.apply