典型的es6类:
类的成员: 构造方法,属性,方法,静态方法等
class Parent {
height = 20;
constructor(name) {
this.name = name;
}
static sayHello() {
console.log('hello');
}
sayName() {
console.log('my name is ' + this.name);
return this.name;
}
}
class Child extends Parent {
constructor(name, age) {
super(name);
this.age = age;
}
sayAge() {
console.log('my age is ' + this.age);
return this.age;
}
}
类的使用时new出来的,跟es5不一样; 类的写法跟es5也是不一样,那么有如下问题:
- es6这样的写法对应于es5写法,类定义哪些属性和方法是对应起来的
- 当继承发生的时候,过程是怎样的
1. es6这样的写法对应于es5写法,类定义哪些属性和方法是对应起来的
es5类的定义
function ClassName () {
this.x = 1;
this.y = 2;
this.sayHello = function () {
console.log('hello');
}
}
ClassName.prototype.sayHello = function () {
console.log('hello');
}
var className = new ClassName();
className.sayHello();
es6类的定义
class ClassName {
x = 1;
y = 2;
constructor () {}
sayHello () {
console.log('hello');
}
}
es5对象:
定义在实例对象上的:
this.x
this.y
this.sayHello
定义在类的原型上的:
ClassName.prototype.sayHello
es6对象:
定义在实例对象上的:
x = 1;
y = 2;
定义在原型上的:
sayHello方法(非静态方法)
另外,es6对象上的静态方法(前缀是static),不在原型上, 不可被实例化对象调用,且不能被子类的实例化对象调用,但是可以被子类继承,通过子类名调用.
2. 当继承发生的时候,过程是怎么样的
es5的继承
function Parent () {
this.x = 1;
this.y = 2;
}
function Child () {
this.z = 3;
}
Child.prototype = new Parent();
var parent = new Parent();
var child = new Child();
es6的继承
class Parent {
height = 20;
static width = 30;
constructor(name) {
this.name = name;
}
static sayHello() {
console.log('hello');
}
sayName() {
console.log('my name is ' + this.name);
return this.name;
}
}
class Child extends Parent {
constructor(name, age) {
super(name);
this.age = age;
}
sayAge() {
console.log('my age is ' + this.age);
return this.age;
}
}
let parent = new Parent('Parent');
let child = new Child('Child', 18);
下面将探索继承发生了什么
es5的继承中,只存在单个原型链;
es6的继承中,同时存在两条原型链;
es5的继承如下:
在构造函数这条原型链上是不存在的;
在实例上的原型链是存在的,
function Parent () {
this.x = 1;
this.y = 2;
}
function Child () {
this.z = 3;
}
Child.prototype = new Parent();
var parent = new Parent();
var child = new Child();
// 在构造函数这条原型链上是不存在的
console.log('Child.__proto__ === Parent', Child.__proto__ === Parent);
/**
在实例上的原型链存在
*/
// 子类实例继承自子类原型
console.log('Child.__proto__ === Child.prototype', child.__proto__ === Child.prototype);
// 子类原型继承自父类原型
console.log('Child.prototype.__proto__ === parent.prototype', Child.prototype.__proto__ === Parent.prototype);
// 父类实例继承自父类原型
console.log('parent.__proto__ === Parent.prototype', parent.__proto__ === Parent.prototype);
// 子类实例继承自父类实例(Child.prototype = new Parent();)
console.log('Child.prototype.__proto__ === parent.__proto__', Child.prototype.__proto__ === parent.__proto__);
es6的继承,存在2条原型链
class Parent {
height = 20;
static width = 30;
constructor(name) {
this.name = name;
}
static sayHello() {
console.log('hello');
}
sayName() {
console.log('my name is ' + this.name);
return this.name;
}
}
class Child extends Parent {
constructor(name, age) {
super(name);
this.age = age;
}
sayAge() {
console.log('my age is ' + this.age);
return this.age;
}
}
let parent = new Parent('Parent');
let child = new Child('Child', 18);
// 构造函数原型链
console.log('Child.__proto__ === Parent', Child.__proto__ === Parent);
console.log('Parent.__proto__ === Function.prototype', Parent.__proto__ === Function.prototype);
console.log('Function.prototype.__proto__ === Object.prototype', Function.prototype.__proto__ === Object.prototype);
console.log('Parent.__proto__ === Function.prototype', Object.prototype.__proto__ === null);
// 实例原型链
console.log('child.__proto__ === Child.prototype', child.__proto__ === Child.prototype);
console.log('Array.prototype.__proto__ === Object.prototype', Child.prototype.__proto__ === Parent.prototype);
console.log('Array.prototype.__proto__ === Object.prototype', Parent.prototype.__proto__ === Object.prototype);
console.log('Array.prototype.__proto__ === Object.prototype', Object.prototype.__proto__ === null);
最后附上一张图: