原型链继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function Parent() {
this.money = 100000
this.head = 1
}
function Child(name, age) {
this.name = name
this.age = age
}
//要放在创建实例之前
// 会造成继承链紊乱
Child.prototype = new Parent()
var son = new Child('jiffy', 22)
// 手动拨正
Child.prototype.constructor = Child
alert(Child.prototype.constructor)
alert(Parent.prototype.constructor)
alert(son.name)
alert(son.age)
alert(son.money)
alert(son.head)
</script>
</body>
</html>
prototype属性直接继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function Parent() { }
// 将要继承的属性赋给prototype属性
Parent.prototype.money = 100000
Parent.prototype.head = 1
function Child(name, age) {
this.name = name
this.age = age
}
// 直接继承父类prototype属性 省去new对象节省内存
// 还是会继承链紊乱
Child.prototype = Parent.prototype
var son = new Child('jiffy', 22)
// 手动拨正
Child.prototype.constructor = Child
// 新问题,因为手动拨正的原因,父类构造函数变成子类的了
alert(Child.prototype.constructor)
alert(Parent.prototype.constructor)
alert(son.name)
alert(son.age)
alert(son.money)
alert(son.head)
</script>
</body>
</html>
空对象作为中介
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function Parent() {
}
// 将要继承的属性赋给prototype属性
Parent.prototype.money = 100000
Parent.prototype.head = 1
function Child(name, age) {
this.name = name
this.age = age
}
// 空对象 几乎不占内存 解决父类构造器同步改变
function extend(Son, Father) {
var N = function () { }
N.prototype = Father.prototype
Son.prototype = new Father()
}
// 依然会造成继承链紊乱
extend(Child, Parent)
var son = new Child('jiffy', 22)
// 手动拨正
Child.prototype.constructor = Child
alert(Child.prototype.constructor)
alert(Parent.prototype.constructor)
alert(son.name)
alert(son.age)
alert(son.money)
alert(son.head)
</script>
</body>
</html>
构造函数绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function Parent() {
}
// 将要继承的属性赋给prototype属性
Parent.prototype.money = 100000
Parent.prototype.head = 1
function Child(name, age) {
this.name = name
this.age = age
}
// 空对象 几乎不占内存 解决父类构造器同步改变
function extend(Son, Father) {
var N = function () { }
N.prototype = Father.prototype
Son.prototype = new Father()
}
// 依然会造成继承链紊乱
extend(Child, Parent)
var son = new Child('jiffy', 22)
// 手动拨正
Child.prototype.constructor = Child
alert(Child.prototype.constructor)
alert(Parent.prototype.constructor)
alert(son.name)
alert(son.age)
alert(son.money)
alert(son.head)
</script>
</body>
</html>
组合继承
说实话,在探索到它的意义之前,我认为这是鸡肋的实现方式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<h1>组合继承</h1>
<strong>也叫伪经典继承</strong>
<ul>
<li>将原型继承和构造函数继承组合在一块</li>
<li>原型链实现对原型属性和方法的继承</li>
<li>借用构造函数实现对实例属性的继承</li>
</ul>
</div>
<script>
function Parent() {
this.money = 100000
this.head = 1
this.hobbies = ['reading', 'fight', 'sleep']
this.say = function () {
alert('我喜欢' + this.hobbies)
}
}
// TODO 这和单独使用构造函数实现继承效果一样 所以多敲几行代码有什么意义?
// Parent.prototype.say = function () {
// alert('我是原型方法,通过原型链继承')
// }
function Child(name, age) {
// 将父对象的构造函数绑定在子对象中
Parent.call(this)
this.name = name
this.age = age
}
// Child.prototype = new Parent()
// Child.prototype.constructor = Child
var son = new Child('jiffy', 22)
alert(Child.prototype.constructor)
alert(Parent.prototype.constructor)
son.say()
</script>
</body>
</html>
拷贝继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<h1>拷贝继承</h1>
<strong>把父对象的所有属性和方法,拷贝进子对象</strong>
<p>将父对象的prototype对象中的属性,一一拷贝给Child对象的prototype对象中</p>
</div>
<script>
function Parent() {
}
Parent.prototype.money = 100000
Parent.prototype.head = 1
Parent.prototype.say = function () {
alert('虽然我只有一个头,但我有' + this.money + '块')
}
function Child(name, age) {
this.name = name
this.age = age
}
function extend(Son, Father) {
var fa = Father.prototype
var son = Son.prototype
for (var i in fa) {
son[i] = fa[i]
}
}
extend(Child, Parent)
var son = new Child('jiffy', 22)
alert(Child.prototype.constructor)
alert(Parent.prototype.constructor)
son.say()
</script>
</body>
</html>