浅谈prototype(一)
关于prototype的文章很多了,我就某些方面来发表自己的看法。
今天我要谈的是:子类继承于父类的方法和属性,在子类是怎么存储的。
先看例子:
//我的调试都是建立在火狐的基础上:firebug+console.log()+__proto__;
//构建一个打印调试的方法
function print(msg){
console.log(msg);
}
//父类
function Father(){
this.name="jone";
}
//父类的公共方法
Father.prototype.song=function(){
alert("go go go!");
};
//子类
function Son(){
this.fight=function(){
alert("fighting!");
}
}
//子类通过原型继承方式继承父类方法和属性
Son.prototype=new Father();
这是prototype原型继承方式的做法。
在讲调试前,先说明下调试环境,firebug我想不用说了,console.log()是火狐浏览器的一个看调试信息的方法,在firebug控制台看结果,还有__proto__这个,不知道的可以看再谈javascript面向对象编程.
下面进入正题,
Son.prototype=new Father() 等同于 Son.prototype={name:"jone",__proto__:Father.prototype};(这个仅限于火狐,在其它浏览器里,[[prototype]]是每个对象的不可见属性,用于指向构建本对象的构造函数的原型对象)
这个为什么成立呢?
使用正常的方法,我们填下如下代码:
Son.prototype=new Father();
//Son.prototype.__proto__.name=["上帝"];//这个相当于给父类原型添加name属性,但是但是会被父类成员变量name覆盖掉
Son.prototype.name="人们";//这里就是给子类原型对象的name属性赋值,当然会改变子类的name属性值,因为子类没有name成员变量。
Son.prototype.__proto__.song=function(){
alert("几度风雨");
};
var hali=new Son();
var wrg=new Father();
hali.song();//弹出“几度风雨”
wrg.song();//弹出“几度风雨”
print(wrg.name);//显示“jone”
print(hali.name);//显示“人们”
从上面代码运行结果,可以得出Son.prototype.__proto__指向的是构造函数的原型对象Father.prototype,使用这个改变属性和方法,会直接改变父类原型的属性和方法,但是改变不了父类的成员变量,是因为,子类是保存了一份父类成员变量和方法。子类继承的
Son.prototype对象赋值过程是这样的:
- Father的构造函数将它的成员变量name复制一份给了Son.prototype对象
- Father的构造函数将它的Father.prototype对象的指针赋给了Son.prototype对象的__proto__属性
由上可以得出Son.prototype=new Father() 等同于 Son.prototype={name:"jone",__proto__:Father.prototype};是成立的。由此也能知道:
- 父类的成员变量,成员方法是直接拷贝一份在子类的原型对象中,所以尽量不使用用成员变量和方法,可以节省内存空间;
最好来个堆内存图情况
第一次写技术文章,有很多不足,如能蒙高手指点一二,乃鄙人三生之幸。本文仅供参考和交流,不能作为教程,教坏了小朋友,我罪大恶极了。
浙公网安备 33010602011771号