我的目标是创建 master_script.js 。主要用于开发的处理程序文件。
此文件的子部分专门用于自定义基础对象的原型:
- 字符串
- 数
- 阵列
- 对象
- 日期
- 功能
- 布尔
醇>
所以当我写出我的代码块时......
/********************************************************/
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.
时,属性|方法的弹出列表不再包含对{的引用{1}}属性,但如果我输入完整的扩展程序len
或n.len
,我会得到o.len
或3
...
所以我知道代码是合法的但我需要控制台弹出窗口,因为有大约40种不同的属性和& 7个基础对象中的每一个的方法......
所以我写了一个测试块试试&找出问题:
2
在/********************************************************/
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__
和现在o
的控制台中展开n
后,我立即注意到所有3个都已发出我最初尝试分配给e
对象的dis
属性。
然后我破解了它:o
本身就是一个对象,它继承了Number.prototype
dis
属性
如何将Object.prototype
属性仅追加到dis
对象,而不o
从n
继承?
答案 0 :(得分:3)
Oy vey。不是最好的主意恕我直言。特别是修改此文件的子部分专门用于自定义基础对象的原型
Object
原型。 Yeesh。
所以我知道代码是合法的,但我需要控制台弹出窗口,因为有大约40种不同的属性& 7个基础对象中的每一个的方法......
为什么呢?您是否在浏览器控制台中进行开发?
你有没有告诉我如何将dis属性仅仅附加到o对象而不是由Object.prototype中的n继承?
好的...
Object.defineProperty(
o, 'dis',
{ get:function(){ return this; } }
);
怎么样?
你添加到Object
原型的任何内容都会出现在所有内容上(这就是为什么这是一个坏主意)。
由于o
仅从<{1}}继承,因此无法定义仅显示在普通对象上而不显示在其他所有内容上的属性。您的选择是:
Object
或o
的普通对象,而是从您自己的自定义类型创建o
,并将您的属性放在该自定义类型的原型上(比修改内置类型的原型要好得多) )。<小时/> 注意:当然,您可以修改
o
,使Number.prototype
属性为dis
:
undefined
就数字而言,这样可以解决你的问题,但Object.defineProperty(Number.prototype, 'dis', {
value: void 0
});
console.log((9).dis);
属性仍然存在于其他所有其他属性中。
请为了善良,请使用分号。想想孩子们。
答案 1 :(得分: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
&amp;的len
上定义一个属性。将其值设置为5
。{}.len
,我们会得到5&amp;如果我们调用[].len
或"".len
或#.len
等,我们会因实例化Object.prototype
的继承而得到相同的结果。Array.prototype
上使用相同的名称定义了一个属性: - len
&amp;将其值设置为50
。{}.len
等,我们会得到相同的结果5,但如果我们调用[].len
,我们会得到50,因为Array.prototype
最近创建了它的定义len
会覆盖Object.prototype
的版本。解决方案:
Object.prototype
定义一个属性,那么为简单起见_
,&amp;将其值设置为子结构对象,该对象包含仅特定于对象的处理程序。Array.prototype
执行相同操作,但将此_
属性的值设置为包含仅限于数组的处理程序的另一个子结构。.len
Array.prototype
版_
版本Object.prototype
版本_
版本号{}.len
版本一样,我们有2个完全独立{{1}没有其他遗产的属性。缺点:
{}._.len
,现在必须以Object.prototype
作为前缀。优点:
Object.prototype
上定义属性时,整个任务可能会成为一个自相矛盾的噩梦,甚至抛出到控制台的错误都会继承属性,如果你向_
添加了100个新的属性方法,那么当您在控制台中展开任何错误时,每个都可见!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.name
,因为object
HTMLCollection
而不是{{1}}。
这是一个宠物项目。它只是在它自己的原型阶段,我正在寻找关于如何扩展这个概念的想法,从那些有这个主题经验的人那里,我要么回到过去的方式,要么突破这个围绕原型修改的耻辱,并想出来一种新的更有效的方式!