簡體   English   中英

如何在不將屬性應用於Number.prototype的情況下將其添加到Object.prototype?

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

我的目標是創建一個master_script.js 主要用於開發的處理程序文件。

該文件的一個小節專門用於自定義基礎對象的原型:

  1. 數組
  2. 賓語
  3. 日期
  4. 功能
  5. 布爾型

所以當我寫我的代碼塊時...

/********************************************************/
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__
)
/********************************************************/

工作正常!

  • 當我在控制台中展開n.__proto__時,它顯示len: (...)屬性,並且它是getter函數get len: function (){
  • 當我輸入n. 控制台上 ,可以在屬性列表中清晰可見。

當我為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 ...

所以我知道代碼合法,但是我需要控制台彈出窗口,因為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個對象均已獲得了最初嘗試僅分配給o對象的dis屬性。

然后我破解了它: Number.prototype本身是一個對象,因此,它繼承了Object.prototypedis屬性。

我如何才能將dis屬性僅附加到o對象,而不能由nObject.prototype繼承呢?

該文件的一個小節專門用於自定義基礎對象的原型

OY合租。 不是最偉大的主意恕我直言。 特別是修改Object原型。 esh

所以我知道代碼合法,但是我需要控制台彈出窗口,因為7個基礎對象中的每一個都有大約40種不同的屬性和方法...

為什么? 您是否正在瀏覽器控制台中進行開發?

您是否有向我展示如何將dis屬性僅附加到o對象而不被n從Object.prototype繼承的方法?

好...

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

怎么樣?

您添加到Object原型的所有內容都會顯示在幾乎所有內容上 (這就是為什么這是一個壞主意)。

由於o 繼承自Object ,因此無法定義僅顯示在普通對象上而不顯示在其他所有對象上的屬性。 您的選擇是:

  • 直接在o上定義屬性,或
  • 不用對o使用普通對象,而是從您自己的自定義類型創建o並將屬性放在該自定義類型的原型上(比修改內置類型的原型要好得多)。


注意:當然,您可以將Number.prototype修改為具有undefineddis屬性:

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

就數字而言,這將解決您的問題,但是dis財產仍然將存在於幾乎所有其他事物上。

而且,出於善意,請使用分號。 想想孩子們。

看一下這個:

/********************************************************
⇒   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的版。

解:

  • 因此,如果為簡單起見_ ,僅為Object.prototype定義1個屬性,並將其值設置為僅包含特定於對象的處理程序的子結構對象。
  • 然后,如果對Array.prototype進行相同的操作,但是將此_屬性的值設置為另一個僅包含特定於數組的處理程序的子結構。
  • 然后,與Array.prototype_版本上方的.len中的.len屬性覆蓋Object.prototype的版本ergo一樣,我們擁有2個完全獨立的_屬性,沒有其他繼承。

缺點:

  • 無法再以簡單的方式{}.len訪問屬性,現在必須將其前綴為{}._.len

好處:

  • Object.prototype上定義屬性時,整個任務可能會成為一個矛盾的噩夢,即使向控制台拋出的錯誤也會繼承該屬性,並且如果您向Object.prototype添加了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}因為它具有objectconstructor.name而不是HTMLCollection

這是一個寵物項目。 它只是在自己的原型階段,我正在尋找具有該主題經驗的人如何擴展此概念的想法,然后再回到舊方法或突破圍繞原型修改的污名並提出一種新的更有效的方法!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM