为什么 Array.prototype.some() 转换类型?真的吗?

Why is Array.prototype.some() converting the type? Is it really?

var x = ["foo","bar"]
function eq2(elem) {return elem == this}
function eq3(elem) {return elem === this}

x.some(eq2, "foo") //true
x.some(eq3, "foo") //false

所以 x[0] 内发生的事情不是 ==="foo"

因为您将 "foo" 作为 thisArg to .some() 传递,它不能使用任意字符串作为 this - 它需要是对象引用。为此,它会自动将其包装为一个对象,因此您的代码相当于:

var x = ["foo","bar"]
function eq2(elem) {return elem == this}
function eq3(elem) {return elem === this}

x.some(eq2, new Object("foo")) //true
x.some(eq3, new Object("foo")) //false

这会将它变成字符串表示的对象,而不仅仅是原始字符串本身,因此使用类型的比较失败:

console.log("foo");
//foo
console.log(new Object("foo"));
//String {0: "f", 1: "o", 2: "o", length: 3, [[PrimitiveValue]]: "foo"}

来自MDN on this

Note that with call and apply, if the value passed as this is not an object, an attempt will be made to convert it to an object using the internal ToObject operation.

这导致将对象与原始值进行比较,其中包含:

new String('foo') == 'foo' // true

但是(正如 Vohuman 正确指出的那样):

new String('foo') !== 'foo' // true

然而,在 strict mode 中,原始值不会自动装箱,所以它在那里工作:

~function()
{
    "use strict";
    var x = ["foo", "bar"];
    function eq2(elem) {return elem == this;}
    function eq3(elem) {return elem === this;}

    document.write(x.some(eq2, "foo") + '<br>');
    document.write(x.some(eq3, "foo") + '<br>');
}();

阅读所有有用的答案后,我最终使用了:

x.indexOf("foo") > -1 //true