advantage
ES6 class provides several significant benefits:
Compatible with the current lot of code.
Relative to the constructor and constructor inheritance, class make it easier for beginners to get started.
Subclass support at the language level.
Subclassable built constructor.
No longer need to inherit the library; the code between the frame becomes more portable.
To lay the foundation for future advanced features: traits (or mixins), immutable instance, and so on.
The tool can be a static analysis of the code (the IDE, type detector, the detector code style, etc.).
Shortcoming
ES6 cover up the JavaScript class inherits the essence;
class will imprison you, because the mandatory new.
Traditional Class
function Point(x, y){
this.x = x;
this.y = y;
}
Point.prototype.toString = function(){
return "(" + this.x + "," + this.y + ")";
}
const p = new Point(1,2);
console.log(p);//Point {x: 1, y: 2}
console.log(p.toString());//(1,2)
ES6 the class written equivalent syntactic sugar
Use class to write the above code
class Points {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString(){
return '(' + this.x + ',' + this.y + ')'; }
}
const ps = new Points(1, 2);
console.log(ps);//Points {x: 1, y: 2}
console.log(ps.toString());//(1,2)
ES6 class can be seen as a further writing constructor
class Cty{
//....
}
console.log(typeof Cty);//function
console.log(Cty === Cty.prototype.constructor);//true
//类的数据类型是函数,类本身就指向构造函数
When in use, but also the use of new commands directly to the class, use the constructor with exactly the same
class Bar {
doStuff(){
console.log('stuff');
}
}
const b =new Bar();
b.doStuff();//stuff
Instance of the class above method, in fact, invoke methods on the prototype
class B {};
const BS = new B();
console.log(BS.constructor === B.prototype.constructor);//true
Classes and subclasses
class Poin{
constructor(x,y){
this.x = x;
this.y = y;
}
toString(){
return `(${this.x},${this.y})`;
}
}
class ColorPoin extends Poin{
constructor(x,y,color){
super(x,y);
this.color = color;
}
toString(){
return super.toString() + " in " + this. color;
}
}
// 类型
console.log(typeof Poin);//function
//news实例
const cp = new ColorPoin(25,8,'green');
console.log(cp.toString());//(25,8) in green
console.log(cp instanceof ColorPoin);//true
console.log(cp instanceof Poin);//true
// instanceof测试构造函数的prototype属性是否出现在对象的原型链中的任何位置
Here are some ways:
Object.assign method can easily add more than one image class method
class ObjAssign {
constructor(name, age){
this.name = name;
this.age = age;
}
}
Object.assign(ObjAssign.prototype,{
toString(){
console.log("string");
},
toValue(){
console.log("value")
}
})
const Obj = new ObjAssign('Bob',24);
console.log(Obj);
Obj.toString();//string
Obj.toValue();//value
console.log(Object.keys(ObjAssign.prototype));//["toString", "toValue"]
console.log(Object.getOwnPropertyNames(ObjAssign.prototype));// ["constructor", "toString", "toValue"]
Instance of the class
class Pott {
constructor(x,y){
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ',' + this.y + ')';
}
}
const pott = new Pott(2,3);
pott.toString();
console.log(pott.hasOwnProperty("x"));//true
console.log(pott.hasOwnProperty("y"));//true
console.log(pott.hasOwnProperty("toString"));//false
console.log(pott);
console.log(pott.__proto__);
console.log(pott.__proto__.hasOwnProperty("toString"));//true
const p1 = new Pott(2,3);
const p2 = new Pott(3,3);
console.log(p1.__proto__ === p2.__proto__);//true
p1.__proto__.printName = function(){
return "Oops";
}
console.log(p1.printName());//Oops
console.log(p2.printName());//Oops
const p3 = new Pott(4,2);
console.log(p3.printName());//Oops
The value function (getter) and stored-value function (setter)
prop attribute has a corresponding function values stored-value functions, and
class MyClass {
constructor(){
//...
}
get prop(){
return 'getter';
}
set prop(value){
console.log("setter:" + value);
}
}
const inst = new MyClass();
inst.prop = 123;//setter: 123
console.log(inst.prop)//getter
And stored-value functions are value functions provided on the Descriptor object properties
class CustomHTMLElement {
constructor(element) {
this.element = element;
}
get html() {
return this.element.innerHTML;
}
set html(value) {
this.element.innerHTML = value;
}
}
const descriptor = Object.getOwnPropertyDescriptor(
CustomHTMLElement.prototype, "html"
);
console.log("get" in descriptor) // true
console.log("set" in descriptor) // true
calss expression
const MyCl = class Me {
getClassName() {
return Me.name;
}
}
const inMe = new MyCl();
console.log(inMe.getClassName());//Me 只在class内部有定义
person executing instance immediately
const person = new class{
constructor(name){
this.name = name;
}
sayName(){
console.log(this.name);
}
}('张三');
person.sayName();//张三
class name property
class Mine {
//...
}
console.log(Mine.name);//Mine
class this point to problems
this.printName = this.printName.bind (this) binding to solve
class Logger{
constructor(){
this.printName = this.printName.bind(this);
}
printName(name = 'there'){
this.print(`Hello ${name}`);
}
print(text){
console.log(text);
}
}
const logger = new Logger();
const {printName} = logger;
printName();//Hello there
Static method static
If the previous method, coupled with the static keyword, it means that the method will not be inherited instances, but invoked by category
class Foo{
static classMethod() {
return 'hello';
}
}
console.log(Foo.classMethod());//Hello
const foo = new Foo();
// console.log(foo.classMethod())//foo.classMethod is not a function
class Fun {
static bar(){
this.baz();
}
static baz(){
console.log('hello');
}
baz(){
console.log('world');
}
}
Fun.bar();//hello
Parent class static methods can be called by subclasses
class Func{
static classMethod() {
return 'hello';
}
}
class Baa extends Func{
static classMethod(){
console.log(super.classMethod + ",too") ;
}
}
Baa.classMethod();//hello,too
The new wording instance attributes
class IncreasingCounter{
// constructor(){
// this._count = 0;
// }
_count = 0;
get value(){
console.log('getting the current value');
return this._count;
}
increment(){
this._count++;
}
}
new.target property
Ensure that the function can only be called by the new command
function PersonMan(name){
if(new.target !== undefined){
this.name = name;
}else{
throw new Error('必须使用new命令生成实例')
}
}
function PersonWoman(name){
if(new.target === PersonWoman){
this.name = name;
}else{
throw new Error('必须使用new命令生成实例')
}
}
const personman = new PersonMan('张三');
const personwoman = new PersonWoman('张三');
// const personwoman2 = PersonWoman.call(PersonWoman,'张三');//报错
Internal call new.target returns the current class
class Rectangle{
constructor(length,width){
console.log(new.target);
console.log(new.target===Rectangle);
this.length = length;
this.width = width;
}
}
const rectangle = new Rectangle(3,4);
When the subclass inherits the parent class, new.target will return a subclass
class Rec{
constructor(length,width){
console.log(new.target);
console.log(new.target===Rectangle);
console.log(new.target===Square);
this.length = length;
this.width = width;
//...
}
}
class Square extends Rec{
constructor(length,width){
super(length,width);
}
}
const squareA = new Square(3,6);//false/true
Reference article
exploring ES6
ES6 Ruan Yifeng