继承
- 让多个类之间建关系,便于代码的管理和复用
- 继承方式
- 原型继承,改变子类的原型对象
- Student.prototype = new Person()
- 缺点:如果父类中有引用数据类型,在子类生成的实例对象中改变该引用数据类型的值,就会影响子类其他实例对象,因为原型实例上的引用数据类型值会被所有实例共享
- Student.prototype = new Person()
function Person() { this.score = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] } let p1 = new Person() p1.score[0] = 2; let p2 = new Person() console.log(p2.score);// 这个不会影响,因为每new一次就创建一个新对象,this绑定到新对象上,引用数据指向不同的堆地址 function Students() { this.ponit = [88, 99] } Students.prototype = new Person() //把students的原型对象指向Person类的一个实例对象 let s1 = new Students() let s2 = new Students() s1.score[0] = 0 console.log('s2:' + s2.score); // 这里会影响,因为父类中引用数据类型前面的那个this,在原型继承时,已经确定为 new Person了,后面子类的实例对象不存在该引用数据this指向问题,所有子类实例中该引用数据都指向同一个堆地址,一旦一个实例对象修改,其他子类实例都会受影响 s2.ponit[1] = 100; console.log('s1:' + s1.ponit); // 这里不会影响,这里的this.point在 new Students时才绑定,各个实例指向了不同的堆地址
- 原型继承,改变子类的原型对象
- 组合继承
- 原型继承+call
- 原型继承 继承原型的公有属性
- call 继承原型的私有属性
- 调用call会让父类构造函数执行多一次
- 原型继承+call
function Person(name,age){
this.name = name;
this.age = age
}
Person.prototype.say = function(){}
Student.prototype = new Person() // 原型继承 可以继承公有方法
Student.prototype.constuctor = Student//原型继承后Student的constructor变成了Person,要重新指向
function Student(name,age,className){
Person.call(this,name,age) //这里会让父类代码执行一次, 不能用bind(bind不执行代码,this.不能赋值)
}
-
Object.create
- 可以给创建出来的对象指定原型对象
- Object.create(null) 创建一个没有原型对象的对象
-
寄生组合继承
- 通过 Object.create
function Person(name,age){
this.name = name;
this.age = age
}
Person.prototype.say = function(){}
//Student.prototype = new Person() // 原型继承 可以继承公有方法
Student.prototype = Object.create(Person.prototype) //把子类的原型指向父类的原型对象,不能拿到父类的私有属性,只能获取父类原型对象上的属性,也就是公有属性
Student.prototype.constuctor = Student//原型继承后Student的constructor变成了Person,要重新指向
function Student(name,age,className){
Person.call(this,name,age) //这里会让父类代码执行一次, 不能用bind(bind不执行代码,this.不能赋值)
}
- ES6中的继承
- 使用class声明一个类
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
say = () => { console.log('我的名字是' + this.name); }
}
class Student extends Person {
constructor(name, age, className) {
super(name, age)
this.className = className
}
}
let s1 = new Student('wc', 22, '1-2')