JavaScript—函数核心对象的行为
据我所知,在JavaScript(Gecko变体)中: 这是一个类似这样的语法糖:JavaScript—函数核心对象的行为,javascript,Javascript,据我所知,在JavaScript(Gecko变体)中: 这是一个类似这样的语法糖: var a = {}; a.__proto__ = A.prototype; A.call(a); 因此,A()(相当于A.call()?)和新的A()应该产生两种不同的结果,如下所示: >>> new Date() Fri Nov 19 2010 01:44:22 GMT+0100 (CET) {} >>> typeof new Date() "object" >&
var a = {};
a.__proto__ = A.prototype;
A.call(a);
因此,A()(相当于A.call()?)和新的A()应该产生两种不同的结果,如下所示:
>>> new Date()
Fri Nov 19 2010 01:44:22 GMT+0100 (CET) {}
>>> typeof new Date()
"object"
>>> Date()
"Fri Nov 19 2010 01:44:42 GMT+0100 (CET)"
>>> typeof Date()
"string"
到目前为止还不错
但是,核心对象函数
的行为不同:
>>> Function('return 123;')
anonymous()
>>> typeof Function('return 123;')
"function"
>>> Function('return 123;')()
123
>>> new Function('return 123;')
anonymous()
>>> typeof new Function('return 123;')
"function"
>>> new Function('return 123;')()
123
我是否遗漏了一些琐碎的东西?您可以从构造函数中判断是否使用
new
调用了您-如果new
,则MyClass的此实例;如果不是new
,this==window
(前提是它是顶级对象-正如gnarf指出的,对于Namespace.MyClass()
,this==Namespace
)
如果(MyClass的此实例)返回new MyClass(),则很可能(有些人更喜欢它)将其置于构造函数的顶部代码>(自然要考虑参数);然后可以使用或不使用new
调用构造函数,结果相同
讨论这个问题的一个问题是。还有其他的。这是因为Function()
返回一个函数,而new Function()
构造一个函数,因此您可以得到相同的输出。您可以从JavaScript中的一个构造函数“返回”一个不同的值——一些内置函数(例如日期)是这样工作的(和函数一样,但它的工作方式不同于Date:-)。我不确定它在哪里被记录下来——在ECMA262中,请参阅其他答案
下面是一个人为的例子,展示了如何创建一个类似于“函数”(在FF中)的ctor:
但是,我不知道ECMA规范是如何定义这一点的……无论如何,返回的结果完全取决于调用的函数/new'ed.——请再次参阅ECMA 262。不确定您的问题是什么……我可以告诉您的是,基本对象中有代码,允许您使用new和notew调用它,但是嘿,表现得有点不同
typeof Number(5) == "number"
typeof new Number(5) == "object"
typeof Boolean(0) == "boolean"
typeof new Boolean(0) == "object"
对基本类型调用new将返回包装为对象的基本体
我写了一篇博客,介绍如何创建使用或不使用新运算符的构造函数。我不使用它,但这是一个有趣的东西。它将让您了解如何根据是否使用新运算符调用函数来更改函数的行为
即使在这番咆哮之后,我仍然不确定您的问题是什么…语言级别的JavaScript没有指定使用构造函数的特定“标准”方式。当您定义自己的构造函数时,您可以选择将其作为构造函数调用(使用new
),作为函数调用(返回新对象),或使其与其中任何一个一起工作
我是不是错过了一些小事
不完全是。ECMAScript第15.3.1节定义了函数
构造函数,即使没有新的
,也可以用作构造函数:
当函数
作为函数而不是构造函数调用时,它会创建并初始化一个新函数
对象。因此,函数调用函数(…)
相当于具有相同参数的对象创建表达式新函数(…)
另一方面,Date
函数(由ECMAScript第15.9.2节)定义为返回字符串:
当Date作为函数而不是构造函数调用时,它返回一个表示当前时间(UTC)的字符串
注意:函数调用Date(…)
不等同于具有相同参数的对象创建表达式new Date(…)
之所以要注意这一点,是因为有这么多的构造函数也可以在没有new
的情况下使用。这并不是因为有人认为所有的构造函数都应该被允许作为普通函数使用,而是因为这正是自早期Netscape以来JavaScript一直在做的事情。Netscape想不出任何事情g专门为Function()
做的,所以它只是复制了新的功能。他们没有太注意使语言保持一致
如果你头脑清醒的话,你就不会像那样设计一种语言的默认类库。但是JavaScript不是一种头脑清醒的语言。它是一种很快就失控的黑客,在任何人花时间改进它的设计之前就达到了广受欢迎的程度。期望它表现一致,你只会失望。这与在表达式中使用new
运算符,规范中描述了这种情况
从§15.3.1开始:函数构造函数被称为函数
因此,函数调用函数(…)等价于具有相同参数的对象创建表达式new function(…)
其他内置构造函数的行为与此类似,例如:
其他构造函数,如创建基本值包装的构造函数(Boolean
、String
、Number
和Date
)的行为不同
typeof Number(5) == "number"
typeof new Number(5) == "object"
typeof Boolean(0) == "boolean"
typeof new Boolean(0) == "object"
前三个如果在不使用new
运算符的情况下使用call,则它们只执行类型转换,例如:
typeof Number("20"); // "number"
typeof String(0xFF); // "string"
typeof String({toString: function () { return 'foo' }}); // "string"
typeof Boolean(""); // "boolean"
typeof Boolean(0); // "boolean"
如果将它们与new
操作符一起使用,它们将返回包装器对象:
这类对象称为基元包装器,它们有一个名为[[PrimitiveValue]]
的内部属性,用于存储其基础值(详细信息)
使用Date
构造函数创建的对象也是基本包装器,它们的基本值是时间值的数字表示
Date
构造函数的语义也有完整的描述,如果它将返回一个“表示当前时间(UTC)的字符串”。您可以从JavaScript中的ctor“return”返回
Array(1,2,3); // [1,2,3]
new Array(1,2,3); // [1,2,3]
typeof Number("20"); // "number"
typeof String(0xFF); // "string"
typeof String({toString: function () { return 'foo' }}); // "string"
typeof Boolean(""); // "boolean"
typeof Boolean(0); // "boolean"
typeof new Number(20); // "object"
typeof new String('foo'); // "object"
typeof new Boolean(true); // "object"