您的位置:首页 > Web前端 > JavaScript

需要掌握的es6特性(一)

2016-07-21 11:22 405 查看
目前es6越来越火,很多公司都开始使用起了es6。因为掌握es6的一些常用特性是非常必要的。

let和const

原来定义变量时,都会使用var来定义。第一次使用的时候就觉得var的定义特别随性特别自由。但是由于太过自由总是容易犯一些很难找到的错。

首先var的作用域现在一般是全局作用域和局部作用域(一般为函数作用域),很容易造成作用域的混淆。

其次声明提前在一方面来说比较自由,因此比较方便。但是一旦有错误很难定位。

现在出现的let和const都属于块级作用域。所以用let来定义for循环特别好,再也不会在循环之后还出现诡异的Bug了(var 定义的对象在循环结束后会影响输出内容)。

比如下面的:

var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10


但如果是使用let的话就不一样了:

var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6


然后const是定义一个只读的常量的,也是块级作用域下的。 const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。

另外由于不能变量提升,因此存在以下几个问题:

暂时性死区

只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

var tmp = 123;

if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}


不允许重复声明

// 报错
function () {
let a = 10;
var a = 1;
}

// 报错
function () {
let a = 10;
let a = 1;
}


function func(arg) {
let arg; // 报错
}

function func(arg) {
{
let arg; // 不报错
}
}


未声明的全局变量,自动成为全局对象window的属性,这被认为是JavaScript语言最大的设计败笔之一。这样的设计带来了两个很大的问题,首先是没法在编译时就报出变量未声明的错误,只有运行时才能知道,其次程序员很容易不知不觉地就创建了全局变量(比如打字出错)。另一方面,从语义上讲,语言的顶层对象是一个有实体含义的对象,也是不合适的。

ES6为了改变这一点,一方面规定,为了保持兼容性,var命令和function命令声明的全局变量,依旧是全局对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于全局对象的属性。也就是说,从ES6开始,全局变量将逐步与全局对象的属性脱钩。

var a = 1;
// 如果在Node的REPL环境,可以写成global.a
// 或者采用通用方法,写成this.a
window.a // 1

let b = 1;
window.b // undefined


变量的解构赋值

ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

以前,为变量赋值,只能直接指定值。

var a = 1;
var b = 2;
var c = 3;


现在:

var [a, b, c] = [1, 2, 3];


let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3

let [ , , third] = ["foo", "bar", "baz"];
third // "baz"

let [x, , y] = [1, 2, 3];
x // 1
y // 3

let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []


如果解构不成功,变量的值就等于undefined。

默认值

解构赋值允许指定默认值。

var [x = 1] = [undefined];
x // 1

var [x = 1] = [null
4000
];
x // null


对象的解构赋值

var { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"


var { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

var { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined


字符串的解构赋值

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"


let {length : len} = 'hello';
len // 5


数值和布尔值的解构赋值

let {toString: s} = 123;
s === Number.prototype.toString // true

let {toString: s} = true;
s === Boolean.prototype.toString // true


函数参数的解构赋值

function add([x, y]){
return x + y;
}

add([1, 2]); // 3


字符串的扩展

字符串的遍历器接口

ES6为字符串添加了遍历器接口,使得字符串可以被for…of循环遍历。

for (let codePoint of 'foo') {
console.log(codePoint)
}
// "f"
// "o"
// "o"


includes(), startsWith(), endsWith()

传统上,JavaScript只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6又提供了三种新方法。

includes():返回布尔值,表示是否找到了参数字符串。

startsWith():返回布尔值,表示参数字符串是否在源字符串的头部。

endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部。

var s = 'Hello world!';

s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true


这三个方法都支持第二个参数,表示开始搜索的位置。

repeat()

repeat方法返回一个新字符串,表示将原字符串重复n次。

'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""


参数如果是小数,会被取整,是负数或者Infinity,会报错。参数NaN等同于0。

padStart(),padEnd()

ES7推出了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart用于头部补全,padEnd用于尾部补全。

'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'

'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'


上面代码中,padStart和padEnd一共接受两个参数,第一个参数用来指定字符串的最小长度,第二个参数是用来补全的字符串。

如果原字符串的长度,等于或大于指定的最小长度,则返回原字符串。

如果用来补全的字符串与原字符串,两者的长度之和超过了指定的最小长度,则会截去超出位数的补全字符串。

'abc'.padStart(10, '0123456789')
// '0123456abc'


如果省略第二个参数,则会用空格补全长度。

模板字符串

$('#result').append(`
There are <b>${basket.count}</b> items
in your basket, <em>${basket.onSale}</em>
are on sale!
`);


数值的扩展

Math的扩展

Math.trunc方法用于去除一个数的小数部分,返回整数部分。

Math.trunc(4.1) // 4
Math.trunc(4.9) // 4
Math.trunc(-4.1) // -4
Math.trunc(-4.9) // -4
Math.trunc(-0.1234) // -0


Math.sign方法用来判断一个数到底是正数、负数、还是零。

它会返回五种值。

参数为正数,返回+1;

参数为负数,返回-1;

参数为0,返回0;

参数为-0,返回-0;

其他值,返回NaN。

Math.sign(-5) // -1
Math.sign(5) // +1
Math.sign(0) // +0
Math.sign(-0) // -0
Math.sign(NaN) // NaN
Math.sign('foo'); // NaN
Math.sign();      // NaN


Math.hypot方法返回所有参数的平方和的平方根。

Math.hypot(3, 4);        // 5
Math.hypot(3, 4, 5);     // 7.0710678118654755
Math.hypot();            // 0
Math.hypot(NaN);         // NaN
Math.hypot(3, 4, 'foo'); // NaN
Math.hypot(3, 4, '5');   // 7.0710678118654755
Math.hypot(-3);          // 3


ES6新增了6个三角函数方法。

Math.sinh(x) 返回x的双曲正弦(hyperbolic sine)

Math.cosh(x) 返回x的双曲余弦(hyperbolic cosine)

Math.tanh(x) 返回x的双曲正切(hyperbolic tangent)

Math.asinh(x) 返回x的反双曲正弦(inverse hyperbolic sine)

Math.acosh(x) 返回x的反双曲余弦(inverse hyperbolic cosine)

Math.atanh(x) 返回x的反双曲正切(inverse hyperbolic tangent)

指数运算符

ES7新增了一个指数运算符(**)。

2 ** 2 // 4
2 ** 3 // 8


指数运算符可以与等号结合,形成一个新的赋值运算符(**=)。

let a = 2;
a **= 2;
// 等同于 a = a * a;

let b = 3;
b **= 3;
// 等同于 b = b * b * b;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  es6 新特性 javascript