class A () {
constructor () {
this.name = 'name';
}
}
创建对象的3种方法
字面量创建
var o1 = {name: '01'};
new 调用构造函数创建
var o2 = new A();
Object.create 方法创建
var o3 = Object.create(A);
实现new 运算符
var thisNew = function (func) {
var o = Object.create(func.prototype);
// 创建一个继承至func.prototype 的新对象 o
var k = func.call(o);
// 执行构造函数,把执行时的this 指向新对象 o。
if (typeof k === 'object') {
o = k;
}
// 如果构造函数返回的是一个对象,这个对象会取代新对象 o。
return o;
}
实现继承的 5 种方式
构造函数实现继承
原型链实现继承
组合继承
寄生组合继承
ES6 class extends 关键字继承
构造函数实现继承
function A () {}
function B () {
A.call(this);
}
优点:可以实现多继承
缺点:只继承了父类在构造函数中的属性,无法继承父类原型上的方法
原型链实现继承
function A () {}
function B () {}
B.prototype = new A();
B.prototype.constructor = B;
优点:可以继承父类的属性和方法
缺点:无法实现多继承;如果父类的属性是引用类型的,一个子类改变这个引用类型,所有的子类都会改变
组合继承
function A () {}
function B () {
A.call(this);
}
B.prototype = new A();
B.prototype.constructor = B;
组合继承由构造函数继承和原型链继承组合实现
优点:可以继承父类的属性和方法,并且子类不会共用引用类型的属性
缺点:执行了两次父类的构造函数,子类原型对象上会有多余的父类属性
寄生组合继承
function A () {}
function B () {
A.call(this)
}
B.prototype = Object.create(A.prototype)
B.prototype.constructor = B
寄生组合继承其实就是组合继承的优化
ES6 class extends 关键字继承
class A {
constructor () {}
}
class B extends A {
constructor () {
super(this)
}
}
JavaScript 面向对象
JavaScript 中类的实现
JS 中类的实现有两种方式。
创建对象的3种方法
实现new 运算符
实现继承的 5 种方式
构造函数实现继承
优点:可以实现多继承
缺点:只继承了父类在构造函数中的属性,无法继承父类原型上的方法
原型链实现继承
优点:可以继承父类的属性和方法
缺点:无法实现多继承;如果父类的属性是引用类型的,一个子类改变这个引用类型,所有的子类都会改变
组合继承
组合继承由构造函数继承和原型链继承组合实现
优点:可以继承父类的属性和方法,并且子类不会共用引用类型的属性
缺点:执行了两次父类的构造函数,子类原型对象上会有多余的父类属性
寄生组合继承
寄生组合继承其实就是组合继承的优化
ES6 class extends 关键字继承
ES5/ES6 的继承除了写法以外还有什么区别
class
声明内部会启用严格模式class
的所有方法都不可枚举class
的所有方法都没有原型对象prototype
class
必须使用new
调用