其中的
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