我的目标是创建一个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.
时,属性|方法的弹出列表不再包含对len
属性的引用,但如果我输入完整扩展名n.len
或o.len
,我会得到所需的结果3
或2
...
所以我知道代码是合法的,但我需要控制台弹出窗口,因为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__
,o
和现在n
的控制台中扩展e
后,我立即注意到所有3个都被赋予了dis
属性,我原本试图仅仅分配给o
对象。
然后我破解了它:Number.prototype
本身就是一个对象,它继承了dis
的Object.prototype
属性
我怎样才能将dis
属性仅仅附加到o
对象而不被n
从Object.prototype
继承?
此文件的子部分专用于自定义基础对象的原型
OY合租。不是最好的主意恕我直言。特别是修改Object
原型。 Yeesh。
所以我知道代码是合法的,但我需要控制台弹出窗口,因为7个基础对象中的每一个都有大约40种不同的属性和方法......
为什么?您是否在浏览器控制台中进行开发?
你有没有告诉我如何将dis属性仅仅附加到o对象而不是从Object.prototype中继承n?
好...
Object.defineProperty(
o, 'dis',
{ get:function(){ return this; } }
);
怎么样?
你添加到Object
原型的任何东西都会出现在几乎所有东西上(这就是为什么这是一个坏主意)。
由于o
只继承自Object
,因此无法定义只出现在普通对象上而不出现在其他所有内容上的属性。您的选择是:
o
上定义属性,或o
的普通对象,而是从您自己的自定义类型创建o
,并将您的属性放在该自定义类型的原型上(比修改内置类型的原型要好得多)。Number.prototype
to have a dis
property of undefined
:
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
定义一个属性,为了简单起见_
,请将其值设置为包含仅对象特定的处理程序的子结构对象。Array.prototype
执行相同操作,但将此_
属性的值设置为包含仅特定于数组的处理程序的另一个子结构。.len
版本的Array.prototype
上面的_
属性覆盖Object.prototype
的版本ergo我们有2个完全独立的_
属性,没有其他遗产。缺点:
{}.len
,它现在必须以{}._.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
。
这是一个宠物项目。它只是在它自己的原型阶段,我正在寻找关于如何扩展这个概念的想法,从那些有关于这个主题的经验,然后我要回到旧的方式或突破这个围绕原型修改的耻辱,并提出一种新的更有效的方式!