关于JavaScript中原型继承中的一点思考 |
本文标签:原型继承 我们先看一段传统的继承代码: 复制代码 代码如下: //定义超类 function Father(){ this.name = "父亲"; } Father.prototype.theSuperValue = ["NO1","NO2"]; //定义子类 function Child(){ } //实现继承 Child.prototype = new Father(); //修改共享数组 Child.prototype.theSuperValue.push("修改"); //创建子类实例 var theChild = new Child(); console.log(theChild.theSuperValue); //["NO1","NO2","修改"] //创建父类实例 var theFather = new Father(); console.log(theFather.theSuperValue); //["NO1","NO2","修改"] 通过上面的代码,我们注意“加红”的代码,子类Child的原型对象是父类Father的一个实例(new Father()),我们在这里是调用new Father()对象中的theSuperValue属性,因为new Father()对象中没有此属性(只有name属性),因此会沿着原型链向它的原型对象(Father.prototype)中去找,找到后发现是一个数组,而且是引用类型,此时我们往此数组中添加一个字符串“修改” 。 之后,我们新建了Child的实例对象theChild,当theChild调用theSuperValue属性时,首先它自己里面没有此属性,就会去它的原型对象(new Father)中去找,可惜这里也没有,接着会到new Father()的原型中去找,OK,在Father.prototype中找到了这个数组,发现是["NO1","NO2","修改"] 。 再接着,我们创建了Father的实例对象theFather,同上,我们在Father.prototype中找到了这个引用类型的数组["NO1","NO2","修改"] 。(当然,数组都是引用类型的!) 通过上面的赘述,本来已经理解原型链概念的朋友觉得是废话连篇,其实我也是呵呵,接下来我们再看一个相似的例子: 复制代码 代码如下: //定义超类 function Father() { this.name = "父亲"; } Father.prototype.theSuperValue = ["NO1", "NO2"]; //定义子类 function Child() { } //实现继承 Child.prototype = new Father(); //修改共享数组 Child.prototype.theSuperValue = ["我是覆盖代码"] //创建子类实例 var theChild = new Child(); console.log(theChild.theSuperValue); //创建父类实例 var theFather = new Father(); console.log(theFather.theSuperValue); 我们看一下上面的代码,我用一种比较特别的紫色标注了此段代码与上段代码的小小区别,但结果却发生了“巨大”变化,见下面的截图: 为什么我说是巨大变化,是因为我们从“重用公共属性”过渡到“覆盖公共属性,建立自己特色属性”上来!我这里是用数组演示的,其实第二种情况常常用在Function中,用子类的方法来覆盖父类的方法 。 |