对象自然函数

Object-Natured Functions

本文关键字:函数 自然 对象      更新时间:2023-09-26

上下文

我注意到有些函数只能使用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一起使用的原因吗?更重要的是,这种类型的函数可以重新创建吗?

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

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

根据这篇文章中的一些评论,如果你处于严格模式,你必须使用函数名Foo,而不是arguments.callee

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

请参见此处的演示,该演示说明了这种情况。

Image的问题在于它是一个宿主对象,这意味着它不需要遵循本地EcmaScript对象的严格语义。例如,它可以从不是Function.prototype的东西继承,实现内部的[[Construct]]方法,但不能实现[[Call]]和类似的东西。

它们是由DOM指定的(请参阅文档中的"new Image(("answers"new Option(("等构造函数在哪里?(,具体在这里:

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

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