js 继承 分为 原型继承、组合继承、寄生组合继承、es6的extend
---------------------------------------------------
原型继承
1.父类的实例作为子类的原型
2.缺点:子类的实例对象共享了父类的构造函数的引用属性
function Person() {
this.name = "tom"
this.money = {
consume: 100,
deposit: 10000
}
}
function Student() {
this.school = "希望小学"
}
Student.prototype = new Person()
var stu = new Student()
console.log(stu.name) // tom
++++++++++++++++++++++++++++++++++++
Student.prototype = new Person() // 父类的实例作为子类的原型
Student的原型属性的值是 Person 的实例
new Person() 的作用过程如下:
var p = {}
p.__proto__ = Person.prototype
var res = Person.call(p)
return res instanceof Object ? res : p
Student.prototype = p ==> Student.prototype.__proto__ == Person.prototype
完成了原型链
Student.prototype.__proto__ = Person.prototype
var o = {}
o.__proto__ = Student.prototype
var res = Student.call(o) // this.school = "希望小学"
实现了共享
o.__proto__.__proto__ = Person.prototype
++++++++++++++++++++++++++++++++++++
stu.money.consume = 200
var stu1 = new Student()
console.log(stu1.money,consume) // 200
这说明了子类的实例对象共享了父类构造函数的引用属性
var p = new Person()
console.log(p.money.consume) // 100
----------------------------------------------
组合继承
1.在子类构造函数中运行父类构造函数 改变this指向
2.获取父类的原型属性的值的方法 改变constructor 解决共享引用属性的问题
3.优点:可传参 不再共享引用属性 缺点:父类构造函数调用了两次
function Person(name) {
this.name = name
this.money = {
consume: 100
}
}
Person.prototype.getName = function() {
alert(this.name)
}
function Man(name, sex) {
Person.call(this, name) // this.name = name
this.sex = sex
}
Man.prototype = new Person()
Man.prototype.constructor = Man
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
function Person(name) {
this.name = name
this.money = {
consume: 100
}
}
Person.prototype.getName = function() {
alert(this.name)
}
function Man(name, sex) {
//把这个引用类型独立出来,放在Man的构造函数里,让Man的实例们各自生成自己的这个属性 屏蔽了原型链上的money属性 (Person)
Person.call(this, name) // 关键代码 解决共享
this.sex = sex
}
Man.prototype = new Person()
Man.prototype.constructor = Man
var tom = new Man('tom', 'man')
console.log(tom.money) // {consume: 200}
tom.money.consume = 200
var john = new Man('john', 'man')
console.log(john.money) // {consume: 100}
// 没有共享
</script>
</body>
</html>
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
function P() {
this.info = {width: 100}
}
function S() {
this.info = {width: 200}
}
S.prototype = new P()
var s = new S()
console.log(s.info.width) // 200
屏蔽了原型链上的info
+++++++++++++++++++++++++++++++++++++++++++++++++++++++