避免了function实现中,无法继承prototype的问题。因为 Author.prototype=new Person(name);new Person()实例会
。但是缺点是已经实例化了Author.prototype。所以当子类实例化的时候,所有非基本数据类型都是reference copy。所以上面例子中,无论实例au1,还是au2返回的值都是dororo1.
属于扩展,把父类的所有域都拷贝到子类。完全没有上述两方面的问题。
寄生组合模式)
JS的继承包括属性的继承和方法的继承,他们分别通过不同的方法来实现。
1.属性的继承
属性的继承通过改变函数的执行环境来实现的。而改变函数的执行环境可以使用call()和apply()两种方法来实现。
我们首先创建一个Animal“类”(因为JS中没有类的概念,这里只是一个模拟,它实际上只是一个Function函数对象)。
方法的执行环境(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程序设计有所帮助。