fe ? not exsit ?

走进基础:class了解一下

Still so, 记录一下小心情,小悸动而不失平静。简单记录一下对主题的理解。

应该会用它咯

class 声明 + constructor 构造 + 类成员

1
2
3
4
5
6
7
8
class Animal {
constructor () {
this.name = 'wangwangwang';
}
hello () {
console.log('hello', this.name);
}
}

真的是类似其他强类型语言的继承吗?走入它把。。

可惜不是呀,只是为了接近像java类仍使用prototype的语法糖而已。先大致浏览一下在线babel transform后的代码。

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
40
41
42
43
"use strict";

var _createClass = (function() {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function(Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
})();

function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}

var Animal = (function() {
function Animal() {
_classCallCheck(this, Animal);

this.name = "wangwangwang";
}

_createClass(Animal, [
{
key: "hello",
value: function hello() {
console.log("hello", this.name);
}
}
]);

return Animal;
})();

wow,先get几个知识点

  1. class 虽然是类,本质就是函数
1
2
3
4
//本质函数得以验证。
var Animal = (function() {
return Animal;
})();
  1. contructor 不能形似函数直接调用
1
2
3
4
5
6
7
8
9
10
11
12
13

function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function Animal() {

//调用_classCallCheck, 检测prototype不一致,即抛出类型错误
_classCallCheck(this, Animal);

this.name = "wangwangwang";
}
  1. Animal的成员方法hello === Animal.protoype.hello
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var _createClass = (function() {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
//通过参数区分静态和类成员函数,利用Object.defineProperty把成员属性和静态属性分别定义到类的prototype和类的本身属性上。
return function(Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
})();

额外的小tips

  1. 静态属性、私有属性暂不支持。

    类似这种Animal.name不太认可

  2. new.target

    new是从构造函数生成实例对象的命令。ES6 为new命令引入了一个new.target属性,该属性一般用在构造函数中,返回new命令作用于的那个构造函数。可用来限制调用的模式。

1
2
3
4
5
6
7
8
9
10
11
class Animal {
constructor() {
if(new.target === undefined ) {
console.log('必须使用 new 命令生成实例');
} else if (new.target === Animal) {
console.log('必须使用即成来调用');
}
}
}

var Ani1 = new Animal(); //必须使用继承来调用

综上,明显得,class是prototype的语法糖而已,写法优雅。