ECMAScript6(0):ES6简明参考手册

var substring = ‘foo’;

console.log(string.indexOf(substring) > -1);

检测返回值是否大于-1表示字符串是否存在,我们可以用.includes()替换,它返回一个boolean值。

const string = ‘food’;

const substring = ‘foo’;

console.log(string.includes(substring)); // true

.repeat()

function repeat(string, count) {

var strings = [];

while(strings.length < count) {

strings.push(string);

}

return strings.join(‘’);

}

在ES6中,我们一种更简洁的实现方法:

// String.repeat(numberOfRepetitions)

‘meow’.repeat(3); // ‘meowmeowmeow’

模板字面量(Template Literals)


(译注:原文是Template Literals,而非Template Strings)

利用模板字面量,我们可以直接在字符串使用特殊字符而不用转义它们。

var text = “This string contains “double quotes” which are escaped.”;

let text = This string contains "double quotes" which don't need to be escaped anymore.;

模板字面量还支持插值,可以轻松完成连接字符串和值的任务:

var name = ‘Tiger’;

var age = 13;

console.log(‘My cat is named ’ + name + ’ and is ’ + age + ’ years old.’);

const name = ‘Tiger’;

const age = 13;

console.log(My cat is named ${name} and is ${age} years old.);

在ES5中,我们这样操作多行字符串:

var text = (

‘cat\n’ +

‘dog\n’ +

‘nickelodeon’

);

或者

var text = [

‘cat’,

‘dog’,

‘nickelodeon’

].join(‘\n’);

模板字面量可以保留多行字符串,我们无需显式的放置它们:

let text = ( `cat

dog

nickelodeon`

);

模板字面量可以接受表达式, 比如:

let today = new Date();

let text = The time and date is ${today.toLocaleString()};

解构赋值(Destructuring)


解构赋值允许我们从数组或对象中提取出值(甚至深度嵌套的值),并把他们存入变量的简单语法

解构数组(Destructuring Arrays)

var arr = [1, 2, 3, 4];

var a = arr[0];

var b = arr[1];

var c = arr[2];

var d = arr[3];

let [a, b, c, d] = [1, 2, 3, 4];

console.log(a); // 1

console.log(b); // 2

解构对象(Destructuring Objects)

var luke = { occupation: ‘jedi’, father: ‘anakin’ };

var occupation = luke.occupation; // ‘jedi’

var father = luke.father; // ‘anakin’

let luke = { occupation: ‘jedi’, father: ‘anakin’ };

let {occupation, father} = luke;

console.log(occupation); // ‘jedi’

console.log(father); // ‘anakin’

模块(Modules)


ES6之前,我们只用如Browserify的库在客户端创建模块,并且需要用到Node.js。利用ES6,我们现在可以直接使用任何类型的模块(AMD和CommonJS)

CommonJS中的exports

module.exports = 1;

module.exports = { foo: ‘bar’ };

module.exports = [‘foo’, ‘bar’];

module.exports = function bar () {};

ES6中的export

在ES6中,提供各种不同类型的exports,我们可以运行如下:

export let name = ‘David’;

export let age = 25;​​

输出对象列表:

function sumTwo(a, b) {

return a + b;

}

function sumThree(a, b, c) {

return a + b + c;

}

export { sumTwo, sumThree };

我们也可以简单地通过export关键字输出函数、对象和值(等等):

export function sumTwo(a, b) {

return a + b;

}

export function sumThree(a, b, c) {

return a + b + c;

}

And lastly, we can export default bindings:

function sumTwo(a, b) {

return a + b;

}

function sumThree(a, b, c) {

return a + b + c;

}

let api = {

sumTwo,

sumThree

};

输出默认api:

/* Which is the same as

  • export { api as default };

*/

建议:在模块结束的地方,始终输出默认的方法。这样可以清晰地看到接口,并且通过弄清楚输出值的名称节省时间。所以在CommonJS模块中通常输出一个对象或值。坚持使用这种模式,会使我们的代码易读,并且可以轻松的在ES6和CommonJS中进行插补。

ES6

ES6 提供提供各种不同的imports,我们输入一整个文件:

import ‘underscore’;

这里值得注意的是,简单的输入一文件会在文件的最顶层执行代码。和Python类似,我们已经命名了imports:

import { sumTwo, sumThree } from ‘math/addition’;

我们还可以重命名这些已经有名的imports:

import {

sumTwo as addTwoNumbers,

sumThree as sumThreeNumbers

} from ‘math/addition’;

此外,我们可以输入各种东西(也叫做 namespace import)

import * as util from ‘math/addition’;

最后,我们可以从模块输入一列值:

import * as additionUtil from ‘math/addition’;

const { sumTwo, sumThree } = additionUtil;

如下这样从默认绑定进行输入

import api from ‘math/addition’;

// 例如: import { default as api } from ‘math/addition’;

虽然最好要保持输出简单,但是如果我们需要,我们有时可以混用默认输入,当我们想如下输出的时候:

// foos.js

export { foo as default, foo1, foo2 };

我们可以如下输入它们:

import foo, { foo1, foo2 } from ‘foos’;

当使用commonj语法(如React)输入一个模型的输出时,我们可以这样做:

import React from ‘react’;

const { Component, PropTypes } = React;

这个也可以进一步简化,使用:

import React, { Component, PropTypes } from ‘react’;

注意:输出的值是绑定,不是引用。因此,绑定的值发生变化会影响输出的模型中的值。避免修改这些输出值的公共接口。

参数(Parameters)


在ES5中,我们可以很多方法操作函数参数的默认值、未定义的参数和有定义的参数。在ES6中,我们可以用更简单的语法实现这一切。

默认参数(Default Parameters)

function addTwoNumbers(x, y) {

x = x || 0;

y = y || 0;

return x + y;

}

在ES6中,我们可以简单的把默认值赋给参数:

function addTwoNumbers(x=0, y=0) {

return x + y;

}

addTwoNumbers(2, 4); // 6

addTwoNumbers(2); // 2

addTwoNumbers(); // 0

剩余参数(Rest Parameters)

在ES5中,我们这样操作一个未定义的参数:

function logArguments() {

for (var i=0; i < arguments.length; i++) {

console.log(arguments[i]);

}

}

使用休止符(…)我们可以传入大量未定义的参数:

function logArguments(…args) {

for (let arg of args) {

console.log(arg);

}

}

已命名的参数(Named Parameters)

ES5中,一种处理已命名参数的方式是使用选项方式,这种方法来自jQuery。

function initializeCanvas(options) {

var height = options.height || 600;

var width = options.width || 400;

var lineStroke = options.lineStroke || ‘black’;

}

通过解构成正式参数的方式,我们可以实现同样的功能:

function initializeCanvas(

{ height=600, width=400, lineStroke=‘black’}) {

// Use variables height, width, lineStroke here

}

如果我们想使全部参数值可选,我们可以用一个空对象这样结构:

function initializeCanvas(

{ height=600, width=400, lineStroke=‘black’} = {}) {

// …

}

展开运算符(Spread Operator)


在ES5中,查找一个array中的最大值需要使用Math.max的apply方法:

Math.max.apply(null, [-1, 100, 9001, -32]); // 9001

在es6中,我们使用展开运算符将array传递给函数作为参数:

Math.max(…[-1, 100, 9001, -32]); // 9001

我们可以用这样简洁的语法链接数组字面量:

let cities = [‘San Francisco’, ‘Los Angeles’];

let places = [‘Miami’, …cities, ‘Chicago’]; // [‘Miami’, ‘San Francisco’, ‘Los Angeles’, ‘Chicago’]

类(classes)


在ES6之前,我们通过创建构造器函数,并且在其prototype上添加属性的方法创建一个类:

function Person(name, age, gender) {

this.name = name;

this.age = age;

this.gender = gender;

}

Person.prototype.incrementAge = function () {

return this.age += 1;

};

并且用一下方法创建继承类:

function Personal(name, age, gender, occupation, hobby) {

Person.call(this, name, age, gender);

this.occupation = occupation;

this.hobby = hobby;

}

Personal.prototype = Object.create(Person.prototype);

Personal.prototype.constructor = Personal;

Personal.prototype.incrementAge = function () {

Person.prototype.incrementAge.call(this);

this.age += 20;

console.log(this.age);

};

ES6 提供了十分有用的句法在后台实现这一切,我们可以这样直接创建一个类:

class Person {

constructor(name, age, gender) {

this.name = name;

this.age = age;

this.gender = gender;

}

incrementAge() {

this.age += 1;

}

}

并且用关键字extends实现继承:

class Personal extends Person {

constructor(name, age, gender, occupation, hobby) {

super(name, age, gender);

this.occupation = occupation;

this.hobby = hobby;

}

incrementAge() {

super.incrementAge();

this.age += 20;

console.log(this.age);

}

}

建议:使用ES6的语法创建类模糊了后台的实现和原型如何工作,这个好特性可以使我们的代码更整洁。

Symbols


Symbol在ES6之前就已经出现了, 但是现在我们有了一个公共的接口可以直接使用。Symbol是唯一且不可改变的值,被用作哈希中的键。

Symbol()

调用Symbol()或者Symbol(description)会创建一个不能在全局查找的独一无二的符号。一种使用symbol()的情况是,利用自己的逻辑修补第三方的对象或命名空间,但不确定会不会在库更新时产生冲突。例如,如果你想添加一个方法refreshCompontentReact.Component,并且确信这个方法他们不会在以后的更新中添加。

const refreshComponent = Symbol();

React.Component.prototype[refreshComponent] = () => {

// do something

}

###Symbol.for(key)

Symbol.for(key) 依然会创建一个唯一且不能修改的Symbol,但是它可以在全局被查找。两次调用相同的Symbol.for(key) 会创建一样的Symbol实例。注意,他和Symbol(description)不是相同的:

Symbol(‘foo’) === Symbol(‘foo’) // false

Symbol.for(‘foo’) === Symbol(‘foo’) // false

Symbol.for(‘foo’) === Symbol.for(‘foo’) // true

一个常见的symbol方法Symbol.for(key)是可互操作的。(使用这个方法)这个可以通过使用自己的代码在包括已知接口的第三方的对象参数中查找symbol成员实现,例如:

function reader(obj) {

const specialRead = Symbol.for(‘specialRead’);

if (obj[specialRead]) {

const reader = objspecialRead;

// do something with reader

} else {

throw new TypeError(‘object cannot be read’);

}

}

在另一个库中:

const specialRead = Symbol.for(‘specialRead’);

class SomeReadableType {

specialRead {

const reader = createSomeReaderFrom(this);

return reader;

}

}

ES6中,一个值得注意的是关于Symbol的互操作性的例子是Symbol.iterator,它存在于Arrays、Strings、Generators等等的所有可迭代类型中。当作为一个方法调用的时候,它会返回一个具有迭代器接口的对象。

Maps


Maps是JavaScript中十分有用的结构。在ES6之前, 我们通过对象创建哈希maps:

var map = new Object();

map[key1] = ‘value1’;

map[key2] = ‘value2’;

但是,这样不能保护我们对已有属性以外的重写:

getOwnProperty({ hasOwnProperty: ‘Hah, overwritten’}, ‘Pwned’);

TypeError: Property ‘hasOwnProperty’ is not a function

Map允许我们使用set、get和search(等等)访问属性值。

let map = new Map();

map.set(‘name’, ‘david’);

map.get(‘name’); // david

map.has(‘name’); // true

最意想不到的是Map不再限制我们只使用字符串作为键,我们现在可以使用任何类型作为键而不会发生类型转换。

let map = new Map([

[‘name’, ‘david’],

[true, ‘false’],

[1, ‘one’],

[{}, ‘object’],

[function () {}, ‘function’]

]);

for (let key of map.keys()) {

console.log(typeof key);

// > string, boolean, number, object, function

}

注意:当使用如map.get()等方法测试相等的时候,诸如function和object这样的非原始值不能正常工作。因此,依然应该使用原始值(作为键),比如String、Boolean和Number。

我们也可以使用.entries()方法作为迭代器遍历Map

for (let [key, value] of map.entries()) {

console.log(key, value);

}

WeakMaps


ES6之前,为了保存私有数据,我们采取了很多方式。其中一个方法就是命名转换:

class Person {

constructor(age) {

this._age = age;

}

_incrementAge() {

this._age += 1;

}

}

但是命名转换会引起代码库混乱,并且不能保证总是被支持。为此,我们使用WeakMaps存储数据:

let _age = new WeakMap();

class Person {

constructor(age) {

_age.set(this, age);

}

incrementAge() {

let age = _age.get(this) + 1;

_age.set(this, age);

if (age > 50) {

console.log(‘Midlife crisis’);

}

}

}

使用WeakMap存储数据时的一个很有趣的事情是,这个key不会暴露出属性名,需要使用Reflect.ownKeys()实现:

const person = new Person(50);

person.incrementAge(); // ‘Midlife crisis’

Reflect.ownKeys(person); // []

使用WeakMap更实际的例子是在不污染DOM自身的情况下存储与DOM元素相关的数据:

let map = new WeakMap();

let el = document.getElementById(‘someElement’);

// 给元素存一个弱引用

map.set(el, ‘reference’);

// 获得元素的值

let value = map.get(el); // ‘reference’

// 移除引用

el.parentNode.removeChild(el);

el = null;

// 元素被回收后,map是空的

如上所示,当一个对象被GC回收后,WeakMap会自动移除以其为标识符的键值对。

注意:为了进一步说明这个例子的实用性。当一个与DOM对应的对象的具有引用时,考虑jQuery如何存储它。使用WeakMaps,jQuery可以在DOM元素被删除时自动释放与之关联的内存。总而言之,对任何库而言,WeakMaps对操作DOM元素是非常实用的。

Promises


Promise允许我们把水平的代码(回调函数的地狱):

func1(function (value1) {

func2(value1, function (value2) {

func3(value2, function (value3) {

func4(value3, function (value4) {

func5(value4, function (value5) {

// Do something with value 5

});

});

});

});

});

转换为竖直的代码:

func1(value1)

.then(func2)

.then(func3)

.then(func4)

.then(func5, value5 => {

// Do something with value 5

});

在ES6之前,我们使用bluebird或是Q,现在我们有了Promises:

new Promise((resolve, reject) =>

reject(new Error(‘Failed to fulfill Promise’)))

.catch(reason => console.log(reason));

这里我们有2个handlers,resolve(Promise执行成功时调用的函数)和reject(Promise失败时调用的函数)。

使用Promise的好处:使用嵌套的回调函数处理错误会很混乱。使用Promise,我们可以很清晰的使错误冒泡,并且就近处理它们。更好的是,在它处理成功(或失败)之后Promise的值是不可修改的。

以下是个使用Promise的实例:

var request = require(‘request’);

return new Promise((resolve, reject) => {

request.get(url, (error, response, body) => {

if (body) {

resolve(JSON.parse(body));

} else {

resolve({});

}

});

});

我们可以使用Promise.all()并行的处理一个异步操作数组:

let urls = [

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
ue5 => {

// Do something with value 5

});

在ES6之前,我们使用bluebird或是Q,现在我们有了Promises:

new Promise((resolve, reject) =>

reject(new Error(‘Failed to fulfill Promise’)))

.catch(reason => console.log(reason));

这里我们有2个handlers,resolve(Promise执行成功时调用的函数)和reject(Promise失败时调用的函数)。

使用Promise的好处:使用嵌套的回调函数处理错误会很混乱。使用Promise,我们可以很清晰的使错误冒泡,并且就近处理它们。更好的是,在它处理成功(或失败)之后Promise的值是不可修改的。

以下是个使用Promise的实例:

var request = require(‘request’);

return new Promise((resolve, reject) => {

request.get(url, (error, response, body) => {

if (body) {

resolve(JSON.parse(body));

} else {

resolve({});

}

});

});

我们可以使用Promise.all()并行的处理一个异步操作数组:

let urls = [

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-7ECq7AgN-1715348360242)]

[外链图片转存中…(img-W91R8I4t-1715348360242)]

[外链图片转存中…(img-MFziNdyx-1715348360243)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值