每个 JavaScript 对象都是一个函数吗?

5

是否存在一个不是函数的JavaScript对象?

javascript: x=y=z=Object; alert([window.navigator.userAgent,x,y,z].join("\n\n"))

有一个评论认为xyz只是引用,因此Object也只是对function Object() {...}的引用,因为Object的值被赋给了x,它们是“相同的”。作为“证明”。

javascript:x=Object;x.p=43;alert([x==Object,x===Object,x.p,Object.p])

显示

true,true,43,43

给定function Thing(){}x=new Thing()会使得x成为一个对象还是对它的引用?new Thing()Thing呢?在y=x=new Thing()y=x=Thing中的y又是什么?如果Thing=function(){}呢?区别无关紧要。"一切事物"(是否如此?)都是按引用调用,但可以通过评估字符串来强制执行按名称调用。所以……

javascript:
    void function(x,y,z){
        alert(  [window.navigator.userAgent,x,y,z].join("\n\n") )
    }(Object,Object,Object)

或者

javascript:
    void function(x){  (function (y){  (function (z){
             alert(  [window.navigator.userAgent,x,y,z].join("\n\n") )
         })(y) })(x) }(Object)

(虽然不完全是无用的 - function的值必须使用(...)void强制转换。 (...)的细微差别是微妙的:

javascript:       /* 43.p gives a runtime error but not ... */
    alert([ (43).p=34, 43["q"]=17, (x=43).z="hmmm" ]); 
    alert([ 43["p"], (43).z, x.p, x["z"], x]);

显示 34,17,hmmm,,,,43

)

或者甚至是一个对象数组

javascript:alert([window.navigator.userAgent,Object,Object,Object].join("\n\n"))

提供:

Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3

function Object() { [native code] }

function Object() { [native code] }

function Object() { [native code] }

有许多不是Object的对象。


正如答案中所指出的那样,如果对象被修改,则它本身可能不再是自己。
危险!危险!威尔·罗宾逊!

x=y=z=Object=null; alert([window.navigator.userAgent,Object,x,y,z].join("\n\n"));

参考资料


1
@Ibu ...但并不是所有的对象都是函数;-) - user166390
2
@pst,谢谢你帮我完成了我的句子。 - Ibu
但是...所有非字面对象都是函数实例化。 - Ekim
通过 javascript:alert(Object)Objectfunction Object() { [native code] },因此... - Ekim
4个回答

6

你没有创建对象,而是创建了对Object函数的引用。如果你想要它们成为对象,可以这样做:

x = y = z = {}

然后alert(x)将返回object [Object]。默认情况下,Object是构造对象的函数。如果您重新分配名称Object(至少Firefox似乎允许我这样做,尚未测试所有浏览器),那么Object将不再是函数,而是您分配给它的任何内容。因此,答案是“不”,Object不总是一个函数,除非已被明确地重新声明。根据Firebug的说法:
>>> Object
Object()
>>> Object = {}
Object {}
>>> Object
Object {}

看起来它可以重新分配。我不能保证这会产生什么影响,如果有的话。


1
你比我先说了...不过,当谈到JavaScript时,我不喜欢使用“引用”这个词(以下是我对第一句话的建议):你没有创建[新的]对象,而是将函数对象[它是一个构造函数]分配给变量。 - user166390
这也是一个很好的说法,关键在于你可以创建不是函数的对象,但不能通过将对象函数分配给变量来实现。 :) - g.d.d.c
是的,是的...但是...有没有不是函数的对象?请注意仔细的措辞和语法。大写的“Object”和没有冠词“an”。我确实指的是“Object”实体。有没有一个(Object)不是函数的对象!?这个问题不是关于创建对象的。 - Ekim
@ekim - 当JS解释器加载Object时,它是Object函数(即新的Object构造函数)。您可以调用Object = {}将其转换为实际的对象字面量,但这会消除调用new Object()的能力,因为您已覆盖了先前的签名。我...不确定我是否理解您提问的方式。 - g.d.d.c
但是 xyz 都是对象 - 尽管是同一个对象 - 它们都是 Object 对象,它是一个函数类型的对象或者简单地说就是一个函数。 - Ekim
我有点玩笑地反问...然而,JavaScript是一种函数式编程语言,其中一切都是函数和对象。关于对象和函数以及它们的表现机制有微妙的细微差别。Object、new Object()、Object()、Function、new Function()、Function()问题非常简单,答案同样简单——是的。我很好奇人们对这个陈述的直接看法是什么。有趣的是没有人直接回答! - Ekim

2

你将Object构造函数分配给变量x、y和z。 如果你改为说x=new Object(),你就不会再看到它们被称为函数了。


确切地说,问题仍然存在 - 答案是“是”吗? - Ekim
@ekim 对象和函数是Javascript的两个根本的非原始元素。https://developer.mozilla.org/en/JavaScript/Guide/Values,_Variables,_and_Literals - Shad
https://developer.mozilla.org/en/JavaScript/Guide/Functions 和 https://developer.mozilla.org/en/JavaScript/Guide/Working_with_Objects 描述了构造基础知识。 - Ekim
给定的参考资料,https://developer.mozilla.org/en/JavaScript/Guide/Values,_Variables,_and_Literals,描述了 JavaScript 的标记 - https://developer.mozilla.org/en/JavaScript/Guide/Predefined_Core_Objects 定义了核心对象(原始值),除了在此处列举的 https://developer.mozilla.org/en/JavaScript/Reference#Standard_global_objects_(by_category) 中明显缺少 Object。 - Ekim

1

在JavaScript中,可以使用new运算符在函数名前创建对象来使用任何函数作为构造函数。生成的对象不会是Function

ObjectFunction之间也存在循环关系,可以通过以下方式进行测试:

Object instanceof Function // true
Function instanceof Object // true

{}Object不是同一个东西,但{}new Object()是。

function foo() {}
foo instanceof Function // true
foo instanceof Object // true

var bar = new foo();
bar instanceof Function // false
bar instanceof Object // true

var baz = {};
baz instanceof Function; // false
baz instanceof Object; // true

不存在“循环关系”。对象和函数都是函数,它们都继承自Function.prototype,而Function.prototype又继承自Object.prototype(因此它们都是函数,所有JavaScript函数也都是对象)。instanceOf运算符只是检查原型链,它并不能告诉你太多信息。 - RobG
所以...简单的答案是...是的吗?每个对象(即使我只知道一个,但确实有这个)都是一个函数! - Ekim
“任何函数...使用new运算符作为构造函数创建对象时...都不会是一个Function”这种说法是不正确的,证明:javascript:function f(){return function(){}};alert(new f) - Ekim
实际上存在一种递归循环关系,这是基于对象和函数的构造函数机制定义的,其中Function和Object都是代表。请考虑以下内容:javascript:with(Object)alert([Object,constructor,prototype.constructor ])。更多细节请参阅http://chat.stackoverflow.com/rooms/2245/discussion-between-ekim-and-felix-kling。 - Ekim

0

这里是一种确定 JavaScript 中任何东西类型的绝佳方法。

注意:您应该发送一个窗口以外的其他内容...

在此尝试...

            (function (self) {
                var values = [
                          'Function',
                          'Object',
                          'Array',
                          'String',
                          'Number',
                          'Date',
                          'RegExp',
                          'Boolean',
                          'Null',
                          'Error'
                     ];

                for (var i in values) if (values.hasOwnProperty(i)) {
                     var value = values[i];

                     self['is' + value] = (function (v) {
                          return function (o) {
                                 var r = '';

                                 try {
                                     r = (o === null) ?
                                              'Null' :
                                              Object.prototype.toString.call(o).replace(/^\[object\s(\w+)\]$/, '$1');
                                 } catch (e) {
                                     r = 'Undefined';
                                 }

                                 return !!(r === v);
                          };
                     })(value);
                }
           })(window);

           alert(isFunction(Object));

问题不需要考虑类型 - 它问的是“Object是否总是一个函数?” - Ekim
是的,但 javascript: alert([Object, typeof(Object)]) 更基础。 - Ekim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接