Javascript中数学和数组的区别是什么?
Javascript在其内置类型和对象方面似乎有一些自由 要获取数组类型中的函数,可以执行以下操作:Javascript中数学和数组的区别是什么?,javascript,arrays,Javascript,Arrays,Javascript在其内置类型和对象方面似乎有一些自由 要获取数组类型中的函数,可以执行以下操作: > Array().slice function slice() { [native code] } 所以这里的数组看起来像一个标准函数,被用作构造函数。除了slice不是Array()函数的成员函数,它是Array对象的成员函数 Array()的另一个不寻常之处是,无论是否使用new()调用它,它似乎都会返回一个数组对象: 另一方面,Math似乎是一个始终存在的内置单
> Array().slice
function slice() {
[native code]
}
所以这里的数组看起来像一个标准函数,被用作构造函数。除了slice不是Array()函数的成员函数,它是Array对象的成员函数
Array()的另一个不寻常之处是,无论是否使用new()调用它,它似乎都会返回一个数组对象:
另一方面,Math似乎是一个始终存在的内置单例对象(即:无需实例化)。因此,您可以使用Math.min.apply,而使用Array().slice.apply处理数组
我的问题是,是什么让Array()与您自己编写的构造函数和Javascript的其他内置对象如此不同。您正在编写的
Array().slice()
这意味着:
new
关键字通过改变调用函数的方式(即,使用新创建的对象实例作为此
上下文值)起到了作用。函数可以自由地检查此
是否引用了全局对象,如果是,则可以主动返回新创建的对象
“数学”对象只是一个对象;您可以将其定义如下:
var Math = {
min: function(n1, n2) { ... },
max: function(n1, n2) { ... },
// ...
};
我将引用你的问题,在线发表一些评论: 除了。。。slice不是Array()函数的成员函数,它是Array对象的成员函数 更确切地说,
slice
是Array.prototype
对象的成员,通过执行Array()
,您正在创建一个新的数组对象,该对象继承自Array.prototype
,这就是slice
可用的原因
Array()的另一个不寻常之处是,无论是否使用new()调用它,它似乎都会返回一个数组对象:
此行为也由其他内置构造函数共享,例如函数
:
var fn = Function('return "foo";');
相当于:
var fn = new Function('return "foo";');
规范(vs)中对这些情况进行了描述,但当您在使用或不使用new
时,其他构造函数会呈现不同的行为,例如,基本包装器:
new Number("20"); // produces a Number object
typeof new Number("20"); // "object"
Number("20"); // makes type conversion
typeof Number("20"); // "number"
另一方面,Math似乎是一个始终存在的内置单例对象(即:无需实例化)。因此,您可以使用Math.min.apply,而使用Array().slice.apply处理数组
是的,Math
是一个简单的对象,而不是像Array
那样的函数
它继承自对象。prototype
和IIRC它与简单用户定义对象的唯一独特区别是它的内部[[Class]]]
属性包含“Math”,例如:
我的问题是,是什么让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' }
至少在Chrome中,数学就是一个例子。在Firefox上,它直接包装到本机代码,甚至在
for in
循环中都不可用。是的,我确信它并没有真正定义成这样-我的意思是,这只是对象性质的一个说明。@Ivo,无法使用for in
循环枚举Math
对象的属性,因为它们被描述为不可枚举,例如:Math.propertyEnumerable('max')代码>生成假@CMS Ah ok。但Opera很奇怪,你可以调用Math的构造函数,却得到了一个没有原型的无用对象,因此没有函数。@必须报告Ivo,这是一件非常糟糕的事情,它完全反对:“Math的
对象没有[[Construct]]
属性;无法将Math
对象用作带有new
运算符的构造函数。此外:“Math
对象没有[[Call]]
属性;无法将Math
对象作为函数调用。”
Object.prototype.toString.call(Math); // "[object Math]"
function Foo (arg) {
if (!(this instanceof Foo)) { return new Foo(arg); }
this.foo = arg;
}
new Foo('bar'); // { foo: 'bar' }
Foo('bar'); // { foo: 'bar' }