-1

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

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

  1. 细绳
  2. 数字
  3. 大批
  4. 目的
  5. 日期
  6. 功能
  7. 布尔值

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

/********************************************************/
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.输入时,属性|方法的弹出列表不再包含对该属性的引用,但是如果我输入完整的扩展名或者我得到所需的结果or ...lenn.leno.len32

所以我知道代码是合法的,但我需要控制台弹出窗口,因为 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__,nowone我注意到所有 3 个都被赋予了dis我最初尝试分配给该o对象的属性。

然后我破解了它:Number.prototype它本身就是一个对象,所以它继承了它的dis属性Object.prototype

如何将dis属性仅附加到o对象而不被nfrom继承Object.prototype

4

2 回答 2

3

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

OY合租。恕我直言,这不是最好的主意。特别是修改Object原型。是的。

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

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

你有没有告诉我如何将 dis 属性仅附加到 o 对象而不被 n 从 Object.prototype 继承?

好的...

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

怎么样?

你添加到Object原型中的任何东西都会出现在几乎所有东西上(这就是为什么这是一个坏主意)。

由于o 继承自Object,因此无法定义仅显示在普通对象上而不显示在其他所有对象上的属性。您的选择是:

  • 直接在 上定义属性o,或
  • 不要使用普通对象,而是从您自己的自定义类型o创建o并将您的属性放在该自定义类型的原型上(比修改内置类型的原型要好得多)。


注意:当然,您可以修改Number.prototype为具有以下dis属性undefined

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

console.log((9).dis);

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

看在上帝的份上,请使用分号。想想孩子们。

于 2015-01-22T08:26:03.383 回答
0

看一下这个:

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

解决方案:

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

缺点:

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

好处:

  • 当在整个任务上定义属性Object.prototype可能会成为一个自相矛盾的噩梦,即使是抛出到控制台的错误也会继承这些属性,如果您添加了 100 个新属性|方法,Object.prototype那么当您在控制台中展开任何错误时,每个都是可见的!
  • 此方法确保只有 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},因为 this 有constructor.name一个objectnot HTMLCollection

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

于 2015-01-23T21:46:24.883 回答