1. ES5中原型继承
functiion Person (name, age) {
// 私有属性
this.name = name,
this.say = function () {
console.log('my name is' + this.name)
}
}
// 原型方法
Person.prototype.cry = function () {
console.log(this.name + 'cried')
}
//使用new来调用构造函数的目的,当引擎执行到new关键字时,会在内存中开辟一段内存空间,并且new关键字会把内存空间的首地址返回出来,这样就可以通过接收返回值的变量来访问这段内存空间
//在构造函数中,添加属性方法时添加在this指针上的,this指针的指向取决于调用者,构造函数是new调用的,而new开辟了新的内存空间,所以this指针就执行这段内存空间,向this指针指定的属性和方法,最后添加在了这段内存中。
//自动返回new开辟的内存空间的首地址
原型继承: 将上级函数的实例赋值给下级函数的原型
function Son () {}
Son.prototype = new Person()
2. 借用构造函数
- 基本思想:在子类型构造函数的内部调用超类型构造函数,通过使用apply()和call()方法可以在将来新创建的对象上执行构造函
function People() {
this.colors = ["red", "blue", "green"];
}
function Women() {
// 借调了超类型的构造函数
People.call(this);
}
var instance1 = new Women();
instance1.colors.push("black");
console.log(instance1.colors); // ["red", "blue", "green", "black"]
var instance2 = new Women();
console.log(instance2.colors); // ["red", "blue", "green"]
// 并不能完成函数实例对上级函数原型的继承,但是解决了私有属性复用问题,借用构造函数继承,可以实现所谓继承(模拟继承,js天生没有继承的方法)
3. ES6 继承
// class这样声明出来的类其实在底层还是使用了 JavaScript 的函数 和 原型链 (来模拟类的行为)
// class相当于es5中的构造函数
// class中只能定义方法,不能定义对象,变量等
class People {
constructor (color){
this.color = color
}
sale () {
return this.color
}
}
class Women extends People {
constructor(color){
// constructor()方法返回一个全新的对象
// 子类继承父类,会同时继承父类的私有属性方法,constructor()为私有属性方法
// 如果一个类没有指定constructor() 方法,则会添加默认的constructor()方法;
// 子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工,如果不调用super方法,子类就得不到this对象。因此,只有调用super之后,才可以使用this关键字。
super(color) //使用extend必须使用super(); super关键字来调用父类的构造方法;
}
sale () {
super.sale()
}
}
let p = new Women('red');
console.log(p)
- 用Object.create实现类继承
// Shape - 父类(superclass)
function Shape() {
this.x = 0;
this.y = 0;
}
// 父类的方法
Shape.prototype.move = function (x, y) {
this.x += x;
this.y += y;
console.info('Shape moved.');
};
// Rectangle - 子类(subclass)
function Rectangle() {
Shape.call(this); // call super constructor.
}
// 子类续承父类
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle; // 修正constructore指向
var rect = new Rectangle();
console.log('Is rect an instance of Rectangle?',
rect instanceof Rectangle); // true
console.log('Is rect an instance of Shape?',
rect instanceof Shape); // true