本文实例汇总了javascript关于继承的用法。分享给大家供大家参考。具体如下:
例子:
复制代码 代码如下:
/**
* 实现子类继承父类,但不会产生多余的属性和方法
* @returns {function}
*/
define(function(){
return function(subtype, supertype){
var proto = new object(supertype.prototype);
proto.constructor = subtype;
subtype.prototype = proto;
};
});
//——————————————————————————
define(function(){
function ostring(s)
{
this.str = s;
this.length = this.str.length;
}
ostring.prototype.show = function(){
alert(this.str);
};
return ostring;
});
//——————————————————————————
define(['inherit', 'ostring'], function(inherit, ostring){
function wstring(s){
//用call实现调用父类构造函数
ostring.call(this, s);
this.chlength = 2 * s.length;
}
//继承其他的属性
inherit(wstring, ostring);
wstring.prototype.add = function(w)
{
alert(this.str + w);
};
return wstring;
});
再看例子
一、用function实现:
复制代码 代码如下:
function person(name) {
this.name = name;
}
person.prototype.getname = function() {
return this.name;
}
function author(name, books) {
this.inherit=person;
this.inherit(name);
this.books = books;
}
var au=new author(dororo,learn much);
au.name
或者同等效力的:
复制代码 代码如下:
function person(name) {
this.name = name;
}
person.prototype.getname = function() {
return this.name;
}
function author(name, books) {
person.call(this, name);
this.books = books;
}
var au=new author(dororo,learn much);
au.getname
由于这只是将this作为参数,调用父类person的构造函数,把赋予父类的所有域赋予author子类,所以任何父类person构造函数之外的定义的域(原型prototype),子类都不会继承。所以上面例子中,au.getname将是没有被定义的(undefined),因为getname是在person的原型对象中定义的。而且,子类的构造函数要在定义自己的域之前调用父类构造函数,免得子类的定义被父类覆盖掉。也就是说,author定义属性book要在person.call之后,否则会被person中属性覆盖。同时,在子类中也最好不要用prototype来定义子类的函数域,因为在一个子类被new,实例化之后就要执行prototype,然后才是调用父类的构造函数,这样也容易被父类的属性覆盖掉。
二、用prototype实现:
复制代码 代码如下:
function person(name) {
this.name = name;
}
person.prototype.getname = function() {
return this.name;
}
function author(name, books) {
this.books = books;
}
author.prototype=new person(name);
author.prototype.constructor=author;
author.prototype.getbooks = function() {
return this.books;
}
var au1=new author(dororo1,learn much);
var au2=new author(dororo2,learn less);
alert(au1.getname());
alert(au2.getname());
这种方法避免了function实现中,无法继承prototype的问题。因为 author.prototype=new person(name);new person()实例会调用person构造和原型的所有属性。但是缺点是已经实例化了author.prototype。所以当子类实例化的时候,所有非基本数据类型都是reference copy。所以上面例子中,无论实例au1,还是au2返回的值都是dororo1.三、用“混合”实现
复制代码 代码如下:
function person(name) {
this.name = name;
}
person.prototype.getname = function() {
return this.name;
}
function author(name, books) {
this.base = new person(name);
for(var key in this.base){
if(!this[key]){
this[key]=this.base[key];
}
}
this.book=books;
}
var au1=new author(dororo1,work);
var au2=new author(dororo2,play);
alert(au1.getname());
alert(au2.getname());
au1.book;
au2.book;
属于扩展,把父类的所有域都拷贝到子类。完全没有上述两方面的问题。
寄生组合模式)js的继承包括属性的继承和方法的继承,他们分别通过不同的方法来实现。
1.属性的继承
属性的继承通过改变函数的执行环境来实现的。而改变函数的执行环境可以使用call()和apply()两种方法来实现。
我们首先创建一个animal“类”(因为js中没有类的概念,这里只是一个模拟,它实际上只是一个function函数对象)。
复制代码 代码如下:
function animal(typename) {
//为当前方法的执行环境(this)添加一个属性typename
//但是执行环境(this)要执行这个函数的时候才能确定
this.typename = typename;
this.colors = [red,while];
}
//想函数的原型里 添加 两个(对象共享的)的方法
animal.prototype.shout = function () { alert(我是:-- + this.typename);};
animal.prototype.eat = function () { alert(我是:-- + this.typename) };
//--定义一个狮子--“类”(其实就是一个函数)
function lion(tn) {
//--执行animal方法,并通过apply的第一个参数 修改了animal的执行环境为lion的this
//同样的,lion的this,也要在执行的时候才能确定是谁
animal.apply(this,[狮子]);//--继承了父类的变量属性,this因为是new了lion,this是lion
}
lion.prototype = animal.prototype; //继承父类的方法,搞定--但是这写不好,当子类再添加方法时候,父类同样也有此方法,这是指针引用
lion.prototype.hunt = function () {
alert(我是:狮子,我要去捕猎~~·~);
}
var aminm = new animal();
aminm.hunt(); //---可以访问到子类的方法,这样就不好了
//----那么如何解决这个问题呢》??????
//---解决方案:继承方法时候可以这样写:
lion.prototype = new animal();//继承父类的方法,把animal对象赋给了prototype原型,其实它里面也有属性
var lion = new lion(); //new 关键字除了创建的,还会修改lion对象的执行环境为lion对象本身
// ---换句话说,就是new完了之后,lion函数里的this就是lion函数本身了,然后调用lion函数
分析一下new关键字:
而new关键字是十分伟大的,在上段代码中,new关键字完成了以下几项工作:
1)开辟堆空间,以准备存储lion对象
2)修改lion对象本身的执行环境,使得lion函数的this指向了lion函数对象本身。
3)调用lion“类”的“构造函数”,创建lion对象
4)将lion函数对象的堆地址赋值给变量l,这个时候l就指向了这个lion函数对象
lion.shout();
lion.eat();
但是这种继承有个缺点:就是父类的构造函数的被调用了两次,call一次,然后new又一次。
希望本文所述对大家的javascript程序设计有所帮助。