ES5--ES6

babel在线转换

*1. 变量、常量声明

{
  var a = 'var';
  let b = 'let';
  const c = 'const';//常量
console.log(a + ',' + b);//1,2
}
console.log(a + ',' + b);//ReferenceError: b is not defined
                            //let增加了块级作用域,内外不同

*2. 解构赋值

//变量
let [, [, [c]]] = [1, [2, [3]]];//深层嵌套,单一也一样,逗号前也可用变量,同等情况赋值,var,const都可
console.log(c);//3
let [a, ...b] = [1, 2, 3];//"rest模式"
console.log(a+','+ b);//1, 2, 3
console.log(b);//[2, 3]
//对象
let robotA = { name: "Bender" };//对象名,属性,值
let { name: nameA } = robotA;//属性,变量名,对象名
console.log(nameA);// "Bender"
var { foo, bar } = { foo: "lorem", bar: "ipsum" };//对象名=属性,值
console.log(foo);// "lorem"
//注意
var {blowUp} = null;// TypeError: can't convert null to object
                       //使用对象赋值模式时,被解构的值必需能够转换成一个对象(object)。大多数的类型都可以转换为一个对象,但null和undefined却并不能被转换。
//默认值
var [missing = true] = [];//对于值和属性未定义的数组与对象,可用解构赋值设定默认值
console.log(missing);// true
var { message: msg = "Something went wrong" } = {};
console.log(msg);// "Something went wrong"
var { x = 3 } = {};
console.log(x);// 3

*3. 箭头函数Arrow Function

// ES5
function total(a, b) {
  let a = b;
  return a + b;
};
// ES6
var total = (a, b) => {
  let a = b;
  return a + b
};//单个参数可省略括号;函数体只有return ...可省略大括号;去掉前缀就是匿名函数;返回一个对象必须({})小括号包对象
/*this in arrow function*/
//ES5
{
  ...
  addAll: function(pieces) {
    var self = this;//保存this
    _.each(pieces, function (piece) {
      self.add(piece);//使用外部this
    });
  },
  ...
}
    // ES6的方法语法
{
  ...
  addAll(pieces) {
    _.each(pieces, piece => this.add(piece));//this继承了外围作用域的this值,不可改变
  },
  ...
}

*4. 函数参数

//默认值default
function log(x, y = 'World') {
  console.log(x, y);
}
log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello
//参数打包Rest
function f(x, ...y) {// y is an Array
  return x * y.length;
}
f(3, "hello", true);//6
//数组展开Spread
function f(x, y, z) {
  return x + y + z;
}
f(...[1,2,3]);// 6

*5. 字符串模块Template Strings

var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`// return "Hello Bob, how are you today?"
//大括号里也可以是函数fn(),取得函数返回值

*6. 迭代器Iterators、生成器Generator

对集合中的任意项进行处理是很常见的操作。JavaScript 提供了好几种方法来遍历一个集合,从简单的 for循环至 map()filter() 。迭代器和生成器将迭代的概念纳入javascritp的核心语言中,并提供了一种自定义 for...of 循环体的机制 。

//迭代器
//在JavaScript 中迭代器是一个对象,提供 next() 方法,返回序列中的下一项。这个方法返回包含done和value两个属性的对象。for-in可代替,但是无序,for-of可代替
function makeIterator(array){//创建一个迭代器,如果是对象,可设置第二个参数表示是否迭代属性值。。。
    var nextIndex = 0;
    return {
       next: function(){
           return nextIndex < array.length ?
               {value: array[nextIndex++], done: false} :
               {done: true};
       }
    }
}
var it = makeIterator(['yo', 'ya']);//一旦初始化,next()方法可以用来依次访问对象中的键-值
console.log(it.next().value); // 'yo'
console.log(it.next().value); // 'ya'
console.log(it.next().done);  // true
//生成器:一个更好的方法来构建遍历器
//一个生成器其实是一种特殊类型的函数(这个函数作为一个为迭代器工作的工厂),一个函数如果它里面包含了一个或一个以上的yield表达式(yield关键字只能被包含在下面的代码快中才有用 <script type="application/javascript;version=1.7">  (或者更高版本).XUL脚本标记访问这些功能不需要这个特殊的块。),那么这个函数就成为一个生成器了。
function* (){};//生成器函数:一种可以从中退出并在之后重新进入的函数。生成器的环境(绑定的变量)会在每次执行后被保存,下次进入时可继续使用。
//当一个生成器函数被一个函数体调用时并不会马上执行;相反,它会返回一个generator-iterator对象。每次调用generator-iterator的next()方法将会执行这个函数体至下一个yield表达式并且返回一个结果。当函数执行完或者执行到一个return时抛出一个StopIteration exception异常。
function* simpleGenerator(){
  yield "first";
  yield "second";
  yield "third";
  for (var i = 0; i < 3; i++)
    yield i;
}
var g = simpleGenerator();
print(g.next()); // prints "first"
print(g.next()); // prints "second"
print(g.next()); // prints "third"
print(g.next()); // prints 0
print(g.next()); // prints 1
print(g.next()); // prints 2
print(g.next()); // StopIteration is thrown
/*generator-iterator对象的send()方法可以用来修改生成器的内部状态。
传递一个值给send()将被视为最后一个yield表达式的结果(生成器暂停)。(个人观点:相当于重启生成器)
你必须在你使用send(参数)前通过调用next()来启动生成器。
*/
/*generator-iterator对象的close() 方法来强制生成器结束。结束一个生成器会产生如下影响:
所有生成器中有效的 finally 字句将会执行;
如果 finally 字句抛出了除 StopIteration 以外的任何异常,该异常将会被传递到 close() 方法的调用者;
生成器会终止
*/

*7. Class。有constructor、extends、super,但本质上是语法糖(对语言的功能并没有影响,但是更方便程序员使用)

class Artist {
    constructor(name) {
        this.name = name;
    }
    perform() {
        return this.name + " performs ";
    }
}
class Singer extends Artist {
    constructor(name, song) {
        super.constructor(name);
        this.song = song;
    }
    perform() {
        return super.perform() + "[" + this.song + "]";
    }
}
let james = new Singer("Etta James", "At last");
james instanceof Artist; // true
james instanceof Singer; // true
james.perform(); // "Etta James performs [At last]"

*8. Modules

//ES6提供了如下几种导入方式:
// Default exports and named exports
import theDefault, { named1, named2 } from 'src/mylib';
import theDefault from 'src/mylib';
import { named1, named2 } from 'src/mylib';
// Renaming: import named1 as myNamed1
import { named1 as myNamed1, named2 } from 'src/mylib';
// Importing the module as an object (with one property per named export)
import * as mylib from 'src/mylib';
// Only load the module, don’t import anything
import 'src/mylib';
//如下几种导出方式:
 //命名导出
export var myVar1 = ...;
export let myVar2 = ...;
export const MY_CONST = ...;
export function myFunc() {}
export function* myGeneratorFunc() {}
export class MyClass {}
// default 导出
export default 123;
export default function (x) {
    return x
};
export default x => x;
export default class {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
};
//也可以自己列出所有导出内容
const MY_CONST = ...;
function myFunc() {}
export { MY_CONST, myFunc };
//或者在导出的时候给他们改个名字
export { MY_CONST as THE_CONST, myFunc as theFunc };
//还可以导出从其他地方导入的模块
export * from 'src/other_module';
export { foo, bar } from 'src/other_module';
export { foo as myFoo, bar } from 'src/other_module';

*9. Map映射 + Set集合 + WeakMap弱映射 + WeakSet弱集合

// Sets,不易被回收
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;
// Maps,不易被回收
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;
//WeakMap,允许从内存中清除不再需要的被这些集合所引用的对象。
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined
// Weak Sets,允许从内存中清除不再需要的被这些集合所引用的对象。
var ws = new WeakSet();
ws.add({ data: 42 });//Because the added object has no other references, it will not be held in the set

*10. Math + Number + String + Array + Object APIs

Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN") // false

Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) // 5
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2

"abcde".includes("cd") // true
"abc".repeat(3) // "abcabcabc"

Array.from(document.querySelectorAll('*')) // Returns a real Array
Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior

[0, 0, 0].fill(7, 1) // [0,7,7]
[1, 2, 3].find(x => x == 3) // 3
[1, 2, 3].findIndex(x => x == 2) // 1
[1, 2, 3, 4, 5].copyWithin(3, 0) // [1, 2, 3, 1, 2]
["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
["a", "b", "c"].keys() // iterator 0, 1, 2
["a", "b", "c"].values() // iterator "a", "b", "c"

Object.assign(Point, { origin: new Point(0,0) })

*11. 代理Proxies

使用代理(Proxy)监听对象的操作

//可监听的操作: get、set、has、deleteProperty、apply、construct、getOwnPropertyDescriptor、defineProperty、getPrototypeOf、setPrototypeOf、enumerate、ownKeys、preventExtensions、isExtensible。
var target = {};
var handler = {
  get: function (receiver, name) {
    return `Hello, ${name}!`;
  }
};
var p = new Proxy(target, handler);
p.world === 'Hello, world!';

*12. Symbol

一种新的原始数据类型Symbol,表示独一无二的值

/*
*Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象
*Symbol值不能与其他类型的值进行运算
*Symbol值作为对象属性名时,不能用点运算符
*Symbol值作为属性名时,该属性还是公开属性,不是私有属性
**/
// 没有参数的情况
var s1 = Symbol();
var s2 = Symbol();
s1 === s2 // false
// 有参数的情况
var s1 = Symbol("foo");
var s2 = Symbol("foo");
s1 === s2 // false
//作为属性
var a = {};
var name = Symbol();
a.name = 'lili';
a[name] = 'lucy';
console.log(a.name,a[name]); //lili,lucy
//Symbol.for(),首先在全局中搜索有没有以该参数作为名称的Symbol值,有就返回这个Symbol值,否则新建并返回一个以该字符串为名称的Symbol值。和原Symbol不同。
var s1 = Symbol.for('foo');
var s2 = Symbol.for('foo');
s1 === s2 // true
//Symbol.keyFor()返回一个已登记的Symbol类型值的key。实质就是检测该Symbol是否已创建
var s1 = Symbol.for("foo");
Symbol.keyFor(s1) // "foo"
var s2 = Symbol("foo");
Symbol.keyFor(s2) // undefined

*13. Promises

Promises是处理异步操作的对象,使用了 Promise 对象之后可以用一种链式调用的方式来组织代码,让代码更加直观(类似jQuery的$.Deferred())。

Promises三种状态:Fulfilled(成功);Rejected(失败);Pending(Promise 对象实例创建时候的初始状态)

//then、 catch
function helloWorld (ready) {
    return new Promise(function (resolve, reject) {
        if (ready) {
            resolve("Hello World!");
        } else {
            reject("Good bye!");
        }
    });
}
helloWorld(true).then(function (message) {
    alert(message);//resolve的内容
}, function (error) {
    alert(error);//reject的内容
});
//then(onFulfilld, onRejected) 方法就是根据 Promise 对象的状态来确定执行的操作,resolve 时执行第一个函数(onFulfilled),reject 时执行第二个函数(onRejected)
//then(onFulfilld, onRejected) 可写成then(fn).catch(fn)相当于 then(fn).then(null, fn),catch(fn相当于)onRejected 函数的一个简写
helloWorld(true).then(function (message) {
    return message;
}).then(function (message) {
    return message  + ' World';
}).then(function (message) {
    return message + '!';
}).then(function (message) {
    alert(message);
});
//上述例子通过链式调用的方式,按顺序打印出了相应的内容。then 可以使用链式调用的写法原因在于,每一次执行该方法时总是会返回一个 Promise 对象。另外,在 then onFulfilled 的函数当中的返回值,可以作为后续操作的参数

//Promises.all()、Promises.race()
//Promise.all 可以接收一个元素为 Promise 对象的数组作为参数,当这个数组里面所有的 Promise 对象都变为 resolve 时,该方法才会返回。
var p1 = new Promise(function (resolve) {
    setTimeout(function () {
        resolve("Hello");
    }, 3000);
});
var p2 = new Promise(function (resolve) {
    setTimeout(function () {
        resolve("World");
    }, 1000);
});
Promise.all([p1, p2]).then(function (result) {
    console.log(result); // ["Hello", "World"]
});
//上面的例子模拟了传输两个数据需要不同的时长,虽然 p2 的速度比 p1 要快,但是 Promise.all 方法会按照数组里面的顺序将结果返回。
//使用场景:通常接口之间没有关联(例如不需要前一个接口的数据作为后一个接口的参数),这个时候 Promise.all 方法就可以派上用场了
//Promise.race,它同样接收一个数组,不同的是只要该数组中的 Promise 对象的状态发生变化(无论是 resolve 还是 reject)该方法都会返回。

参见:
浅谈JavaScript、ES5、ES6
ES6与ES5差别
【探秘ES6】系列专栏(六):解构赋值
深入浅出ES6(七):箭头函数 Arrow Functions
迭代器和生成器
ES6详解八:模块(Module)!
ES6入门之Symbol
谈谈 ES6 的 Promise 对象

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容