今天在网上查看Javascript面向对象编程相关文章时,看到了一个让我下意识判断错误的例题,虽然原理很简单,但还是记录下来,供日后工作和广大Javascript学习者查询。
<script type="text/javascript"> function A(){ this.a="a"; } A.prototype.b="b"; A.prototype.getA=function(){ return this.a; } function B(){ this.c="c"; } B.prototype=new A(); B.prototype.constructor=B; var b=new B(); var a=new A(); console.log(b.constructor==B); console.log(a.constructor==B); console.log(b instanceof B); console.log(b instanceof A); console.log(b instanceof Object); </script>
上面是一段我自己编写的代码,具体问题是写出console.log的值,其中我的下意识的判断:
console.log(a.constructor==B); //true
理由是B.prototype.contructor重写了A.prototype对象contructor属性,运行以上代码:
运行结果证明我的下意思判断是错误,B.prototype.contructor并没有重写了A.prototype对象contructor属性,而是为B.prototype对象(即实例化的A对象)添加了contructor属性。总的来说我犯了一个低级的错误:
虽然可以通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。如果我们在实例中添加了一个属性,而该属性与实例原型中的属性同名,那我们就在实例中创建该属性,该属性将会屏蔽原型中的那个属性。使用delete操作符可以完全删除实例属性,而不能删除原型中的属性。所以原型中的属性对实例对象来说是只读的。