1
由于直接扩展内置对象是个不好的习惯,所以我想创建一个扩展全局对象的本地对象,与$.extend(obj, Math)
。 Math
是一个对象,但你似乎无法访问其任何属性的这样的:使用JavaScript扩展数学对象
for (obj in Math) {
console.log(obj);
}
为什么?
由于直接扩展内置对象是个不好的习惯,所以我想创建一个扩展全局对象的本地对象,与$.extend(obj, Math)
。 Math
是一个对象,但你似乎无法访问其任何属性的这样的:使用JavaScript扩展数学对象
for (obj in Math) {
console.log(obj);
}
为什么?
因为它们都被定义为非可枚举的。几乎所有规范定义对象的内置属性都是不可枚举的。列举对象中的属性时,不会显示非枚举属性(通过for-in
或Object.keys
)。
两个想法的你,虽然:
您可以Math
为原型创建的对象,像这样:
// Create the MyMath object with Math as its prototype
var MyMath = Object.create(Math);
// Check that MyMath has a Math function on it
display(MyMath.floor(2.3));
// Utility function
function display(msg) {
document.body.insertAdjacentHTML("beforeend", "<p>" + msg + "</p>");
}
ES5引入了新的函数Object.getOwnPropertyNames
,它可以获取所有属性的名称(可枚举和不可枚举)来自对象。 (而且因为Math
原型为Object.prototype
,你可能只是想“自己”的属性。)所以,你可以做到这一点上兼容ES5引擎:
// Create the MyMath object with all of the own properties on Math
var MyMath = {};
Object.getOwnPropertyNames(Math).forEach(function(name) {
MyMath[name] = Math[name];
});
// Check that MyMath has a Math function on it
display(MyMath.floor(2.3));
// Utility function
function display(msg) {
document.body.insertAdjacentHTML("beforeend", "<p>" + msg + "</p>");
}
选项1可能是您更好的选择,这不仅仅是因为在ES5引擎之前可以对单参数版本的Object.create
进行填充/填充。
扩展内置对象的*原型通常被认为是不好的做法,除了匀场/填充。但是将函数添加到非原型(如'Math')是非常无害的。 – 2014-10-10 09:30:56
@ T.J.Crowder为什么?如果其他人也添加了同名的东西呢?还是因为它非常罕见? – Luxiyalu 2014-10-13 08:10:23
为什么增加原型通常被认为是不好的做法?是的,这是冲突 - 与其他人添加的内容相冲突,并更新为规范。例如:几年前,PrototypeJS使用'=='比较将“indexOf”添加到数组实例。然后'indexOf'被添加到规范中,但是使用'==='比较。因此,使用PrototypeJS并依赖旧定义的代码将会因新定义而失败。它也得到了一个坏名字,因为在ES5之前,你不能将不可枚举的属性添加到原型,所以像人们没有想到的那样添加。 – 2014-10-13 08:51:34