越来越多的开源库开始使用ES2015来构建代码了,大家知道ES6=ES2015,ES6在2015年被ECMAScript标准化组织approve,各大浏览器厂商要完全支持ES6的强大功能还须一些时日,对于喜爱新尝试的同学难道只有干等吗?幸运的是有了babel,traceur等transpiler的帮助,我们根本不用等待浏览器原生支持ES6才开始使用新技术了!其实babel做的事情很简单,他就是把es6的代码转换成浏览器认识的ES5代码。简单举一个例子,比如ES6中引入的语言原生支持模块的关键字import, export在仅实现ES5的浏览器中无法运行,因此babel做的就是将import, export转换为commonJS的模块格式require, exports, 随后在加载到浏览器端的SystemJS模块加载器的帮助下(或者通过webpack,browserify Module bundler工具整合),就能完全实现了ES6模块的功能。

本文视图整理我在学习ES6过程中遇到的一些常见重要知识点和疑惑的问题

Variable and Parameters

block scope

ES6中引入了block scope的概念,配合使用let来declare一个变量的话,该变量就只在block中可见

if (flag){
let x = 3; // x只在这个{}block中可见
}
return x; // x is not defined error!

declared vs initialized

var x;  // declared

x = 5 ; // initialized

'use strict';
function udpate(){
pid = 12;
}
let pid = null;
update();
console.log(pid); //12 和var声明的变量类似,外部scope可以被inner访问,由于pid在全局定义,函数内可以访问全局变量

let vs var

let支持块作用域,不会像var那样hoisted到前面

同样let支持for block

for (let i=0;i <10; i++)
{
}
return i // i not defined, 原因是i只在for loop中可见 for (var i=0;i <10; i++)
{
}
return i // i==10

let在for loop中以及closure下和传统var的区别

'use strict';
let updatefns = [];
for (let i=0;i<2;i++){
updatefns.push(function(){ return i; //注意let在for loop中使用时,每一次循环都会在for block中定义一个新的i,所以updatefns[0]()将返回0而不是2~!!
//好好体会这一点:在es5中的closure则会返回2
}); consoloe.log(updatefns[0]()); //返回0 consoloe.log(updatefns[1]()); //返回1

const(chrome,firefox支持的,貌似非es6标准)

const MAX_AGE 130
MAX_AGE = 200 //syntax error
const NOTINIT //语法错误,const必须初始化!

注意:const的scope和let是一致的,这是es6引入的新特性

Destructuring

let x = 2;
let y = 3;
[x,y] = [y,x] //[3,2]
// 右边的是array, 左边不是array,而是destructuring,只对x,和y赋值
// destructuring assignment, 注意 let [x,y]=[2,3] //这里对x,y两个单个变量赋值: x=2, y=3并且在后面可以直接访问
expect(x).toBe(2)
expect(y).toBe(3); var retv = function(){
return [1,2,3];
}
let [, x , y] = retv(); // [1,2,3]解构 这里 , 号表示忽略部分结构单元
exepct(x).toBe(2)
exepct(y).toBe(3) var retO = function(){
return {
firstName: "alice",
lastName: "zhang",
social: {
qq: "13442",
wechat: "wechatalice"
}
}
} let { firstName: f, lastName: l, social:{wechat: weixin}} = retO();
//f = "alice", l = "zhang" , weixin = "wechatalice" let { firstName, lastNamel, social:{wechat}} = retO();
//firstName= "alice", lastName = "zhang" , wechat = "wechatalice" //模拟一个ajax call返回结果解构:
let ajax = function(url, {data, cache}{
return data; //注意这里data是从ajax调用者传入的配置对象解构出来data字段后直接返回的
//在通常的ajax调用中,则从server端返回
}
let result = ajax("api/test", {
data: "test data for ajax", //这是ajax调用的传入对象,可以被ajax解构成变量
cache: false
});
expect(result).toBe("test data for ajax") // true

再看一些例子:

let salary = ['1000',3000','2000'];
let [ low, ...remaining ] = salary; //在destructuring中使用rest操作符
console.log(remaining); // ["3000","2000"] let salary = ['1000',3000'];
let [ low, average, hight = '8000' ] = salary; //在destructuring中使用默认参数
console.log(high); // let salary = ['1000',3000'];
let low, average, hight; // 先let声明变量
[ low, average, hight = '8000' ] = salary; //通过destructuring来赋值变量
console.log(high); // 8000 function reviewSalary([low, average], high = '8000'){
console.log(average); //在这里通过destructure传入的数组来赋值average
}
reviewSalary(['2000','3000']); //3000

destucturing object需要注意的点:

let salary = {
low: '3000',
average: '4000',
high: '5000'
}
let newLow, newAverage, newHigh;
{ low: newLow, average: newAverage, high: newHigh} = salary; //注意额,这个是会出现syntax error的,原因是js引擎会认为是一条语句,
//解决方案是用()括起来
({ low: newLow, average: newAverage, high: newHigh} = salary); // let [high, low] = null; //会出错,destructure的对象必须要支持iterator

default value(默认参数值)

var doWork = function(name){
// es5中对默认name参数的处理方法:使用|| 操作符,如果不传入name,则name就为zhangsan
name = name || "zhangsan" ;
return name;
}; var doWork = function(name = "zhangsan"){
// es6给name参数一个默认值,如果不传入name,则name就为zhangsan
return name;
}; doWork(); //默认参数同样适用于解构:
let ajax = function(url, {data = “default data”, cache}{
return data; //注意这里data是从ajax调用者传入的配置对象解构出来data字段后直接返回的,
// 如果传入对象不含data,则取默认值 default data
//在通常的ajax调用中,则从server端返回
}
let result = ajax("api/test", {
cache: false
});
expect(result).toBe("default data") // true

Rest Parameters ...paraName (必须是最后一个参数)

let sum = function(name, ...numbers){
// rest parameter必须是函数的最后一个参数
let result = 0;
for (let i=0;i<numbers.length;i++){
result += numbers[i];
}
return result;
}
let result = sum("alicechang") // 0    // 如果不传入numbers参数,则numbers就是一个空数组[]
let result = sum("alicechang",1,2,3) // 6 // 注意这时numbers就是一个数组了[1,2,3]  let result = sum("alicechang",1,3,5,6) //15 // 注意这时numbers就是一个数组了[1,3,5,6]

Spread Operator ...[a1,a2,a3]

let dowork = function(x,y,z){
return x+y+z;
}
var result =dowork(...[1,2,3]); //将数组中的3个数分别传给x,y,z形参
expect(result).toBe(6) //也可以用来构建新的数组:
var a = [4,5,6];
var b = [1,2,3, ...a, 7,8,9];
// b就等于 [1,2,3,4,5,6,7,8,9]了!!

同时也可以用在对字符串的操作上:

var maxCode = Math.max(..."43201");
console.log(maxCode); // var codeArray = ["A",..."BCD","E"];
console.log(codeArray);// ["A","B","C","D","E"];

通过...实现配置项的合并

export default {
install(vue, opts){ // Merge options argument into options defaults
const options = { ...optionsDefaults, ...opts } ...
}
}

Template Literal: `template String ${ varName }`

let category = "music";
let id = 1234;
let url = `http://myserver.com/${category}/${id}`;
//这时 url中的变量就会被替换,最后的value = http://myserver.com/music/1234

更多的例子:

let invoiceNum = '1350';
console.log(`Invoice Number: ${"INV-"+invoiceNum}`); //Invoice Number: INV-1350 //插值早于函数被调用!
function showMsg(message){
let invoiceNum = '99'; //注意这个invoiceNum不会被用到,因为插值要早于函数调用
}
let invoiceNum = '1350';
showMsg(`Invoice Number: ${invoiceNum}`); //Invoice Number: 1350

template还支持所谓的tag, tag template literal 比如:

let upper = function(strings,...values){
let result = "";
for (var i=0; i <strings.length; i++){
result+=strings[i];
if (i<values.length){
result+= values [i];
}
}
return result.toUpperCase();
}
var x = 1; y =3;
var result = upper `${x} + ${y} is equal to ${x+y}`;
// result为: 1 + 3 IS EQUAL TO 4

再看看几个所谓tag template literal的例子:

function processInvoice(segments){
console.log(segments);
}
processInvoice `template` ; // ["template"] 这是我们的template literal的value //更复杂一点的例子:
function processInvoice(segments, ...values){
console.log(segments);
console.log(values);
}
let invoiceNum = '1350';
let amount = '2000';
// 在这里tag就是processInvoice, template literal就是`Invoice......${amount}`
processInvoice `Invoice: ${invoiceNum} for ${amount}`;
//输出内容
["Invoice: "," for ", ""] //这就是所有独立的string内容
[1350,2000] //这就是所有插值的value

可以参考: http://exploringjs.com/es6/ch_template-literals.html来详细了解所谓tag template literal的功用

Arrow Functions =>(this指向问题)

var getPrice = () => 5.99;
console.log(typeof getPrice); // function
var getPrice = count => count*4.00; //只有一个参数时,可以不用()
console.log(getPrice(2)); //

arrow functions除了具有以上语法格式简洁的优点外,更重要的是为了解决es5中的this难题:

document.addEventListener('click',function(){
console.log(this); //这里this为#document(接收事件的哪个对象),而不
//不是代码执行的context(代码执行时function的context实际上应该是window!
});
document.addEventListener('click',() =>
console.log(this); //这里this为window!也就是function执行时的context
);

更多关于arrow function中的this指向问题

var invoice = {
number: 123,
process: function(){
consoloe.log(this);
}
}
invoice.process(); // object invoice, ES5中this is being set to the object on which the function(owns the this) is called var invoice = {
number: 123,
process: () =>{
consoloe.log(this);
}
}
invoice.process(); // window, arrow function中的this指向context the code running on var invoice = {
number: 123,
process: function(){
return () => consoloe.log(this.number);
}
}
involice.process()(); //123, this指向invoice var invoice = {
number: 123,
process: function(){
return () => consoloe.log(this.number);
}
}
var newInvoice = {
number: 456
}
involice.process().bind(newInvoice)(); //123, 注意bind不能绑定一个对象到一个arrow function!甚至js会抛出错误, 不能修改arrow的this
involice.process().call(newInvoice); //123, 注意call也不能绑定一个对象到一个arrow function!甚至js会抛出错误, 不能修改arrow的this

arrow function不具有prototype属性(传统ES5的函数都具有该属性可以访问使用)

var getPrice = () => 5.99;
console.log(getPrice.hasOwnProperty('prototype') //false,因为arrow function不具有prototype属性!

Object Literal extension

var price = 5, quantity = 30;
var productView = {
price, // = price: price
quantity // =quantity: quantity
}
console.log(productView); // {price: 5, quantity: 30} var field = 'dynamicField';
var price = 5;
var productView = {
[field+"-001"]: price
}
console.log(productView); //返回{dynamicFiled-001: 5}

for ... of loops

var cates = ['hardware','software'];
for (var item of cates){
cosole.log(item); // hardware software
} var cates = [,,];
for (var item of cates){
cosole.log(item); // undefined undefined
} var codes = "ABCDE";
var count = 0;
for (var code of codes){
count++;
}
console.log(count); //5 for ... of可以loop字符串

ES6/ES2015常用知识点和概念的更多相关文章

  1. 关于ES6(ES2015)的知识点详细总结

    ECMAScript6 ECMAScript简称就是ES,你可以把它看成是一套标准,JavaScript就是实施了这套标准的一门语言,现在主流浏览器使用的是ECMAScript5. http://ba ...

  2. ES6 常用知识点总结

    ES6常用知识总结 之前总结了es5中js的一些知识点.这段时间看了石川blue老师讲解的es6课程,结合阮一峰老师的es6教程,随手做了一些笔记和总结分享给大家.内容还是es6主要的知识点,基本没有 ...

  3. ES6/ES2015核心内容

    ECMAScript定义了: JS语言语法 – 语法解析规则.关键字.语句.声明.运算符等. 类型 – 布尔型.数字.字符串.对象等. 原型和继承 内建对象和函数的标准库 – JSON.Math.数组 ...

  4. 30分钟掌握ES6/ES2015核心内容

    30分钟掌握ES6/ES2015核心内容   ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript ...

  5. 30分钟掌握ES6/ES2015核心内容(上)

    ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015. 也就是说,ES6就是ES2015. ...

  6. ES6/ES2015核心内容(上)

    ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015.也就是说,ES6就是ES2015. ...

  7. ES6/ES2015核心内容(转载)

    ES6其实就是ES2015,因为是2015年发布的,所以也叫ES2015.这个版本是JS的最新版本,很多浏览器还不支持,所有有了babel,专门把最新的JS转换一下,让大部分浏览器都支持的JS版本. ...

  8. 一文学会 TypeScript 的 82% 常用知识点(下)

    一文学会 TypeScript 的 82% 常用知识点(下) 前端专栏 2019-11-23 18:39:08     都已经 9021 年了,TypeScript(以下简称 TS)作为前端工程师不得 ...

  9. 掌握ES6/ES2015核心内容

    ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015. 也就是说,ES6就是ES2015. ...

随机推荐

  1. qt下qmake:提示could not exec '/usr/lib/x86_64-linux-gnu/qt4/bin/qmake': No such file or directory

    编译出现的问题解决方法: 打开终端输入,qmake -v,出现错误:qmake: could not exec '/usr/lib/x86_64-linux-gnu/qt4/bin/qmake': N ...

  2. 利用JS获取本地时间和服务器时间

    <p id="labTime"> <script type="text/javascript"> //取客户端时间 setInterva ...

  3. centos7 装机配置及 mysql 安装过程

    打开网卡,使操作系统可以上网 1 ip add 查看网卡,lo是回环网卡可以忽略,ens33为实际网卡. [root@localhost ~]# ip add 1: lo: <LOOPBACK, ...

  4. python设计模式--读书笔记

    GoF在其设计模式一书中提出了23种设计模式,并将其分为三类: 创建型模式 将对象创建的细节隔离开来,代码与所创建的对象的类型无关. 结构型模式 简化结构,识别类与对象间的关系,重点关注类的继承和组合 ...

  5. UUID生成工具

    public class UUIDUtils { private static SecureRandom SEEDER_STATIC = null; private static byte[] ADD ...

  6. 使用WinSCP进行简单代码文件同步

    前言传输协议FTPFTPSSFTPSCP为什么使用WinSCP?CMD的FTP命令FileZillaPuTTYrsyncSublime的SFTP插件WinSCPWinSCP进行简单代码文件同步总结备注 ...

  7. (转)python time模块和datetime模块详解

    python time模块和datetime模块详解 原文:http://www.cnblogs.com/tkqasn/p/6001134.html 一.time模块 time模块中时间表现的格式主要 ...

  8. oracle 层次化查询(生成菜单树等)

    1.简介:Oracle层次化查询是Oracle特有的功能实现,主要用于返回一个数据集,这个数据集存在树的关系(数据集中存在一个Pid记录着当前数据集某一条记录的Id). 2.层次化查询主要包含两个子句 ...

  9. codeforces 638B—— Making Genome in Berland——————【类似拓扑排序】

    Making Genome in Berland time limit per test 1 second memory limit per test 256 megabytes input stan ...

  10. shell脚本检测监控mysql的CPU占用率

    网站访问量大的时候mysql的压力就比较大,当mysql的CPU利用率超过300%的时候就不能提供服务了,近乎卡死状态,这时候最好的方法 就是重启mysql服务.由于这种事具有不可预见性,我们不知道什 ...