一、对象冒充:
function Parent(username){
this.username = username;
this.hello = function(){
alert(this.username);
}
}
function Child(username,password){
this.method = Parent; //method作为一个临时属性,并指向Parent所指向的对象
this.method(username); //执行method,即执行Parent构造函数
delete this.method; //销毁临时属性method,此时Child已经有了Parent的所有属性和方法
this.password = password;
this.world = function(){
alert(this.password);
}
}
var parent = new Parent("liuxiaowei");
var child = new Child("admin","123456");
parent.hello(); //liuxiaowei
child.hello(); //admin
child.world(); //123456
二、call方式:
call()是function类中的方法
call()方法的第一个参数的值赋给类(即方法)中出现的this
call()方法的第二个参数开始依次是赋给类(即方法)所接受的参数
function Parent(username){
this.username = username;
this.hello = function(){
alert(this.username);
}
}
function Child(username,password){
Parent.call(this,username); //在Child中执行Parent
this.password = password;
this.world = function(){
alert(this.password);
}
}
var parent = new Parent("liuxiaowei");
var child = new Child("admin","123456");
parent.hello(); //liuxiaowei
child.hello(); //admin
child.world(); //123456
缺点:
1.实例不是父类的实例,只是子类的
2.只能继承父类的属性和方法,不能继承父类原型属性和方法
3.无法实现函数服用,每个子类都有父类实例函数的副本
三、apply方式
apply()方法与call()相同
但是apply()第二个参数是数组类型,数组中的每个元素依次赋值给类(即方法)所接受的参数
Parent.apply(this,new Array(username));
四、原型链方式
function Parent(){
}
Parent.prototype.hello = "hello";
Parent.prototype.sayHello = function(){
alert(this.hello);
}
function Child(){
}
Child.prototype = new Person(); //将Parent中所有通过prototype追加的属性和方法都追加到Child
Child.prototype.world = "world";
Child.prototype.sayWorld = function(){
alert(this.world);
}
var c = new Child();
c.sayHello(); //hello
c.sayWorld(); //world
缺点:
1.无法多继承
2.来自原型对象的所有属性被所有实例共享
3.创建子类实例时,无法向父构造函数传参
五、call、原型链混合方式
function Parent(hello){
this.hello = "hello";
}
Parent.prototype.sayHello = function(){
alert(this.hello);
}
function Child(hello,world){
Prarent.call(this,hello);
this.world = "world";
}
Child.prototype = new Parent();
Child.prototype.sayWorld = function(){
alert(this.world);
}
var c = new Child("admin","123456");
c.sayHello(); //admin
c.sayWorld(); //123456
缺点:
1.调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上那份屏蔽了)