JS中的继承
继承:在基于类的语言中,对象是类的实例,并且类可以从另一个类继承,JS是一门基于原型的语言,这意味着对象直接从其他对象继承。
通过原型实现继承:一个新对象可以继承一个旧对象的属性。你通过创建一个有用的对象开始,接着可以创建更多和那个对象类似的对象。
//用于给新创建的对象更换原型 Object.create = function (o){ var F = function (){}; F.prototype = o; return new F() } var myMam = { name: 'CSH', getName: function (){ return this.name; }, getSays: function (){ return this.saying || ''; } }; //创建一个新的对象,这个对象的原型继承了myMan对象 var myCat = Object.create(myMam) myCat.saying = 32; myCat.getSays() //32 myCat.getName() //CSH
函数化继承:函数化可以让我们拥有私有变量和私有函数。
var cons = function (my){ var that; //私有变量 my = my || {}; //把共享的变量和函数添加到my对象中 that = {name: 'csh'}; //一个对象 return that; //返回that对象给cons }
my对象是一个为继承链中的构造器提供秘密共享的容器。my对象选择性地使用。如果没有传入一个my对象,那么会创建一个my对象。接下来声明该对象私有实例变量和方法。通过简单的声明变量就可以做到。构造器的变量和内部函数变成了该实例的私有成员。内部函数可以访问my、that以及其他私有变量。
给my对象添加共享的成员(my对象是全局对象):
my.member = value; my.sic = function (){ //code....... };
我们还可以扩充that,加入组成该对象接口的特权方法,我们可以在that私有变量中添加方法或者某些属性(这个变量最后会return返回给cons变量)。或者更安全地,我们可以先将函数定义为私有方法,然后再将他们分配给that:
//分两步定义met的好处是,如果其他方法想要调用met,它们可以直接调用met()。 //如果该实例被破坏、篡改或者被替换掉,调用met的方法将同样会继续工作。 var met = function (){ //code...... }; that.met = met;
函数化模式还给我们提供了一个处理父类方法。我们将构造一个super方法,它取得一个方法名并返回调用那个方法的函数。该函数将调用原来的方法,尽管属性已经变化了:
Object.prototype.super = function (name){ var that = this, method = that[name]; return function (){ return method.apply(that, arguments); } }