Object.prototype.toString是函数还是属性?

时间:2017-08-19 16:37:17

标签: javascript

在询问之前,我曾尝试过做作业并避免重复。因此,我已经阅读了大约20个问题和答案(主要是关于SO),它们都涉及toString()。但不幸的是,他们都没有回答我的实际问题。所以我们走了......

许多示例包含类似的代码:

Object.prototype.toString.call(someVariable);

我只是想知道为什么toString可以像这里的属性一样使用。我在MDN和其他地方阅读了Object.prototype的参考资料。他们都在toString()的成员中列出一个功能 Object.prototype,但是没有属性 toString

此外,我在我的代码中的几个地方使用如上所示的行。出于测试目的,我添加了括号以使其“干净”:

Object.prototype.toString().call(someVariable);

显然,这并没有使它“干净”,但只是让它返回错误的结果,甚至使浏览器失速(我目前正在研究究竟发生了什么)。

我已经阅读了一些关于没有括号的调用函数的问题和答案。但即使我接受上面显示的第一个代码行实际上调用了一个函数(虽然它看起来像访问属性),但仍然无法解释为什么当我添加括号时出现错误,如第二个代码行所示。能够在没有括号的情况下调用函数不应该意味着无法用括号调用它们吗?是吗?

我认为这个问题已经没有答案了(如果是的话,我道歉),那么请问一个简短的解释吗?

3 个答案:

答案 0 :(得分:3)

  

Object.prototype.toString是函数还是属性?

Object.prototype.toString是一个属性。该属性的是对函数的引用。完全是这样的:

var obj = {f: function() { } };

在那里,obj.f是一个属性,其值是对函数的引用。

Object.prototype.toString初始值是the spec%ObjProto_toString%已知的内在函数Function.prototype。它可以被覆盖,但这样做会破坏很多东西。

要记住的是,在JavaScript中,函数只是从Function.prototype *继承并且可以调用的对象。就像其他对象一样,您可以在属性和变量中保留对它们的引用(您甚至可以向函数本身添加属性),传递这些引用等等。这与处理“类”和方法等的许多语言形成鲜明对比。各种函数作为特殊的非对象事物。

* (主机提供的对象不需要从private void button_Click(object sender, EventArgs e) { Exam frm= new Exam(); // frm.ShowDialog(); frm.Show(); } 继承,但在现代环境中大多数都是;在某些过时的浏览器中,有些则没有。)

答案 1 :(得分:2)

功能只是价值。 Object.prototype()对象的属性,其值是函数。

Object.prototype.toString是函数调用运算符。 Object.prototype.toString不会调用函数;它只是获取Object.prototype.toString.call(...)属性的值(恰好是一个函数)。

函数也是对象,具有自己的属性。这就是你可以做Object.prototype.toString的原因:这得到call函数,然后获取它的call属性,然后调用它(这是允许的,因为var foo = function () { return "hello"; }; var bar = foo; console.log(bar); console.log(bar());的值是另一个函数)。

即使不涉及属性,这也有效:

foo

第一行为bar变量指定一个函数值。

第二行为foo分配相同的值,从console.log读取。请注意,我们没有调用函数,我们只是像其他任何值一样传递它。

第一个console.log显示功能本身。

第二个()显示调用该函数的结果,因为我们使用了from_unixtime(unix_timestamp('1-Nov-2012' , 'dd-MMM-yyyy'))

答案 2 :(得分:1)

欢迎使用JavaScript。确实,在某些情况下可以在没有()的情况下调用函数(特别是new f),但在这种情况下不行。您看到的是对用作对象的函数的引用,但未被称为(尚未)。这是常见的事情,虽然在这种情况下,它可能比平常更加模糊,所以我会解释为什么这样做。

当您显式调用其call方法(每个函数都从Function原型继承)时,函数最终会被调用,这允许您将函数体中的this绑定到某个任意对象。您的第一个示例可能someVariable.toString()做同样的事情。那么为什么要使用更长的形式?

嗯,someVariable可能没有toString方法(如果它是null或未定义,因为它们不是对象而不能被装入对象中),在这种情况下使用someVariable.toString会抛出一个TypeError。或者其原型toString方法可能具有与基本对象不同的行为。在这种情况下,我想作者想用一个老式的技巧来获取一个对象的“物种”的名称,这涉及Object.prototype.toString总是返回"[Object whatever]"的地方,其中“无论什么”将是构造函数的名称或Null或Undefined。