ES6的Class语法和箭头函数

1、原型链继承

众所周知,JavaScript不是一种传统的面向对象的语言,因为他跟传统的面向对象语言不同,它没有类于php或者java等传统编程语言的类。那么,它是如何实现面向对象的功能的呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14

function Cat(name,age){
this.name = name;
this.age = age;
}

Cat.prototype.type = '猫科动物';
Cat.prototype.eat = function(){alert('吃');}

// 然后生成实例

var cat1 = new Cat("大毛","23");
alert(cat1.type); //猫科动物

上面的这种,我们叫他原型链继承。JavaScript规定,所有的构造函数,都有Prototype属性,指向另一个对象,这个对象所有的属性和方法,都会被另一个实例对象继承。

2、类语法实现继承

原型链的语法,在于理解起来困难,不如Java等的面向对象理解起来直观。因此,ES6标准推出了一个class的语法糖,让我们也可以像其他面向对象语言一样,实现简单的类继承。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

class Bar {
default(x,y) {
console.log(x,y);
}
default2(i,u) {
console.log(i,u);
}
}

//调用

var b = new Bar();

b.default(5,6);
b.default2(7,8);

因为ES6的class语法实质上,只是一种语法糖,所以尽管写法上有区别,但实现上,还是原型链继承。

1
2
3
4
5
6
7
8
9
10
11
class default {
default(x,y) {
console.log(x,y)
}
}

//等同于

default.prototype = {
default(x,y){}
}

再来看一个例子,这里,我们要做一件事。

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
const ClassMe = class me {
getClassName(){
return Me.name;
}
}

// 上面使用表达式定义了一个类,这个类的名字仍然是me,而不是ClassMe。

//实例化这个类

let Me = new ClassMe();

inst.getClassMe(); //Me

//如果不需要用到类名,那么也可以写成

const ClassMe = class {}

//Class立即执行

let person = new class {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name)
}
},('吴万海');

person.sayName();

不存在的变量提升

我们在编写JavaScript函数中,肯定有写法利用到JavaScript的变量提升。比如把大串的函数封装放到函数执行的最下面。但是在class中是不允许这样做的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

add();

function add() {
console.log('123');
}

//但在class中,这样执行是不行的。

new Foo(); //ReferenceError
class Foo {};

// 因为,在class中不存在变量提升,Foo类使用在前,定义在后,于是就出现了报错。必须保证子类在父类之后。

{
let Foo = class {};
class Bar expends Foo {
}
}

// 上面这样则不会报错,因为Bar继承Foo的时候,Foo已经有定义了。

class的静态方法

类相当于实例的原型,所有在类中定义的方法,都会在实例中继承。如果在一个方法前,假如static关键字,就表示这个方法不会被继承,而是直接通过类来调用这就是静态方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

class Foo {
static classMethod() {
return 'hello'
}
Foo.classMethod(); //hello
}

//这里我们没有通过new关键字的构造方法,来继承这个类的实例,而是使用了**static**的关键字,表示这个类不会被继承,而是直接通过类调用。

var foo = new Foo();
foo.classMethod;

//TypeError foo not is a function

上面的程序报了一个错,表示不存在这个函数方法。因为我们这里使用了static关键字,可以直接在类上调用,而不是在实例上。

待续….

JavaScript的类语法,让我们编写面向对象的程序更简单。因此,条件支持,应该更多的使用新语法。

3、箭头函数

箭头函数,本质上是匿名函数。只是在形式上做了简化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

//比如我们旧时候写一个函数

function add(x,y) {
console.log(x,y);
}

add(4,5);

//ES6改进版

var add = (x,y)=>x*y

等同于

function(x,y) {
return x*y
}

这种因为结构简单,所以,我们省略了,大括号和renturn关键字,但是,如果更复杂一点的,就不行了。

1
2
3
4
5
6
7
8
(x,y) => {
if (x > 0) {
return x*x
}
else {
return x*y
}
}