在这个Javascript语句中执行的.call()函数是什么?

时间:2010-07-14 20:47:48

标签: javascript

我正在积极学习javascript,我发现了以下声明:

Object.prototype.toString.call([]); 

我不知道它的意义或作用。

我对.call有一个模糊的理解,因为它允许你在一个不同的对象(我认为)的上下文中调用一个方法,但是我很难理解{{1函数正在上面的语句中播放。所以我想知道是否有人能解释.call()在这里做了什么?

谢谢!

2 个答案:

答案 0 :(得分:27)

call方法将被调用函数的this值设置为作为第一个参数传递的对象,在您的示例中,您正在对Array对象执行Object.prototype.toString方法。 / p>

如果您在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]]内部属性,此属性包含一个字符串值,表示对象定义的分类,<的可能值em> native 对象是:

  • "Object"
  • "Array"
  • "Function"
  • "Date"
  • "RegExp"
  • "String"
  • "Number"
  • "Boolean"
  • "Error"用于错误对象,例如ReferenceErrorTypeErrorSyntaxErrorError等实例
  • 全局"Math"对象的
  • Math
  • "JSON",用于ECMAScript 5th Ed上定义的全局JSON对象。规格。
  • {li> "Arguments"代表arguments对象(也在ES5规范中引入)
  • "null"(仅在几天前在ES5 errata中介绍)
  • "undefined"

正如我之前所说的,属性是内部,没有办法改变它,规范没有提供任何操作符或内置函数来执行它,而 >只有方式可以通过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]]内部属性的值。

另见:

答案 1 :(得分:1)

因为toString主要不是通过参数调用的,而不是toString('foo'),而是bar.toString()。哪个call派上用场。

不同的toString s

我说“大多数”因为有toString s:

  1. Object.prototype.toString返回表示对象
  2. 的字符串
  3. Array.prototype.toString返回表示指定数组及其元素
  4. 的字符串
  5. Number.prototype.toString返回表示指定Number对象的字符串
  6. String.prototype.toString返回表示指定String对象的字符串
  7. Function.prototype.toString返回表示函数源代码的字符串
  8. 单独使用的实例

    (new Object()).toString();                // "[object Object]"
    ["foo", "bar"].toString();                // "foo,bar"
    (6).toString(2);                          // "110"
    ("meow").toString();                      // "meow"
    (function(){return 'x';}).toString()      // "function (){return 'x';}"
    

    虽然所有对象原型都继承自Object,但后者不会从toString的{​​{1}}继承Object,这意味着它们都是不同的东西并有不同的用途。要告诉对象的类型,toString是有用的,因为它返回一个类型:

      

    每个对象都有一个toString()方法,当要将对象表示为文本值或者以期望字符串的方式引用对象时,会自动调用该方法。默认情况下,toString()方法由来自Object的每个对象继承。如果在自定义对象中未覆盖此方法,则toString()将返回“[object type]”,其中type是对象类型。

    呼叫

    请注意,其中唯一带参数的是Object.prototype.toString,它用于指定结果编号的基数。因此,为了对具有自己的toString方法的数组,数字和其他对象调用Number.prototype.toString,您需要Object.prototype.toString来指定call

    this