2014-10-10 77 views
1

由于直接扩展内置对象是个不好的习惯,所以我想创建一个扩展全局对象的本地对象,与$.extend(obj, Math)Math是一个对象,但你似乎无法访问其任何属性的这样的:使用JavaScript扩展数学对象

for (obj in Math) { 
    console.log(obj); 
} 

为什么?

+1

扩展内置对象的*原型通常被认为是不好的做法,除了匀场/填充。但是将函数添加到非原型(如'Math')是非常无害的。 – 2014-10-10 09:30:56

+0

@ T.J.Crowder为什么?如果其他人也添加了同名的东西呢?还是因为它非常罕见? – Luxiyalu 2014-10-13 08:10:23

+1

为什么增加原型通常被认为是不好的做法?是的,这是冲突 - 与其他人添加的内容相冲突,并更新为规范。例如:几年前,PrototypeJS使用'=='比较将“indexOf”添加到数组实例。然后'indexOf'被添加到规范中,但是使用'==='比较。因此,使用PrototypeJS并依赖旧定义的代码将会因新定义而失败。它也得到了一个坏名字,因为在ES5之前,你不能将不可枚举的属性添加到原型,所以像人们没有想到的那样添加。 – 2014-10-13 08:51:34

回答

3

因为它们都被定义为非可枚举的。几乎所有规范定义对象的内置属性都是不可枚举的。列举对象中的属性时,不会显示非枚举属性(通过for-inObject.keys)。

两个想法的你,虽然:

  1. 您可以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>"); 
     
    } 
     
    

  2. 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进行填充/填充。