Javascript中Math和Array有什么区别?

Pau*_*son 2 javascript arrays

当涉及到它的内置类型和对象时,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的其他内置对象如此不同.

CMS*_*CMS 6

我会在内容中发表一些评论,引用你的问题:

除了... slice不是Array()函数的成员函数,它是Array对象的成员函数.

更确切地说,sliceArray.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)