您好,欢迎访问一九零五行业门户网

关于JavaScript中原型继承中的一点思考_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中,用子类的方法来覆盖父类的方法。
在第二段代码中,我们需要关注的是紫色代码前的“=”号,它是赋值操作符。如果我们对child.prototype及new father()对象调用这个赋值操作符时,我们就在这个对象上“新建”了一个属性,当在下面的thechild实例上调用thesupervalue时,返回的当然是新属性值[我是覆盖代码]。
但当我们新创建一个父类实例thefather对象时,调用该对象上的thesupervalue属性,我们就会发现对象上并没有啊,这是为什么呢?因为我们刚才覆盖的是father对象new father();而不是father类,所以,通过fater()构造函数创建的新对象thefather并不包含新建的属性,当然,接下来的事情大家都明白,就是沿着原型链向上找,ok,在father.prototype中找到了,就是我们一开始定义的那个数组。
通过上面两个例子,我们在js中使用原型提供的继承功能时,尤其是利用子对象操作原型方法、对象时,切记“=”号赋值与引用调用这两种不同的操作,因为他们会带来完全不同的结果。
其它类似信息

推荐信息