其中的
var O = Object(this);
var len = O.length >>> 0;
這兩句話是什麼意思?
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(searchElement, fromIndex) {
var k;
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var O = Object(this);
var len = O.length >>> 0;
if (len === 0) {
return -1;
}
var n = +fromIndex || 0;
if (Math.abs(n) === Infinity) {
n = 0;
}
if (n >= len) {
return -1;
}
k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
while (k < len) {
if (k in O && O[k] === searchElement) {
return k;
}
k++;
}
return -1;
};
}
我想大声告诉你2017-06-14 10:56:26
Object(this)不是為了創建新對象,而是為了把this轉成Object,對於本身就是Object的對象自然是沒用的,例如Array和Object。
O.length >>> 0
這裡的三個大於號可不是表示總是大於等於0,而是JS的一個位運算符,表示無符號位移,後面的0表示位移0位,不過JS在執行無符號位移之前,會轉成無符號32位元整數來計算,所以>>>0
表示的就是把O.length
轉換成正整數。
為什麼要有這兩步,JS的Array不已經是個Object了? array.length本身不肯定是個非負整數了麼?那是因為這個函數是個可以通用的函數,可以使用call來讓非Array調用,舉例來說:
Array.prototype.indexOf.call("abc","c") // 2
這裡的"abc"在函數體裡是那個this,它是一個基本型,需要包裝成一個Object才能使用下面的in語法。
0 in "ab" // TypeError
0 in Object("ab") // true
而我們使用Array.prototype.indexOf方法不僅可以在基本類型上,還可以在一個非Array的Object上,這時候length是自己指定的,沒法保證是正整數了,所以在函數內部需要轉成非負整數。
var obj = {"0":"hello","1":"world",length:2.7568}
Array.prototype.indexOf.call(obj,"world") //1