码迷,mamicode.com
首页 > 编程语言 > 详细

一步步学习javascript基础篇(5):面向对象设计之对象继承(原型链继承)

时间:2015-12-07 16:17:15      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:

上一篇介绍了对象创建的几种基本方式,今天我们看分析下对象的继承。

一、原型链继承

1.通过设置prototype指向“父类”的实例来实现继承。

function Obj1() {
    this.name1 = "张三";
}
function Obj2() {
}
Obj2.prototype = new Obj1();
var t2 = new Obj2();
alert(t2.name1);

技术分享

这里有个明显的缺点就是:(如果父类的属性是引用类型,那么我们在对象实例修改属性的时候会把原型中的属性修改,这样会在每个实例对象中改变数据,而这不是我们想要的效果)

function Obj1() {
    this.arr = ["张三"];
}
function Obj2() {
}
Obj2.prototype = new Obj1();
var t2 = new Obj2();
alert(t2.arr);//打印“张三”
t2.arr[t2.arr.length] = "李四";
var t1 = new Obj2();
alert(t1.arr);//打印“张三,李四”

例:

那我们怎样规避这种问题呢?接着往下看。

2. 利用构造函数来实现继承

function Obj1() {
    this.arr = ["张三"];
}
function Obj2() {
    Obj1.call(this);//【1.新增】
}
//Obj2.prototype = new Obj1();【2.注释这行】
var t2 = new Obj2();
alert(t2.arr);//打印“张三”
t2.arr[t2.arr.length] = "李四";
var t1 = new Obj2();
alert(t1.arr);//打印“张三,李四”

我们看到上面代码,就注释了一行,新增了以后。打印出来的效果完全不一样了。现在的arr属性是每个实例对象独有的了。(之前是定义到原型上的,而原型的属性对每个实例都是共享的

 技术分享

技术分享

例:

同样,单纯的这种方式也是有问题的。因为我们这样就无法继承对象的方法了。如:

function Obj1() {
    this.arr = ["张三"];
}
Obj1.prototype.sayHi = function () { alert(this.arr); }////【1.新增】
function Obj2() {
    Obj1.call(this);
}        
var t2 = new Obj2();
//t2里面是没有sayHi方法的

我们可以使用原型和构造的混用来解决,如下:

3.通过原型和构造来实现继承

function Obj1() {
    this.arr = ["张三"];
}
Obj1.prototype.sayHi = function () { alert(this.arr); }
function Obj2() {
    Obj1.call(this);
}
Obj2.prototype = new Obj1();//【1.新增】
var t2 = new Obj2();
t2.sayHi();

如上,通过构造函数中的  Obj1.call(this); 和设置原型属性 Obj2.prototype = new Obj1(); 结合使用,完美解决问题。

这里需要注意一个地方,如果把 Obj2.prototype = new Obj1(); 改成 Obj2.prototype = Obj1.prototype ; 的话,会有你想不到的问题。如:

function Obj1() {
    this.arr = ["张三"];
}
Obj1.prototype.sayHi = function () { alert(this.arr); }
function Obj2() {
    Obj1.call(this);
}
Obj2.prototype = Obj1.prototype;//【1.新增】
var t2 = new Obj2();
t2.constructor.prototype.sayHi = function () { alert("test") };//修改Obj2中的原型的方法
var t1 = new Obj1();
t1.sayHi();
//影响到了Obj1中的原型的方法。因为 Obj2.prototype = Obj1.prototype;让两个对象的原型指向了同一处。
//所以还是只能用Obj2.prototype = new Obj1();

 例:

4.什么是原型链 

如:

//*************Obj1****
function Obj1() {
    this.arr = ["张三"];
}
Obj1.prototype.sayHi = function () { alert(this.arr); }

//*************Obj2****
function Obj2() {
    Obj1.call(this);
    this.name = "张三";
}
Obj2.prototype = new Obj1();
Obj2.prototype.sayHi2 = function () { alert(this.name); };

//*************Obj3****
function Obj3() {
    Obj2.call(this);
}
Obj3.prototype = new Obj2();
Obj3.prototype.sayHi3 = function () { };

//*******************
var t3 = new Obj3();
t3.sayHi();

 Obj3继承Obj2,Obj2继承Obj1。我们的Obj3的实例对象访问sayHi的时候,会先去Obj3的实例对象中找sayHi方法(没找到),然后去Obj3的原型中找(没找到),然后去父类Obj2的原型中找(没找到),然后去Obj1的原型中找(找到了)。这个找的路径就是原型链。

技术分享

 

这是学习记录,不是教程。文中错误难免,您可以指出错误,但请不要言辞刻薄。

原文链接:http://haojima.net/zhaopei/517.html

本文已同步至目录索引:一步步学习javascript

欢迎上海“程序猿/媛”、"攻城狮"入群:【沪猿】229082941 入群须知

欢迎对个人博客感兴趣的道友加入群:【嗨-博客】469075305 入群须知

如果您觉得文章对您有那么一点点帮助,那么麻烦您轻轻的点个赞,以资鼓励。

 

一步步学习javascript基础篇(5):面向对象设计之对象继承(原型链继承)

标签:

原文地址:http://www.cnblogs.com/zhaopei/p/5024260.html

(0)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!