需要掌握的es6特性(一)
2016-07-21 11:22
405 查看
目前es6越来越火,很多公司都开始使用起了es6。因为掌握es6的一些常用特性是非常必要的。
首先var的作用域现在一般是全局作用域和局部作用域(一般为函数作用域),很容易造成作用域的混淆。
其次声明提前在一方面来说比较自由,因此比较方便。但是一旦有错误很难定位。
现在出现的let和const都属于块级作用域。所以用let来定义for循环特别好,再也不会在循环之后还出现诡异的Bug了(var 定义的对象在循环结束后会影响输出内容)。
比如下面的:
但如果是使用let的话就不一样了:
然后const是定义一个只读的常量的,也是块级作用域下的。 const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。
另外由于不能变量提升,因此存在以下几个问题:
未声明的全局变量,自动成为全局对象window的属性,这被认为是JavaScript语言最大的设计败笔之一。这样的设计带来了两个很大的问题,首先是没法在编译时就报出变量未声明的错误,只有运行时才能知道,其次程序员很容易不知不觉地就创建了全局变量(比如打字出错)。另一方面,从语义上讲,语言的顶层对象是一个有实体含义的对象,也是不合适的。
ES6为了改变这一点,一方面规定,为了保持兼容性,var命令和function命令声明的全局变量,依旧是全局对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于全局对象的属性。也就是说,从ES6开始,全局变量将逐步与全局对象的属性脱钩。
以前,为变量赋值,只能直接指定值。
现在:
如果解构不成功,变量的值就等于undefined。
ES6为字符串添加了遍历器接口,使得字符串可以被for…of循环遍历。
includes():返回布尔值,表示是否找到了参数字符串。
startsWith():返回布尔值,表示参数字符串是否在源字符串的头部。
endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部。
这三个方法都支持第二个参数,表示开始搜索的位置。
参数如果是小数,会被取整,是负数或者Infinity,会报错。参数NaN等同于0。
上面代码中,padStart和padEnd一共接受两个参数,第一个参数用来指定字符串的最小长度,第二个参数是用来补全的字符串。
如果原字符串的长度,等于或大于指定的最小长度,则返回原字符串。
如果用来补全的字符串与原字符串,两者的长度之和超过了指定的最小长度,则会截去超出位数的补全字符串。
如果省略第二个参数,则会用空格补全长度。
Math.sign方法用来判断一个数到底是正数、负数、还是零。
它会返回五种值。
参数为正数,返回+1;
参数为负数,返回-1;
参数为0,返回0;
参数为-0,返回-0;
其他值,返回NaN。
Math.hypot方法返回所有参数的平方和的平方根。
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)
指数运算符可以与等号结合,形成一个新的赋值运算符(**=)。
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;
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- OpenERP v6.1新特性解读 (一)整体易用性、界面、移动性
- OpenERP v6.1新特性解读 (三) 技术
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- 最后一次说说闭包
- Ajax
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)
- JavaScript拆分字符串时产生空字符的原因