当涉及到它的内置类型和对象时,Javascript似乎需要一些自由.
要获取Array类型中的函数,您可以执行以下操作:
> Array().slice
function slice() {
[native code]
}
Run Code Online (Sandbox Code Playgroud)
所以这里Array看起来像是一个用作构造函数的标准函数.除了... slice不是Array()函数的成员函数,它是Array对象的成员函数.
关于Array()的另一个不寻常的事情是它似乎返回一个Array对象,无论你是否使用new()调用它:
> var a = Array()
undefined
> a
[]
> a.length
0
> var b = new Array()
undefined
> b
[]
> b.length
0
Run Code Online (Sandbox Code Playgroud)
另一方面,Math似乎是一个始终存在的内置单例对象(即:不需要实例化).因此,在使用Array().slice.apply的Array时,您将使用Math.min.apply.
我的问题是什么使得Array()与你自己编写的构造函数和Javascript的其他内置对象如此不同.
我会在内容中发表一些评论,引用你的问题:
除了... slice不是Array()函数的成员函数,它是Array对象的成员函数.
更确切地说,slice
是Array.prototype
对象的成员,通过执行Array()
,您正在创建一个新的数组对象,继承自Array.prototype
,这slice
就是可用的原因.
关于Array()的另一个不寻常的事情是它似乎返回一个Array对象,无论你是否使用new()调用它:
其他内置构造函数也共享此行为,例如Function
:
var fn = Function('return "foo";');
Run Code Online (Sandbox Code Playgroud)
相当于:
var fn = new Function('return "foo";');
Run Code Online (Sandbox Code Playgroud)
这些情况在规范中描述(数组构造函数称为函数 vs 新数组),尽管其他构造函数在使用或不使用它们时会呈现不同的行为new
,例如,原始包装器:
new Number("20"); // produces a Number object
typeof new Number("20"); // "object"
Number("20"); // makes type conversion
typeof Number("20"); // "number"
Run Code Online (Sandbox Code Playgroud)
另一方面,Math似乎是一个始终存在的内置单例对象(即:不需要实例化).因此,在使用Array().slice.apply的Array时,您将使用Math.min.apply.
是的,Math
是一个简单的对象,而不是像这样的函数Array
.
它继承自Object.prototype
和IIRC,它与一个简单的用户定义对象的唯一区别在于它的内部[[Class]]
属性包含"Math",例如:
Object.prototype.toString.call(Math); // "[object Math]"
Run Code Online (Sandbox Code Playgroud)
我的问题是什么使得Array()与你自己编写的构造函数和Javascript的其他内置对象如此不同.
Array
没有那么不同,您可以编写一个构造函数,如果使用new
或不调用,其行为方式相同,例如:
function Foo (arg) {
if (!(this instanceof Foo)) { return new Foo(arg); }
this.foo = arg;
}
new Foo('bar'); // { foo: 'bar' }
Foo('bar'); // { foo: 'bar' }
Run Code Online (Sandbox Code Playgroud)