JavaScript 继承

原型式继承

在 js 中, 方法定义在原型对象中, 而属性定义在实例对象中,调用方法的时候, 实例对象本身是没有该成员的, 但是依旧可以调用该方法, 好像这个方法就是该实例对象的一样. 因此, 我们称该实例对象继承自原型对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var Person={
sayHello:function(){
console.log('我是'+this.name+'今年'+this.age);
}
}

//student构造函数
function Student(name,age){
this.name=name;
this.age=age;
}

//这里把Person对象赋值到Student构造函数的原型对象上,这样Student构造函数的实例就可以运用Person对象的方法
Student.prototype=Person;

//根据Student构造函数创建一个实例对象s1.
var s1=new Student('lilei',18);

s1.sayHello();

混入

就是将一个对象中的成员加到另一个对象中(通过自定义 extend 方法完成继承)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var obj2= {
name:'lilei',
sayHello:function(){
console.log('我是'+this.name);
}
};

var obj3= {
age:18,
sayHello1:function(){
console.log('我是'+this.name+'今年'+this.age);
}
};

var obj1={
extend:function(obj){

//arguments为函数中默认的对象,里面存储着所有的函数传入参数。
for(var i=0; i< arguments.length;i++){

for(var k in arguments[i]){
this[k]=arguments[i][k];
}

}
}
};

//将obj2和obj3混入到obj1中
obj1.extend(obj2,obj3);

obj1.sayHello();

obj1.sayHello1();

混合式继承

将多个对象的各个功能混合在一起,就是通过混入的方式,加到构造函数的原型(prototype)上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var Person={
sayHello:function(){
console.log('我是'+this.name+'今年'+this.age);
}
}
function Student(name,age){//student构造函数
this.name=name;
this.age=age;
}
Student.prototype.extend=function(obj){
for(var k in obj){
this[k]=obj[k];
}
}

// 根据Student构造函数创建一个实例对象s1.
var s1=new Student('lilei',18);

// 根据Student构造函数创建一个实例对象s2.
var s2=new Student('lllli',18);

// 这样就是Student构造函数继承了Person对象。所有Student构造函数创建的实例都要Pserson对象的方法
Student.prototype.extend(Person);

// 这样就是Student构造函数的实例s1继承了Person对象。其他Student构造函数创建的实例都没有Pserson对象的方法
// s1.extend(Person);

s1.sayHello();
s2.sayHello();
  • 关于继承 ES5 中给我们内置了一个快速的方法:Object.create(对象)
1
2
3
4
5
6
7
8
9
10
11
12
var o={
name:'lilei',
age:16,
sayHello:function(){
console.log('我是'+this.name+'今年'+this.age);
}
};

//ES5中内置的Object.create()方法可以让我们快速的继承
var obj=Object.create(o);

obj.sayHello();

上下文调用实现继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var Person={
sayHello:function(){
console.log('我是'+this.name+'今年'+this.age);
}
};

function Student(name,age){//student构造函数
this.name=name;
this.age=age;
};

//根据Student构造函数创建一个实例对象s1.
var s1=new Student('lilei',18);

//根据Student构造函数创建一个实例对象s2.
var s2=new Student('lllli',18);

Person.sayHello.call(s2);

ES6 的继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// es6继承
class Animal {

//构造函数,里面写上对象的属性
constructor(props) {
this.name = props.name || 'Unknown';
}

//方法写在后面
eat() {
//父类共有的方法
console.log(this.name + " will eat pests.");
}
}

//class继承
class Bird extends Animal {

//构造函数
//props是继承过来的属性,myAttribute是自己的属性
constructor(props,myAttribute) {
//调用实现父类的构造函数
//相当于获得父类的this指向
super(props)

//父类的属性,也可写在父类中
this.type = props.type || "Unknown";

//自己的私有属性
this.attr = myAttribute;
}

//自己私有的方法
fly() {
console.log(this.name + " are friendly to people.");
}

//自己私有的方法
myattr() {
console.log(this.type+'---'+this.attr);
}
}

//通过new实例化
var myBird = new Bird({
name: '小燕子',

//卵生动物
type: 'Egg animal'
},'Bird class')

myBird.eat()
myBird.fly()
myBird.myattr()