Js语言的传统方法是通过构造函数,定义并生成新对象,prototype 属性使您有能力向对象添加属性和方法,是一种基于原型的面向对象系统。
//Person.js
function Person(x,y){
this.x = x;
this.y = y;
this.say=function(){return y}
}
Person.prototype.toString = function (){
return (this.x + "的年龄是" +this.y+"岁");
}
let person = new Person('张三',12);
console.log(person.toString());//张三的年龄是12岁
ES6引入了Class(类)这个概念,作为对象的模板,通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
//Person.js
class Person{
// 构造
constructor(x,y){
this.x = x;
this.y = y;
this.z=1;
}
p(){
return 2;
}
toString(){
return (this.x + "的年龄是" +this.y+"岁");
}
}
export {Person};
//index.js
import {Person} from './Person';
let person = new Person('张三',12);
console.log(person.toString());//张三的年龄是12岁
// 类上面的方法等同于
Person.prototype = {
toString(){ return (this.x + “的年龄是” +this.y+“岁”);},
};
constructor方法,这就是构造方法,this关键字则代表实例对象。
constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。
定义“类”的方法的时候,前面不需要加上function这个关键字,方法之间不需要逗号分隔
类的所有方法都定义在类的prototype属性上面。
类的构造方法必须使用new关键字
Object.assign方法可以给对象Person动态的增加方法,
Object.assign(Person.prototype, {
getage(){},
toValue(){}
});
extends
Class之间可以通过extends
关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多。
//student类通过extends关键字,继承了Person类的所有属性和方法。
class Student extends Person {
constructor(x, y, color) {
super(x, y); // 调用父类的constructor(x, y)
this.z=3;
console.log(super.p());//2将super当作一个对象使用
this.age = 10;
}
}
super
super
表示父类构造函数,用来新建父类的this对象。
子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。
super作为对象时,指向父类的原型对象。super指向父类Person.prototype,所以super.p()就相当于Person.prototype.p()
ES5与ES6构造函数的区别
class A {
constructor() {
this.p = 2;
}
}
class B extends A {
get m() {
return super.p;
}
}
let b = new B();
b.m // undefined
class A {
constructor() {
this.x = 1;
}
print() {
console.log(this.x);
}
}
class B extends A {
constructor() {
super();
this.x = 2;
}
m() {
super.print();
}
}
let b = new B();
b.m() // 2