Class in JavaScript

类的本质

类的本质是函数

1
2
3
class User {
};
console.log(typeof User); //function

在类中添加原型方法

1
2
3
4
5
6
7
8
class User {
constructor(name){
this.name = name;
};
getName(){
console.log(this.name);
};
};

相当于:

1
2
3
4
5
6
function User(name){
this.name = name;
};
User.prototype.getName = function(){
console.log(this.name);
}

类与构造函数差异

  • 类定义的方法不能遍历

静态属性和方法只能通过类原型来调用

使用静态方法批量生产对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var data = [{
"1990": 794362.7682,
"code": "GB",
"name": "United Kingdom",
"change": -10,
"region": "EU",
},
{
"1990": 71303.67987,
"code": "SE",
"name": "Sweden",
"change": -20,
"region": "EU",
},
];

class EU {
constructor(data) {
this.model = data;
}
get change() {
return this.model.change;
}
static create(data) {
// data = JSON.parse(JSON.stringify(data));
return data.map(item => new EU(item));
}
static maxChange(data) {
return data.sort((a, b) => {
return Math.abs(b.change) - Math.abs(a.change)
})[0];
}
static totalEmission(data) {
return data.reduce((acc, cur) => {
return acc['1990'] + cur['1990']
})
}
}
var EUs = EU.create(data);

静态属性和方法也是可以被继承的。

访问器

gettersetter 可以用来管理属性,防止属性被随意修改

声明方法:方法前加get or set

1
2
3
4
5
6
7
8
9
10
11
class User {
constructor(){
this.name = name;
};
get name(){
return this.name
};
};
let user1 = new User('ruoyu');
//使用访问器时不需要加括号
console.log(user1.name); // 'ruoyu'

属性保护

  1. 可以通过_<name> 命名方式来告知此属性是私有属性,但此方式只是一种公认的提示,本身并不能防止属性的修改。

  2. 通过symbol来保护属性,比如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    const AGE = Symbol("age")
    class User {
    _name = 'ruoyu';
    constructor(age) {
    this[AGE] = age;
    };
    }
    let user1 = new User(19);
    console.log(user1) // {_name: "ruoyu", Symbol(age): 19}
  3. 通过WeakMap()键值对集

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const _age = new WeakMap();
    class User {
    constructor(name) {
    this.name = name;
    _age.set(this, {age:18,password:123});
    }
    };
    let user1 = new User('ruoyu');
    //属性并不会暴露在外部,除非使用get访问器
    console.log(md) // {name:'ruoyu'}
    console.log(_age) //WeakMap {User => {age:18,pasword:123}}

Super

super 一直指向当前对象, 在继承关系中,如果想要使用父类中的属性方法,可以使用super关键字来指向当前对象。

下面通过普通方法来模拟super

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let user = {
name: "user",
show() {
return this.name;
}
};
let spawn = {
__proto__: user,
name: "spawn",
show() {
return this.__proto__.show.call(this);
}
};
console.log(spwan.show()); // 'spawn'

super关键词相当于一颗语法糖

1
2
3
4
//上述代码中spwan中的show方法可以简写成:
show(){
return super.show();
}

Note: super关键词只能在类或对象的方法中使用

在继承父类构造者中,可以使用super()方法来调用父类中的构造函数.

1
2
3
4
5
6
7
8
9
10
class Parent {
constructor(name) {
this.name = name;
}
};
class Son extends Parent{
constructor(name){
super(name);
}
}

原理剖析:

1
2
3
4
5
6
7
8
function Parent(name) {
this.name = name;
}
function Son(...args) {
Parent.apply(this, args);
}
Son.prototype = Object.create(Parent.prototype);
Son.prototype.constructor = Son;
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2020 Ruoyu Wang
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信