上下文
我注意到只能使用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
一起使用的原因吗?更重要的是,可以重新创建这种类型的功能吗?
答案 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
错误。