Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

“__proto__”是个研究的好工具哟

  “__proto__”是个非标准的对象属性,为什么我要强调它的非标准呢?这是因为就连IE10都没兼容上它,我们可能无法在前端开发中使用它。但是作为调试与研究的工具,它的意义重大!有了“__proto__”就可以很容易地描述前面几篇文章中提到的问题了。
  上一篇中我一直提到实例化对象是把“构造器.prototype”所指向的地址复制到实例中。但是它储存在实例中的什么位置呢?如果在IE下研究这个问题就只能脑内补完了,因为IE中并不把这个储存有原型地址的对象公开。但是在Chrome和Firefox中,这个从构造器复制来的原型地址就储存在“__proto__”这个非标准属性中。它不仅可读,而且还是可写的!是不是有点太奔放了!?
var o={};
o.__proto__={a:1};
alert(o.a); //1
alert(o.hasOwnProperty("a")); //false
  这样就可以给一个实例直接指定上原型,这个测试中,a这个属性相当于原型继承而来的(虽然没有构造器),所以a并不是o本身所具有的属性。这个东西可写实在是太没节操了!嘛,反正现在它不是标准的,不管这么多。另外,对于正常的对象,“__proto__”和构造器的原型对象是相等的。
var O=function(){};
var o=new O;
alert(o.__proto__==o.constructor.prototype); //true
  这就意味着,修改实例的“__proto__”会影响到构造器(尼玛这是乱伦啊)! var O=function(){};
var a=new O,b=new O;
a.__proto__.name="次碳酸钴";
alert(b.name); //次碳酸钴
  这结果显然是节操掉一地了!这个方法要是投入项目中使用就太乱来了。ECMA一直不标准化这玩意儿,IE也一直不引入这玩意儿,果然是情有可原的。不过虽然这个东西不建议在项目中使用,但是作为一种调试和研究的方法就非常优秀了。我们可以清晰的看出一个对象从构造器继承来了什么东西。而且每个实例都有这个属性,这就意味着我们可以通过它找出整个原型链条。
function A(){};
function B(){};
function C(){};
C.prototype={name:"次碳酸钴"};
B.prototype=new C;
A.prototype=new B;
var a=new A;
console.dir(a);

  也许将来哪一天,这个属性真被标准化了,我也觉得它应该是只读的比较好。要是可写,在逻辑上实在太扯了。
网名:
3.80.32.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^