call 方法将调用函数的 this 值设置为作为第一个参数传递的对象,在您的示例中,您正在对 Array 对象执行 Object.prototype.toString 方法。
数组对象,有自己的 toString 方法 (Array.prototype.toString),它会隐藏来自 Object.prototype 的那个,如果您调用 [].toString();,则将调用 Array.prototype 上的方法。
例如:
function test() {
alert(this);
}
test.call("Hello"); // alerts "Hello"
另一个例子:
var alice = {
firstName: 'Alice',
lastName: 'Foo',
getName: function () {
return this.firstName + ' ' + this.lastName;
}
};
var bob = {
firstName: 'Bob',
lastName: 'Bar',
};
alice.getName.call(bob); // "Bob Bar"
在上面的例子中,我们在 Bob 的对象上使用了 Alice 的 getName 方法,this 的值指向 bob,所以该方法的工作原理就像它是在第二个对象上定义的一样。
现在我们来谈谈Object.prototype.toString 方法。 JavaScript 中的所有原生对象都包含一个名为 [[Class]] 的 internal 属性,该属性包含一个字符串值,该值表示对象的分类规范定义,的可能值本机 对象是:
"Object"
"Array"
"Function"
"Date"
"RegExp"
"String"
"Number"
"Boolean"
-
"Error" 用于错误对象,例如 ReferenceError、TypeError、SyntaxError、Error 等的实例
-
"Math" 代表全局 Math 对象
-
"JSON" 用于在 ECMAScript 第 5 版中定义的全局 JSON 对象。规格。
-
"Arguments" 用于 arguments 对象(也在 ES5 规范中引入。)
-
"null"(几天前在ES5 errata中介绍过)
"undefined"
正如我之前所说的,该属性是 internal,没有办法改变它,规范没有提供任何操作符或内置函数来做到这一点,而 只有你可以通过Object.prototype.toString方法访问它的值。
这个方法返回一个由以下组成的字符串:
"[object " + this.[[Class]] + "]"
仅用于说明目的,因为无法直接访问[[Class]]。
例如:
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call(/foo/); // "[object RegExp]"
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call(new Date); // "[object Date]"
// etc...
这对于以安全的方式检测对象的种类非常有用,对于检测数组对象,这是使用最广泛的技术:
function isArray(obj) {
return Object.prototype.toString.call(obj) == '[object Array]';
}
使用instanceof 运算符可能很诱人,但如果您在跨帧 环境中工作,这种方式会导致问题,因为在一帧上创建的数组对象不会instanceof Array 另一个的构造函数。
上述方法将毫无问题地工作,因为该对象将完整地包含其[[Class]] 内部属性的值。
另见: