对象性功能

时间:2013-04-20 22:04:13

标签: javascript function object constructor

上下文

我注意到只能使用new前缀调用某些函数。在没有它的情况下调用时,会抛出错误非法调用。下面是两个示例,说明在以不同方式调用Image时控制台的反应。

-> new Image();
<- <img>
-> Image();
<- TypeError: DOM object constructor cannot be called as a function.

更有趣的是,经过仔细观察,这些类型的功能看似功能,但事实并非如此。以Image为例,typeof命令显示Image是一个函数,Image的构造函数暗示它是一个Object。

这与大多数建筑功能非常不同,如下图所示。

function Foo(){
    this.identity = 'Bar';
}

可以通过两种方式调用Foo函数new Foo()Foo()。这与Image函数非常不同。

问题

Image函数的此操作与大多数构造函数非常不同。这怎么可能?这就是new前缀必须与Image一起使用的原因吗?更重要的是,可以重新创建这种类型的功能吗?

2 个答案:

答案 0 :(得分:4)

我认为,当new关键字未用于创建Foo的实例时,这是您正在寻找的重现异常的逻辑:

function Foo() {
    if (!(this instanceof arguments.callee)) 
        throw new TypeError("DOM object constructor cannot be called as a function.");

    this.identity = 'Bar';
}

根据this post中的一些评论,如果您处于严格模式,则必须使用函数名称arguments.callee而不是Foo

function Foo() {
    if (!(this instanceof Foo)) 
        throw new TypeError("DOM object constructor cannot be called as a function.");

    this.identity = 'Bar';
}

查看说明情况的 DEMO here

答案 1 :(得分:2)

Image的问题在于它是host object - 这意味着它不需要遵循原生EcmaScript对象的严格语义。例如,它可以从不是Function.prototype的东西继承,实现内部[[Construct]]方法而不是[[Call]]和类似的东西。

它们由DOM指定(请参阅Where are constructors such as, `new Image()` and `new Option()`, documented?),具体为here

  

提供了一个构造函数,用于创建HTMLImageElement个对象(除了来自DOM的工厂方法,例如createElement()):Image(width, height)作为构造函数调用时,必须返回一个新的HTMLImageElement对象(一个新的img元素)。 [...]

然而,它实现了特定于浏览器的功能:例如,Opera也会创建没有new的图片,而不会抛出NOT SUPPORTED错误。