【问题标题】:Why are some JavaScript constructors not functions?为什么有些 JavaScript 构造函数不是函数?
【发布时间】:2011-10-22 17:12:14
【问题描述】:

澄清:
“JavaScript 构造器”应该更恰当地写成“javascript 构造器”,以强调所考虑的构造器不仅是原生 JavaScript 语言构造器,如 Object、Array、Function 等,还包括 JavaScript 语言定义之外的其他构造器但对于浏览器来说是固有的,例如XMLHttpRequest,“JavaScript”这个词的意思是表示这些构造函数是使用 JavaScript 表达和访问的。

一些参考资料:

在修辞上,有对构造函数 functions 的引用,但不是构造函数 objects

(表面上看,这是因为对象是函数,而函数是对象!
Why in JavaScript is a function considered both a constructor and an object?
更具体地说,对象,或者是 obj-eggs?,ARE,忽略文字实例,函数和函数的实例化是函数的对象实例。可以说,函数是对象存在的基础,这一事实证明了这一点
7.Functions
先于
8.Working with Objects
在 MDN 文档中JavaScript Guide。第 8 节,我反对!提供了使用构造函数和函数实例化创建对象所需的详细信息!)

为什么接口 DOM 的构造函数不是函数?

javascript:
  alert([
    "using browser environment:  \n"+window.navigator.userAgent,
     Option, Image, Audio,
       Storage, XMLHttpRequest, Worker, FileReader,
   ] . 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

[对象选项]

[对象图像]

[对象音频]

[对象存储]

[对象 XMLHttpRequest]

[对象工作者]

[对象文件读取器]

但是……

javascript:
  alert([
             XPCNativeWrapper,
  ].join("\n\n"));

(产生

函数 XPCNativeWrapper() { [本机代码] }

)

和 JavaScript 语言 constructors ARE 函数。

javascript:
  alert([
    "using browser environment:  \n"+window.navigator.userAgent,
             Array, Boolean, Date, Function,
               Number, Object, RegExp, String,
                 Error, Iterator,
  ].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] } 显然 Object 是一个函数。 (我的舌头在我的脸颊上,我很厚脸皮但是,,,)
  • 这里有一些对象对象是函数:javascript:x=y=z=Object; alert([x,y,z].join("\n\n")) 重申,每个对象都是一个函数! (不是每个对象都如此!)

标签: javascript constructor


【解决方案1】:

第一:

对象是函数

不,不是:

> a = function() {}
  function () {}
> a instanceof Object
  true
> b = {}
  Object
> b instanceof Function
  false

toString 方法(在进行字符串连接时会调用该方法)不是获取对象信息的可靠方法。如果我使用typeof,我会得到以下信息:

using browser environment:  
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:5.0.1) Gecko/20100101 Firefox/5.0.1

function

function

function

object

function

function

function

所以你看,除了Storage之外,它们中的大多数,实际上是函数(为什么它对Storage不起作用,我不知道)。

还要记住,DOM 接口的行为可能与原生 JavaScript 对象不同。

另一方面,在 Chrome 中,toString 方法给出了这个:

[object Function] 

[object Function] 

[object Function] 

function Storage() { [native code] } 

function XMLHttpRequest() { [native code] } 

function Worker() { [native code] } 

function FileReader() { [native code] }

【讨论】:

  • typeof Storage === "function" 在 chrome12 中
  • 声明“对象就是函数!”被认为是滑稽的 - 但是......对象是函数实例化!没有函数就没有实例化,没有实例化,通过new,就没有对象! ({property1:value1, property2:value2} 等文字和预定义实体除外)
  • @ekim:是否所有对象都是函数实例化是一个难题。你可以说一切最终都是通过Object构造函数创建的,并继承自Object.prototype。但是Object 函数继承自什么?来自Function.prototype,它本身又继承自Object.prototype。但是Object.prototype 不继承自任何其他对象。
  • @ekim:如果你想有更深入的了解,我建议你阅读 ECMAScript 规范:ecma262-5.com
  • also ... 任意类型的对象(小写)实例和 Object(大写)之间存在区别,Object 类型的构造函数是一个函数!
【解决方案2】:

当您提醒这些值时,浏览器引擎会提醒 value.toString(),所以我们正在讨论为什么 Function.prototype.toString 会以一种奇怪的方式表现。

ES5.1 规范声明:

15.3.4.2 Function.prototype.toString() 返回函数的依赖于实现的表示。此表示具有 FunctionDeclaration 的语法。

请特别注意空格、行终止符和 表示字符串中的分号是依赖于实现的。

toString 函数不是通用的;如果 this 值不是 Function 对象,它会抛出 TypeError 异常。因此,它不能转移到其他种类的对象中作为方法使用。

显然 ES5 声明 toString 返回一个特定于实现的字符串。

如果您阅读 ES Harmony proposals 页面,它会指出:

function to string – 对有问题的 Function.prototype.toString (markm, allen) 进行更详细的说明

这里还有一些资源:

基本上,函数对象(尤其是也是函数的宿主对象)上的toString 是未定义的行为,这是一个已知问题。 TC39 委员会已经在努力将其标准化。

如您所见,主机对象被提议在稻草人中标准化,因此是否将其纳入 ES6 尚无定论。然而,生活在 ECMA 领域的函数对象应该在 ES6 中有一个标准化的 toString 方法,如和谐提案页面上所定义的那样。

【讨论】:

  • "15.3.4.2 Function.prototype.toString ( ) 依赖于实现的表示...具有 FunctionDeclaration 的语法。" Chrome 的 function Worker() { [native code] } 符合条件,但 [object Worker] 没有。
  • so ... 为什么不符合 ImageOption 等?为什么它们是“已知问题”?
  • @ekim 请再次区分 Host 对象(浏览器和 DOM 的一部分)和 ES 对象。宿主对象可以为所欲为,因为它们是宿主对象。它们是尽可能不标准的。
  • 这是题外话,但是......预定义的对象是常规的并且事实上是标准化的,例如 JavaScript:(引用 developer.mozilla.org/en/JavaScript/Reference#Global_Objects)“全局对象标准全局对象(按类别)”虽然可以肯定来自不同供应商的浏览器可能会“扭曲”定义,偶尔会增加“标准”曲目。最初的问题并没有询问“宿主对象”本身,而是询问“JavaScript”构造函数(它们是函数类型的对象)。
  • 原始问题示例确实区分了构造函数的起源,无论是 DOM 还是原生 JavaScript,它们的字符串表示暗示构造函数类型有时可能是通用对象而不是函数。为什么会这样?
【解决方案3】:

这个问题实际上可以解释为:

“JavaScript (ECMAScript) 语言约定是否适用于和限定浏览器的其他组件,例如与 DOM 交互的编程对象?”

最初的问题使用的对象应该是 Function 类型并用作构造函数。这些示例显示了编程环境和 DOM 接口在它们的表示方式上存在着二分法。

如果存在这种实际的二分法,是否明确?

这可能是实际问题。如果是这样,则应在原始问题之前加上此,以将注意力引向真正的问题。

参考:

ECMAScript语言constructor详情:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-16
    • 1970-01-01
    • 2010-09-27
    • 1970-01-01
    相关资源
    最近更新 更多