Web 技术研究所

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

覆写构造器原型对象的问题

  前面的文章中已经搞清了实例与原型的关系。但是,虽然关系已经明确,但是定义依然不明确。由于JavaScript中对象地址都是内部的东西,我们访问一个对象甚至不知道它是真正的对象还是一个指针而已。另外,这个问题并不简单,背后还隐含了另一个问题!
  前面的测试中,我们访问一个实例的属性时候,如果它本身不具有那个属性就会到原型中去找。那么,实例的原型是什么?这不是废话吗?(我为什么要吐自己槽= =。)实例的原型不就是构造器的原型对象吗?它还能是别的!?当然不是别的!关键是构造器的原型对象又是什么?谁都知道是“构造器.prototype”,但是它到底是什么?“实例的原型是构造器的原型对象”这句话是有歧义的。构造器的原型对象是指“构造器.prototype”本身的地址,还是指它指向的对象地址呢?验证这个只要做一个和上回类似的实验就行。 var O=function(){};
O.prototype={a:1};
var o=new O;
alert(o.a); //1
O.prototype={a:2};
alert(o.a); //1
  这个测试中两个输出都是1,也就是说“实例的原型是构造器的原型对象”这句话中“构造器的原型对象”是指“构造器.prototype”指向的对象,而不是它本身。测试中在创建对象后修改了“构造器.prototype”的指向,这个操作并没有影响到已经实例化的对象。也就是说,在new的时候就已经把“构造器.prototype”上保存的地址复制到实例上了。这是在new时就复制的,更确切的说是在构造器函数执行之前就复制的。
  上面这些东西我想内行的人一句话就能概括,但是这里还隐含着另一个问题。那就是继承判断的问题!说到继承判断那太简单了,直接一个instanceof运算符搞定。但是instanceof是如何判断一个对象是否是继承与某个构造器的呢?其实它是用new时从“构造器.prototype”上复制过来的地址判断的。 var O=function(){};
O.prototype={a:1};
var o=new O;
O.prototype={a:2};
alert(o instanceof O); //false
  由此可看出instanceof的工作原理。instanceof运算符有两个操作数,左边是实例,右边是构造器。他的工作是把左操作数在new时从构造器原型对象上复制来的原型地址与右操作数的原型对象地址做比较。如果相同则返回true,如果不相则把左操作数换成它的原型并递归这个操作,直到左边操作数为Object的原型为止。知道这些,我们甚至可以自己实现个instanceof。
  其实,还有个非标准的属性“__proto__”可以轻易的描述这个问题,不过这篇文章就不提它了,下回再来说它吧~
网名:
3.80.55.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^