如何将 属性 添加到 Object.prototype 而不将其应用于 Number.prototype?

How can I add a property to Object.prototype without it being applied to Number.prototype?

我的目标是创建一个master_script.js。主要用于开发的handler文件

此文件的一个小节专门用于自定义基础对象的原型:

  1. String
  2. Number
  3. Array
  4. Object
  5. Date
  6. Function
  7. Boolean

所以当我写出我的代码块时...

/********************************************************/
Object.defineProperty(
    Number.prototype,'len',
    {get:function(){
        str=this.toString()
        return str.length
    }}
)
/********************************************************/
n=123
o={123:'abc',abc:123}
/********************************************************/
console.log(
    'n              ⇒ ',n,
    '\n n.len       ⇒ ',n.len,
    '\n n.__proto__ ⇒ ',n.__proto__
)
/********************************************************/

工作正常!

当我为 o 变量配置相同的设置时,问题开始了:

/********************************************************/
Object.defineProperty(
    Number.prototype,'len',
    {get:function(){
        str=this.toString()
        return str.length
    }}
)
/******************************/
Object.defineProperty(
    Object.prototype,'len',
    {get:function(){
        cnt=0
        for(i in this)  cnt++;
        return cnt
    }}
)
/********************************************************/
n=123
o={123:'abc',abc:123}
/********************************************************/
console.log(
    'n              ⇒ ',n,
    '\n n.len       ⇒ ',n.len,
    '\n n.__proto__ ⇒ ',n.__proto__
)
/******************************/
console.log(
    'o              ⇒ ',o,
    '\n o.len       ⇒ ',o.len,
    '\n o.__proto__ ⇒ ',o.__proto__
)
/********************************************************/

我注意到的第一件事是,当我现在在 控制台 中键入 n.o. 时,属性|方法的弹出列表不再包含对 len 属性 的引用,但如果我输入完整的扩展名 n.leno.len,我会得到 32 的预期结果]...

所以我知道代码是合法的,但我需要 console 弹出窗口,因为 7 个基础对象中的每一个都有大约 40 种不同的属性和方法...

所以我写了一个测试块来尝试找出问题所在:

/********************************************************/
Object.defineProperty(
    Object.prototype,'dis',
    {get:function(){return this}}
)
/******************************/
Object.defineProperty(
    Number.prototype,'len',
    {get:function(){return this.length}}
)
/********************************************************/
o={123:'abc',abc:123}
n=123
e=document.createElement('option')
/********************************************************/
console.log(
    'o              ⇒ ',o,
    '\n o.__proto__ ⇒ ',o.__proto__
)
/******************************/
console.log(
    'n              ⇒ ',n,
    '\n n.__proto__ ⇒ ',n.__proto__
)
/******************************/
console.log(
    'e              ⇒ ',e,
    '\n e.__proto__ ⇒ ',e.__proto__
)
/********************************************************/

控制台 中将 .__proto__ 扩展为 on 和现在的 e 后,我立即注意到所有 3 个都被赋予了 dis 属性 我最初试图仅分配给 o 对象。

然后我破解了:Number.prototype本身就是一个对象,所以它从Object.prototype

继承了dis属性

我如何才能将 dis 属性 单独附加到 o 对象而不被 nObject.prototype 继承?

A subsection of this file is dedicated to customizing the prototypes of the foundation objects

哎哟喂。恕我直言,这不是最好的主意。特别是修改 Object 原型。是的。

So I know the code is legit but I need the console popup as there is about 40 different properties & methods for each of the 7 foundation objects...

为什么?您是在浏览器控制台中进行开发吗?

Do you have the nous to show me how to append the dis property solely to the o object without it being inherited by n from Object.prototype?

好的...

Object.defineProperty(
    o, 'dis',
    { get:function(){ return this; } }
);

怎么样?

您添加到 Object 原型的任何内容都会显示在几乎 所有内容 中(这就是为什么这是个坏主意)。

因为 o 只有 继承自 Object,所以没有办法定义一个 属性 只会出现在普通的 objects 而不是其他一切。您的选择是:

  • 直接在o上定义属性,或者
  • 不是为 o 使用普通的 object,而是从您自己的自定义类型创建 o 并将您的 属性 放在该自定义类型的原型上(很多比修改 built-in 类型的原型更好。


注意: 当然,您可以修改 Number.prototype 以获得 dis 属性 of undefined:

Object.defineProperty(Number.prototype, 'dis', {
    value: void 0
});

console.log((9).dis);

就数字而言,这将解决您的问题,但是 dis 属性 仍然会存在于几乎所有其他存在的东西上。

看在上帝的份上,请使用分号。想想 children.

看看这个:

/********************************************************
⇒   create the master objects.
/********************************************************/
function MasterObject(dis){
    Object.defineProperty(
        this,'this_object',
        {get:function(){return dis}}
    )
}
/******************************/
function MasterArray(dis){
    Object.defineProperty(
        this,'this_array',
        {get:function(){return dis}}
    )
}
/********************************************************
⇒   define the master properties.
/********************************************************/
Object.defineProperty(
    Object.prototype,'_',
    {get:function(){return new MasterObject(this)}}
)
/******************************/
Object.defineProperty(
    Array.prototype,'_',
    {get:function(){return new MasterArray(this)}}
)
/********************************************************
⇒   example to expand in the console.
/********************************************************/
x={a:1,b:2,c:3,d:4,e:5}
y=[]
    y['a']=1
    y['b']=2
    y['c']=3
    y['d']=4
    y['e']=5
z=[x,y]
/********************************************************
⇒   open the console, type [z], hit [enter] and expand...
/********************************************************/

破败:

  • 例如,我们在 Object.prototype 上定义了一个名为 len 的 属性,并将其值设置为 5
  • 现在如果我们调用 {}.len,我们得到结果 5 & 如果我们调用 [].len"".len#.len 等,我们得到相同的结果在实例化时从 Object.prototype 继承。
  • 但是假设我们随后在 Array.prototype 上定义了一个具有相同名称的 属性:- len 并将其值设置为 50.
  • 现在,如果我们调用 {}.len 等,我们得到相同的结果 5,但是如果我们调用 [].len,我们得到 50,因为 Array.prototype 是最近创建的,它的len 的定义覆盖了 Object.prototype 的版本。

解决方案:

  • 因此,如果我们为了简单起见只定义 1 属性 到 Object.prototype 调用 _,并将其值设置为包含特定于 [=66= 的处理程序的子结构对象]对象只。
  • 然后,如果我们对 Array.prototype 执行相同的操作,但将此 _ 属性 的值设置为包含特定于 arrays[= 的处理程序的另一个子结构90=] 仅。
  • 然后与上面列表中的 .len 属性 一样 Array.prototype_ 版本覆盖了 Object.prototype 的版本,因此我们有 2完全独立的 _ 属性,没有杂项继承。

缺点:

  • 无法再以简单的方式 {}.len 访问属性,现在必须添加前缀 {}._.len

好处:

  • Object.prototype 上定义属性时,整个任务可能会变成一个自相矛盾的噩梦,即使抛出到控制台的错误也会继承属性,如果您向 [=13= 添加了 100 个新属性|方法] 然后当你在控制台中展开任何错误时,每个都是可见的!
  • 此方法确保只有 1 个 属性 可见 _,并且 属性 可根据所有者对象的类型进行自定义。

扩展:

  • 我正在考虑修改此代码以适应 符合此标准的各种对象,例如可能是以下对象的处理程序:
x=document.getElementsByTagName('td')
y=x._.len

喜欢:

function MasterObject(dis){
    if(dis.constructor.name=='HTMLCollection'){
        Object.defineProperty(
            this,'len',
            {get:function(){
                cnt=0
                for(ia in dis) cnt++;
                return cnt
            }}
        )
    }
        else{
            Object.defineProperty(
                this,'this_object',
                {get:function(){return dis}}
            )
        }
}

所以 x._.len 可用于任何对象列表但不是说 {a:1} 因为它有一个 constructor.nameobject 而不是 HTMLCollection.

这是一个宠物项目。它只是在它自己的原型阶段,我正在寻找关于如何扩展这个概念的想法,从那些有该主题经验的人那里,然后我要么回到旧方法或突破围绕原型修改的耻辱并提出一种更有效的新方法!