es6常用特性

默认参数

1
2
3
4
var fn = function (width, height) {
var width = width || 50;
var height = height || 100;
};

没有默认参数之前,一切没有问题,知道遇到参数 0 时,就有问题了。0 为假值,就无法变为参数本身的值。在 es6 中,修复了这一缺陷。

1
2
3
var fn = function (width = 50, height = 100) {
...
}

模板字符串

模板字符串是增强版的字符串,用反引号````标识。
如果要在模板字符串中嵌入变量,将变量名写在${}中。
模板字符串会保留所有的空格和换行。

解构赋值

es5 写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 对象
var obj = {
age: 18,
name: 'yy',
};

var age = obj.age;
var name = obj.name;

// 数组
var arr = [1, 2];
var item1 = arr[0];
var item2 = arr[1];

解构赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 对象
var obj = {
age: 18,
name: 'yy',
};

var { age, name } = obj;

// 如果你想自定义变量名,可用冒号重命名,如myage
var { age: myage, name } = obj;

// 数组
var arr = [1, 2];
var [item1, item2] = arr;

箭头函数

箭头函数内部的 this 是词法作用域,由上下文确定

1
2
3
4
var _this = this;
$('.btn').click(function (event) {
_this.sendData();
});

有了箭头函数,就不必使用 that=this、_this=this、.bind(this)…,它总是可以按我们预期使用。

1
2
3
$('.btn').click((event) => {
this.sendData();
});

更简洁的语法:

1
2
3
4
5
const fn = () => {
dosomething;

return true;
};

如果返回结果是单个语句,可以省了{}return

1
2
3
4
const fn = () => true;

// 如果返回的是对象,需要用()包裹
const fn = () => ({ a: 1 });

let 和 const

使用 letconst 生命的变量,只在代码块里有效。代码块可以理解为大括号{}

如果你在 if,for 里面使用 letconst,那么只能再块里使用,在外部访问会报错。

1
2
3
4
5
if (true) {
const a = 1;
}

console.log(a); // Uncaught ReferenceError: a is not defined

暂时性死区

在使用let声明变量之前,对变量进行访问会报错

1
2
3
4
5
6
if (true) {
tmp = 'abc'
console.log(tem) Uncaught ReferenceError: Cannot access 'tmp' before initialization

let tmp
}

不存在变量提升

1
2
3
4
5
console.log(foo); // undefined
var foo = 2;

console.log(bar); // ReferenceError: bar is net defined
let bar = 2;

不能重复声明

不能在布局相同作用域重复声明

1
2
3
4
5
6
7
8
9
10
11
12
13
function fn() {
let x = 1;
let x = 2; // SyntaxError: Identifier 'x' has already been declared
}

if (true) {
let x = 1;
let x = 2; // SyntaxError: Identifier 'x' has already been declared
}

//全局作用域可以,后者覆盖前者
let x = 1;
let x = 2;

const声明一个只读的常量,一旦声明,常量的值就不能改变。

1
2
3
const x = 1;

x = 2; // TypeError: Assignment to constant variable.

如果const声明的是一个对象,可对这个对象下的属性进行增删改操作

1
2
3
4
5
6
7
8
9
10
11
12
13
const o = {
x: 1,
y: 2,
};

// 添加
o.z = 3;

// 删除
delete o['z'];

// 修改
o.x = 11; // o = { x: 11, y: 1 }

如果不希望 const 生命的对象被修改,可用 defineProperty定义属性的权限。

1
2
3
4
5
6
7
8
9
const o = { x: 1 };

Object.defineProperty(o, 'x', {
writable: false,
});

o.x = 2;

console.log(o); // { x: 1 }

Class 类

为了语法更接近传统的面向对象语言(java 和 c++),引入了 Class 类的概念,作为对象的模板。

通过 class 关键字定义类:

1
2
3
4
5
6
7
8
9
10
11
12
class Student {
// 构造函数
constructor(name, age) {
this.name = age; // this指向实例对象
this.age = age;
}

// 定义方法,方法名前面不需要function,挂载在原型上
printName() {
return this.name;
}
}

extends

extends 关键字用于继承父类

super

super 可当做函数使用,也可当做对象使用。

作为函数时,只能在子类构造函数里调用。

1
2
3
4
5
class B extends A {
constructor() {
super();
}
}

super代表的是父类的构造函数,但是返回的是子类的实例。 相当于 A.prototype.construcor.call(this)。也就是说,super()内部的 this 指向的是子类 B。

作为对象时,在普通方法中,指向的是父类的原型对象;在静态方法中,指向父类。

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
class Parent {
static myMethod(msg) {
console.log('static', msg);
}

myMethod(msg) {
console.log('instance', msg);
}
}

class Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);
}

myMethod(msg) {
super.myMethod(msg);
}
}

// super在静态方法中,指向父类
Child.myMethod(1); // static 1

// super在普通方法中,指向父类的原型
var child = new Child();
child.myMethod(2); // instance 2

链判断运算符 ?.

如果一个对象为undefinednull,我们试着去访问该对象下的属性时就会抛出异常

1
2
const obj = undefined;
console.log(obj.name); // Uncaught TypeError: Cannot read properties of undefined (reading 'name')

使用链判断运算符,就不会抛出异常

1
2
3
console.log(obj?.name); // undefined
等价于;
console.log(obj == undefined ? undefined : obj.name);

还有一个常用的错误使用,链运算不能应用于赋值运算符左侧

1
obj?.name = 'tom'; // The left-hand side of an assignment expression may not be an optional property access.ts(2779

ts 非空断言
在有些情况下,你如果明确 obj 对象不为nullundefined,你可以使用非空断言符

1
obj!.name = 'tom';

这是 TypeScript 中的非空断言操作符,用来告诉编译器您已经检查过属性是否为非空,并且可以放心地访问它。

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×