目的
当然是系统学习es6啦。。。并快速了解es6的新特性,并未过多深入。想通过二八定律先全面了解ES6的新特性。
es6简介
简单总结下相关知识点。
es6是什么?
ES6 既是一个历史名词,也是一个泛指,含义是 5.1 版以后的 JavaScript 的下一代标准,涵盖了 ES2015、ES2016、ES2017 等等,而 ES2015 则是正式名称,特指该年发布的正式版本的语言标准。本书中提到 ES6 的地方,一般是指 ES2015 标准,但有时也是泛指“下一代 JavaScript 语言”。
如何查看浏览器兼容性?
各大浏览器的最新版本,对 ES6 的支持可以查看。随着时间的推移,支持度已经越来越高了,超过 90%的 ES6 语法特性都实现了。
nodejs如何查看
Node 是 JavaScript 的服务器运行环境(runtime)。它对 ES6 的支持度更高。除了那些默认打开的功能,还有一些语法功能已经实现了,但是默认没有打开。使用下面的命令,可以查看 Node 已经实现的 ES6 特性。
$ node --v8-options | grep harmony
上面命令的输出结果,会因为版本的不同而有所不同。
转码器
考虑到有可能部分浏览器对es6兼容性可能存在问题,所以有时候需要将es6转成es5,去解决兼容性问题。
Babel 转码器
Babel 是一个广泛使用的 ES6 转码器,可以将 ES6 代码转为 ES5 代码,从而在现有环境执行。这意味着,你可以用 ES6 的方式编写程序,又不用担心现有环境是否支持。下面是一个例子。
// 转码前
input.map(item => item + 1);
// 转码后
input.map(function (item) {
return item + 1;
});
上面的原始代码用了箭头函数,Babel 将其转为普通函数,就能在不支持箭头函数的 JavaScript 环境执行了。
Babel 默认只转换新的 JavaScript 句法(syntax),而不转换新的 API,比如Iterator
、Generator
、Set
、Maps
、Proxy
、Reflect
、Symbol
、Promise
等全局对象,以及一些定义在全局对象上的方法(比如Object.assign)都不会转码。
举例来说,ES6 在Array对象上新增了Array.from方法。Babel 就不会转码这个方法。
Traceur 转码器
Google 公司的Traceur转码器,也可以将 ES6 代码转为 ES5 代码。
此处不展开深究,有兴趣的自行了解 Traceur Transcoding Demo
let 和 const 关键字
let 关键字
ES6 新增了let
关键字,用来声明变量。它的用法类似于var
,但是所声明的变量,只在let
关键字所在的代码块内有效。
应用场景
for
循环的计数器,就很合适使用let
命令。
for (let i = 0; i < 10; i++) {
// ...
}
console.log(i);
// ReferenceError: i is not defined
上面代码中,计数器i
只在for
循环体内有效,在循环体外引用就会报错。
ES6 的块级作用域
let
实际上为 JavaScript 新增了块级作用域。
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
块级作用域的出现,实际上使得获得广泛应用的立即执行函数表达式(IIFE)不再必要了。
// IIFE 写法
(function () {
var tmp = ...;
...
}());
// 块级作用域写法
{
let tmp = ...;
...
}
const 关键字
const
声明一个只读的常量。
- 一旦声明,常量的值就不能改变。
- 一旦声明变量,就必须立即初始化,不能留到以后赋值。
const
的作用域与let
命令相同:只在声明所在的块级作用域内有效。const
声明的常量,也与let
一样不可重复声明。
应用场景
const PI = 3.1415;
console.log(PI) // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.
变量的解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
数组解构
下面是数组赋值并且交换值的例子
//ES6
let list = [ 1, 2, 3 ];
let [ a, , b ] = list ; // a=1 ,b=3
[ b, a ] = [ a, b ] ;//a=3,b=1
//ES5
var list = [ 1, 2, 3 ];
var a = list[0], b = list[2];
var tmp = a; a = b; b = tmp;
对象的解构赋值
//ES6
let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo //aaa
bar //bbb
//ES5
var tmp = { foo: "aaa", bar: "bbb" };
var foo = tmp.foo; //aaa
var bar = tmp.bar; //bbb
字符串的解构赋值
//ES6
const [a,b,c,d,e] = 'hello';
a //h
b //e
c //l
d //l
e //o
/*
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
(然而个人觉得貌似没啥用啊,至少这个应用场景会很少,先了解下即可)
*/
let {length : len} = 'hello';
len // 5
//ES5
var hello ='hello';
var a,b,c,d,e;
a=hello[0];
b=hello[1];
c=hello[2];
d=hello[3];
e=hello[4];
a //h
b //e
c //l
d //l
e //o
/*
对应ES6 获取数组长度
*/
var len = hello.length;
len //5
函数参数的解构赋值
//ES6
function f ([ name, val ]) {
console.log(name, val)
}
function g ({ name: n, val: v }) {
console.log(n, v)
}
function h ({ name, val }) {
console.log(name, val)
}
f([ "bar", 42 ])
g({ name: "foo", val: 7 })
h({ name: "bar", val: 42 })
//ES5
function f (arg) {
var name = arg[0];
var val = arg[1];
console.log(name, val);
};
function g (arg) {
var n = arg.name;
var v = arg.val;
console.log(n, v);
};
function h (arg) {
var name = arg.name;
var val = arg.val;
console.log(name, val);
};
f([ "bar", 42 ]);
g({ name: "foo", val: 7 });
h({ name: "bar", val: 42 });
应用场景
交换变量值
let x = 1;
let y = 2;
[x, y] = [y, x];
函数返回多个返回值
函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便。
// 返回一个数组
function example() {
return [1, 2, 3];
}
let [a, b, c] = example();
// 返回一个对象
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
函数参数的定义
解构赋值可以方便地将一组参数与变量名对应起来。 56
// 参数是一组有次序的值 实际应用场景很少用
function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值 实际应用场景非常有用
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
提取 JSON 数据
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData; //非常有用,rn+redux项目就是这样获取数据绑定视图层展示的
console.log(id, status, number);
// 42, "OK", [867, 5309]
函数参数的默认值
//ES6
function test (_params='default value',_async=true,_callback=function(){}){
}
//ES5
function test(_params,_async,_callback){
if(_params===''|| _params===null|| _params===undefined) _params='default value';
if(_async===''|| _async===null|| _async===undefined) _async=true;
if(_callback===''||_callback===null||_callback===undefined) _callback=function(){};
}
New Built-In Methods(ES6的新支持函数)
Object Property Assignment (浅拷贝)
Object.assign
方法用于对象的合并,将源对象( source )的所有可枚举属性,复制到目标对象( target )。
注意:
- 如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。(克隆对象)
Object.assign()
只是一级属性复制,比浅拷贝多深拷贝了一层而已。用的时候,还是要注意这个问题的。
//ES6
let dest = { quux: 0 }
let src1 = { foo: 1, bar: 2 }
let src2 = { foo: 3, baz: 4 }
Object.assign(dest, src1, src2)
//dest.quux === 0
//dest.foo === 3
//dest.bar === 2
//dest.baz === 4
//ES5
var dest = { quux: 0 };
var src1 = { foo: 1, bar: 2 };
var src2 = { foo: 3, baz: 4 };
Object.keys(src1).forEach(function(k) {
dest[k] = src1[k];
});
Object.keys(src2).forEach(function(k) {
dest[k] = src2[k];
});
//dest.quux === 0;
//dest.foo === 3;
//dest.bar === 2;
//dest.baz === 4;
Array Element Finding (数组查找)
数组查找新增函数
//ES6
[ 1, 3, 4, 2 ].find(x => x > 3) // 4
[ 1, 3, 4, 2 ].findIndex(x => x > 3) // 2
//ES5
[ 1, 3, 4, 2 ].filter(function (x) { return x > 3; })[0]; // 4
// no equivalent in ES5
String Repeating (字符串重复)
感觉没啥应用场景,暂时想不到,join
倒是以前常用,将数组拼接的html模板join
成字符串。
//ES6
" ".repeat(4 * depth)
"foo".repeat(3)
//ES5
//能想到这种方式做字符串拷贝的也是 6666666
Array((4 * depth) + 1).join(" ");
Array(3 + 1).join("foo");
String Searching (字符串查找)
Es6 提供了新的函数进行字符串查找,第二个参数为字符串出现的index
//ES6
"hello".startsWith("ello", 1) // true
"hello".endsWith("hell", 4) // true
"hello".includes("ell") // true
"hello".includes("ell", 1) // true
"hello".includes("ell", 2) // false
//ES5
"hello".indexOf("ello") === 1; // true
"hello".indexOf("hell") === (4 - "hell".length); // true
"hello".indexOf("ell") !== -1; // true
"hello".indexOf("ell", 1) !== -1; // true
"hello".indexOf("ell", 2) !== -1; // false
Number Type Checking (数值校验)
//ES6
Number.isNaN(42) === false
Number.isNaN(NaN) === true
Number.isFinite(Infinity) === false
Number.isFinite(-Infinity) === false
Number.isFinite(NaN) === false
Number.isFinite(123) === true
//ES5
var isNaN = function (n) {
return n !== n;
};
var isFinite = function (v) {
return (typeof v === "number" && !isNaN(v) && v !== Infinity && v !== -Infinity);
};
isNaN(42) === false;
isNaN(NaN) === true;
isFinite(Infinity) === false;
isFinite(-Infinity) === false;
isFinite(NaN) === false;
isFinite(123) === true;
Number Safety Checking (数值范围校验)
校验数值是否在一个安全的范围内
//ES6
Number.isSafeInteger(42) === true
Number.isSafeInteger(9007199254740992) === false
//ES5
function isSafeInteger (n) {
return (
typeof n === 'number'
&& Math.round(n) === n
&& -(Math.pow(2, 53) - 1) <= n
&& n <= (Math.pow(2, 53) - 1)
);
}
isSafeInteger(42) === true;
isSafeInteger(9007199254740992) === false;
Number Comparison (数值比较)
ES6的Number
对象新增了一个常量Number.EPSILON
。这个值很小。引入这么小的一个常量的目的在于,为浮点数计算设置一个误差范围。因为浮点数的计算是不精确的。如果误差小于Number.EPSILON,我们就可以认为得到了正确的结果。
// 举个例子吧:
0.1+0.2; //0.30000000000000004
0.1+0.2-0.3; //5.551115123125783e-17
(0.1+0.2-0.3).toFixed(20); //"0.00000000000000005551"
// 那么我们再来看看0.1+0.2-0.3的值是否小于Number.EPSILON,如果小于,返回true,那我们便可以认为结果正确
(0.1+0.2-0.3).toFixed(20)<Number.EPSILON; // true
//当然我觉得不如这样好了 囧
Number.parseFloat((0.1+0.2).toFixed(2))===0.3
Number Truncation
方法会将数字的小数部分去掉,只保留整数部分。
//ES6
console.log(Math.trunc(42.7)) // 42
console.log(Math.trunc( 0.1)) // 0
console.log(Math.trunc(-0.1)) // -0
//ES5
function mathTrunc (x) {
return (x < 0 ? Math.ceil(x) : Math.floor(x));
}
console.log(mathTrunc(42.7)) // 42
console.log(mathTrunc( 0.1)) // 0
console.log(mathTrunc(-0.1)) // -0
Number Sign Determination (确定数字符号)
此函数共有5种返回值, 分别是 1, -1, 0, -0, NaN. 代表的各是正数, 负数, 正零, 负零, NaN。
//ES6
console.log(Math.sign(7)) // 1
console.log(Math.sign(0)) // 0
console.log(Math.sign(-0)) // -0
console.log(Math.sign(-7)) // -1
console.log(Math.sign(NaN)) // NaN
//ES5
function mathSign (x) {
return ((x === 0 || isNaN(x)) ? x : (x > 0 ? 1 : -1));
}
console.log(mathSign(7)) // 1
console.log(mathSign(0)) // 0
console.log(mathSign(-0)) // -0
console.log(mathSign(-7)) // -1
console.log(mathSign(NaN)) // NaN
参考
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为:2018-05-23 18:16:23