es6 class构造
class是es6提出来的概念,要想实现类似这种类的概念,在es6之前是通过原型的方式来实现的。
在es5中:
function Person() {
// 构造函数体
}
Person.prototype.sayHi = function() {
};
Person.prototype.play = function() {
};
es6中:
class Person {
constructor() {
// 构造函数体
}
// 下面这个sayHi和play就是Person.prototype上面的一个方法
sayHi() {};
play() {};
}
小结:
- 在ES5中,向原型上添加方法是:函数.prototype.方法名 = function() {};
- 在ES6中的对象的属性都是写在constructor关键字里面,方法也都是在原型身上。
es6 继承的底层实现原理
ES6类的底层还是通过构造函数去创建的。
// es6 Parent类实现
class Parent {
constructor(name, age) {
this.name = name;
this.age = age;
}
speakSomething() {
console.log("I can speak chinese");
}
}
// 转换为
var Parent = function() {
function Parent(name, age) {
_classCallCheck(this, Parent); // 判断实例Parent instanceof Parent(函数)是否为true
this.name = name;
this.age = age;
}
// 此方法通过使用Object.defineProperty为function Parent 的prototype添加属性值
_createClass(Parent, [{
key: "speakSomething",
value: function speakSomething() {
console.log("I can speek chinese");
}
}]);
return Parent;
}();
小结:
- 调用_classCallCheck方法判断当前函数调用前是否有new关键字
- 将class内部的变量和函数赋给this
- 执行constructor内部的逻辑
- return this(构造函数默认在最后我们做了)
ES6的继承实现
// 定义子类,继承父类
class Child extend Parent {
static width = 18;
constructor(name, age) {
super(name, age);
}
coding() {
console.log("I can code JS");
}
}
// 转化为
var Child = function (_Parent) {
_inherits(Child, _Parent);
function Child(name, age) {
_classCallCheck(this, child);
return _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).call(this, name, age));
}
_createClass(Child, [{
key: 'coding',
value: function coding() {
console.log("I can code JS");
}
}]);
return Child;
}(Parent);
小结:
1. 调用_inherits函数继承父类的prototype
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: { value: subClass, enumerable: false, writable: true, configurable: true }
});
if (superClass)
Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
(1)检验父构造函数
(2)典型的寄生继承:用父类构造函数的prototype创建一个空对象,并将这个对象指向子类构造函数的prototype。
(3)将父构造函数指向子构造函数的__proto__