一、原型
我们创建的每个函数都有一个 prototype(原型)属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法。逻辑上可以这么理解:prototype 通过调用构造函数而创建的那个对象的原型对象。 使用原型的好处可以让所有对象实例共享它所包含的属性和方法。也就是说,不必在构造函数中定义对象信息,而是可以直接将这些信息添加到原型中。
二、原型代码
<span style="font-family:KaiTi_GB2312;font-size:18px;">function Box() {} //声明一个构造函数
Box.prototype.name = 'Lee'; //在原型里添加属性
Box.prototype.age = 100;
Box.prototype.run = function () { //在原型里添加方法
return this.name + this.age + '运行中...';
};
//比较一下原型内的方法地址是否一致:
var box1 = new Box();
var box2 = new Box();
alert(box1.run == box2.run); //true,方法的引用地址保持一致</span>
为了更进一步了解构造函数的声明方式和原型模式的声明方式, 我们通过图示来了解一下:
三、组合构造函数+ 原型模式
原型模式创建对象也有自己的缺点, 它省略了构造函数传参初始化这一过程, 带来的缺点就是初始化的值都是一致的。而原型最大的缺点就是它最大的优点,那就是共享。
原型中所有属性是被很多实例共享的, 共享对于函数非常合适, 对于包含基本值的属性也还可以。但如果属性包含引用类型,就存在一定的问题:
<span style="font-family:KaiTi_GB2312;font-size:18px;">function Box() {};
Box.prototype = {
constructor : Box,
name : 'Lee',
age : 100,
family : ['父亲', '母亲', '妹妹'], //添加了一个数组属性
run : function () {
return this.name + this.age + this.family;
}
};
var box1 = new Box();
box1.family.push('哥哥'); //在实例中添加'哥哥'
alert(box1.run());</span>
<span style="font-family:KaiTi_GB2312;font-size:18px;">var box2 = new Box();
alert(box2.run()); //共享带来的麻烦,也有'哥哥'了</span>
PS:数据共享的缘故,导致很多开发者放弃使用原型,因为每次实例化出的数据需要保留自己的特性,而不能共享。
为了解决构造传参和共享问题,可以 组合构造函数+ 原型模式:
<span style="font-family:KaiTi_GB2312;font-size:18px;">function Box(name, age) { //不共享的使用构造函数
this.name = name;
this.age = age;
this. family = ['父亲', '母亲', '妹妹'];
};
Box.prototype = { //共享的使用原型模式
constructor : Box,
run : function () {
return this.name + this.age + this.family;
}
};
PS:这种混合模式很好的解决了传参和引用共享的大难题。是创建对象比较好的方法。</span>
四、继承
1、继承是面向对象中一个比较核心的概念。 其他正统面向对象语言都会用两种方式实现继承:一个是接口实现,一个是继承。而 ECMAScript 只支持继承,不支持接口实现,而实现继承的方式依靠原型链完成。
<span style="font-family:KaiTi_GB2312;font-size:18px;">function Box() { //Box 构造
this.name = 'Lee';
}
function Desk() { //Desk 构造
this.age = 100;
}
Desk.prototype = new Box(); //Desc 继承了 Box,通过原型,形成链条
var desk = new Desk();
alert(desk.age);
alert(desk.name); //得到被继承的属性
function Table() { //Table 构造
this.level = 'AAAAA';
}
Table.prototype = new Desk(); //继续原型链继承
var table = new Table();
alert(table.name); //继承了 Box 和 Desk</span>
2、原型链继承流程图
【总结】
自己认为原型模式该开始学习的时候还是比较难理解的但是通过自己很好的学习之后觉着好了很多,看来总结的知识是很重要的,无论是新的知识还是旧的知识。