一.原型链继承
特点:
1.子类的实例即是本身也是父类。
2.父类新增的原型方法和属性,子类对象都可以访问。
缺点:
1.子类添加属性和方法必须写在new之后或者直接写在子类里面。
2.不能实现多继承。
3.子类的实例不能直接向父类传递参。
示例代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>
<!--
特点:
1.子类的实例即是本身也是父类
2.父类新增的原型方法和属性,子类对象都可以访问
缺点:
1.子类添加属性和方法必须写在new之后或者直接写在子类里面
2.不能实现多继承
3.子类的实例不能直接向父类传递参-->
</title>
</head>
<body>
<script>
/*父类的构造函数*/
function Animal(name, sex) {
this.name = name || 'Animal';
this.sex = sex || '未知';
this.sleep = function () {
console.log(this.name + "在睡觉!");
}
}
/*父类的原型对象*/
Animal.prototype = {
eat: function () {
console.log(this.name + "在吃饭!");
},
play: function () {
console.log(this.name + "在玩!");
}
};
/*子类的构造函数*/
function Cat() {
}
/*子类的原型对象
* 将父类的实例对象作为子类的原型对象
* 因为父类的实例对象的原型链指向父类的原型对象
* 所以子类的原型对象的原型链也指向父类的原型对象
* */
//Cat.prototype = new Animal('阿狸','男');
Cat.prototype = new Animal();
Cat.prototype.name = "阿狸";
Cat.prototype.sex = "男";
/*子类的实例对象(不能直接向父类传递参数)*/
var scat = new Cat();
scat.name = '桃子';
scat.sex = '女';
console.log(scat);
scat.sleep();
scat.eat();
scat.play();
console.log(scat instanceof Animal);//true,即子类的实例是父类(instanceof:用来测试一个对象是否为一个类的实例)
console.log(scat instanceof Cat);//true,即子类的实例是本身
</script>
</body>
</html>
二.构造继承
特点:
1.创建子类的时候可以向父类传递参数。
2.可以实现多继承。
缺点:
1.子类对象的实例是本身而不是父类。
2.只能继承父类的构造属性和方法,不能继承原型属性和方法。
3.不是完全的继承,类似克隆父类的副本。
示例代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>
<!--
特点:
1.创建子类的时候可以向父类传递参数。
2.可以实现多继承。
缺点:
1.子类对象的实例是本身而不是父类。
2.只能继承父类的构造属性和方法,不能继承原型属性和方法。
3.不是完全的继承,类似克隆父类的副本。-->
</title>
</head>
<body>
<script>
/*动物类的构造函数*/
function Animal(name, sex) {
this.name = name || 'Animal';
this.sex = sex || '未知';
this.sleep = function () {
console.log(this.name + "在睡觉!");
}
}
/*动物类的原型对象*/
Animal.prototype = {
eat: function () {
console.log(this.name + "在吃饭!");
},
play: function () {
console.log(this.name + "在玩!");
}
};
/*科目类的构造函数*/
function Type(type) {
this.type = type || '类型';
}
/*科目类的原型对象*/
Type.prototype.paTree = function (args) {
console.log(args);
};
/*
*子类的构造函数
*复制父类的构造属性给子类(复制不到父类的原型)
*构造继承,使用父类的构造函数来增强子类
* */
function Cat(name, sex, type) {
Animal.call(this, name, sex);
Type.call(this, type);
}
/*子类的实例对象*/
var cat = new Cat('阿狸', '男', '犬科');
cat.sleep();
console.log(cat);
console.log(cat instanceof Cat);//true
console.log(cat in Animal);//false
console.log(cat instanceof Type);//false
</script>
</body>
</html>
三.实例继承
特点:
1.不限制调用方式:可以new也可以直接调用函数执行。
缺点:
1.不支持多继承。
示例代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>
<!--
优点:
1.不限制调用方式:可以new也可以直接调用函数执行。
缺点:
1.不支持多继承。-->
</title>
</head>
<body>
<script>
/*父类的构造函数*/
function Animal(name, sex) {
this.name = name || 'Animal';
this.sex = sex || '未知';
this.sleep = function () {
console.log(this.name + "在睡觉!");
}
}
/*父类的原型对象*/
Animal.prototype = {
eat: function () {
console.log(this.name + "在吃饭!");
},
play: function () {
console.log(this.name + "在玩!");
}
};
/*子类的构造函数*/
function Mouse() {
var animal = new Animal();
return animal;
}
var mouse = new Mouse();
console.log(mouse);
console.log(mouse instanceof Mouse);//false
console.log(mouse instanceof Animal);//true
</script>
</body>
</html>
四.组合继承
特点:
1.原型链继承和构造继承相互弥补缺点。
缺点:
1.里面存在两个实例消耗内存。
示例代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>
<!--
特点:
1.原型链继承和构造继承相互弥补缺点。
缺点:
1.里面存在两个实例消耗内存。-->
</title>
</head>
<body>
<script>
/*父类的构造函数*/
function Animal(name, sex) {
this.name = name || 'Animal';
this.sex = sex || '未知';
this.sleep = function () {
console.log(this.name + "在睡觉!");
}
}
/*父类的原型对象*/
Animal.prototype = {
eat: function () {
console.log(this.name + "在吃饭!");
},
play: function () {
console.log(this.name + "在玩!");
}
}
/*子类的构造函数*/
function Cat(name,sex){
Animal.call(this,name,sex);//构造继承
}
Cat.prototype=new Animal();//原型链继承
var cat=new Cat('阿狸','男');
console.log(cat);
cat.eat();
console.log(cat instanceof Animal);//true
console.log(cat instanceof Cat);//true
</script>
</body>
</html>
五.寄生继承
特点:
1.没有创建自定义类型,只是套了个壳子返回对象,这个函数即为创建的新对象。
缺点:
1.没有用到原型,无法复用。
示例代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype = {
sleep: function () {
console.log(this.name + "在睡觉!");
}
};
var p = new Person('小明', 18);//实例化person
function Student(obj) {
function fun() {
}
fun.prototype = obj;//寄生在fun函数的原型对象上面
return new fun();
}
function getObj() {
var stu = Student(p);
stu.work = "学习";
return stu;
}
var s = getObj();
console.log(s);
s.sleep();
</script>
</body>
</html>