继承机制,全靠一种很奇特的“原型链”(prototype chain)模式,来实现继承。
实例化没办法继承,每一个实例对象,都有自己的属性和方法。这不仅无法做到数据共享,也是极大的资源浪费。
于是有了 prototype属性的引入:
这个属性包含一个对象(prototype对象),所有实例对象需要共享的属性和方法,都放在这个对象里面;那些不需要共享的属性和方法,就放在构造函数里面。
Javascript还提供了一个instanceof运算符,验证原型对象与实例对象之间的关系。
还有:isPrototypeOf()
这个方法用来判断,某个proptotype对象和某个实例之间的关系。
alert(Cat.prototype.isPrototypeOf(cat1)); //true
alert(Cat.prototype.isPrototypeOf(cat2)); //true
hasOwnProperty()
每个实例对象都有一个hasOwnProperty()方法,用来判断某一个属性到底是本地属性,还是继承自prototype对象的属性.
alert(cat1.hasOwnProperty("name")); // true
alert(cat1.hasOwnProperty("type")); // false
构造函数的继承:
1、构造函数绑定
function Cat(name,color){
Animal.apply(this, arguments);
this.name = name;
this.color = color;
}
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物
2、prototype模式
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物
3、利用空对象作为中介
var F = function(){};
F.prototype = new Animal();
Cat.prototype = new F();
Cat.prototype.constructor = Cat;
F是空对象,所以几乎不占内存。这是,修改Cat的prototype对象,就不会影响到Animal的prototype对象。
非构造函数的继承:
1、object()方法
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
2、浅拷贝
function extendCopy(data) {
var c = {};
for (var i in data) {
c[i] = data[i]
}
return c;
}
3、深拷贝
function deepCopy(data, c) {
var c = c || {};
for (var i in data) {
if (typeof data[i] === 'object') {
c[i] = (data[i].constructor === Array) ? [] : {};
deepCopy(data[i], c[i]);
} else {
c[i] = data [i]
}
}
return c;
}