【学习笔记】ES6标准入门
这里简要记录一下对自己感触比较深的几个知识点,将核心的应用投放于实际的项目之中,提供代码的可维护性。
一、let和const
{
// let声明的变量只在let命令所在的代码块内有效
let a = 1;
var b = 2;
}
console.log(a); // 报错: ReferenceError: a is not defined
console.log(b);
// for循环的技术器就很适合let命令
for (let i = 0; i < 3; i++) {
console.log(i);
} console.log(i); // ReferenceError: i is not defined
// 这里的i是var声明的,在全局范围内有效,素偶一每一次循环,新的i值都会覆盖旧值,导致最后输出的是最后一轮的i值
for (var i = 0; i < 10; i++) {
a[i] = function() {
console.log(i);
}
} a[6](); // var b = []; // 使用let声明的变量尽在块级作用域内有效,所以每一次循环的j其实都是一个新的变量,于是最后输出6
for (let j = 0; j < 10; j++) {
a[j] = function() {
console.log(j);
}
} b[6]();
// let不像var那样会发生"变量"提升的现象
// 但是经过babel转换器转换之后,还是存在变量提升的现象
// ES6明确规定,如果区块中存在let和const命令,则这个区块中对这些命令声明的变量从一开始就形成封闭作用域.只要在声明这些变量之前就使用这些变量,就会报错
{
console.log(foo); // ReferenceError
let foo = 2;
} // 块级作用域
{
// 块级作用域的出现使得获得广泛应用的立即执行匿名函数(IIFE)不再必要了
// IIFE写法
(function() {
var tmp = 'a';
// ...
})(); // 块级作用域写法
{
let tmp = 'a';
// ...
} // 因此,我们可以使用块级作用域来划分业务模块,以及避免全局变量 } {
let a = 'secret'; function f() {
return a;
}
} f(); // 报错
// const声明的常量不得改变值
// const一旦声明常量,就必须立即初始化,不能留到以后赋值
// const的作用域与let命令相同:只在声明所在的块级作用域内有效
// const命令声明的变量也不提升,只能声明后使用
const foo = 'AAA';
foo = 'BBB'; // 编译不通过
{
// 跨模块常量
// constants.js
//export const A = 1;
//export const B = 2;
//export const C = 3;
// test1.js模块
//import * as constants from 'constants';
}
// 全局对象的属性
var a = 1;
console.log(window.a); // let b = 2;
console.log(window.b); // undefined
二、字符串
{
// 使用for of循环字符串
for (let c of 'foo') {
console.log(c);
}
let s = 'Hello world!';
// 使用字符串的startsWidth/endsWidth/includes方法
console.log(s.startsWith('Hello')); // true
console.log(s.endsWith('!')); // true
console.log(s.includes('e')); // true
// 这三个方法都支持第二个参数,表示开始搜索的位置
s.startsWith('world', 6); // true
let person = {
name: 'king',
age: 20
};
// 模板字符串
// 所有的空格和缩进都会被保留在输出中
let str = (`
The name is ${person.name}.
The age is ${person.age}.
`);
console.log(str);
}
三、函数
// 函数参数的默认值
function log(x, y = 'world') {
console.log(x, y);
} log('hello'); // 可以省略尾部参数的默认值 function f(x = 1, y) {
return [x, y];
} f(); // [1, undefined]
f(2); // [2, undefined]
f(, 1); // 报错, 编译无法通过 // rest参数
function add(...values) {
let sum = 0; for (let val of values) {
sum += val;
} return sum;
} console.log(add(2, 5, 3)); // const sortNumbers = function() {
let arr = Array.prototype.slice.call(arguments);
return arr.sort();
}; const sortNumbers = function (...numbers) {
return numbers.sort();
}; sortNumbers(3, 1, 2); // rest参数必须是参数列表中的最后一个
const push = function(array, ...items) {
items.forEach(function(item) {
array.push(item);
});
}; let a = []; console.log(push(a, 3, 1, 2));
四、对象
// Object.assign方法用来将源对象的所有可枚举属性复制到目标对象
let target = {
a: 1
}; // 后边的属性值,覆盖前面的属性值
Object.assign(target, {
b: 2,
c: 3
}, {
a: 4
}); console.log(target); // 用处1 - 为对象添加属性
class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
} //let p = new Point(1, 2);
//
//console.log(p); // Point {x: 1, y: 2} // 用处2 - 为对象添加方法
Object.assign(Point.prototype, {
getX() {
return this.x;
},
setX(x) {
this.x = x;
}
}); let p = new Point(1, 2); console.log(p.getX()); // // 用处3 - 克隆对象
function clone(origin) {
return Object.assign({}, origin);
}
五、Set和Map
// Set里面的成员的值都是唯一的,没有重复的值,Set加入值时不会发生类型转换,所以5和"5"是两个不同的值.
let s = new Set(); [2, 3, 5, 4, 5, 2, 2].map(function(x) {
s.add(x);
}); //for (let i of s) {
// console.log(i);
//} console.log([...s]); console.log(s.size); // 数组去重
function dedupe(array) {
return Array.from(new Set(array));
} console.log(dedupe([1, 2, 2, 3])); // 1, 2, 3
{
// Map类似于对象,也是键值对的集合,但是"键"的范围不限于字符串,各种类型的值(包括对象)都可以当做键.
// 也就是说,Object结构提供了"字符串--值"的对应,Map的结构提供了"值——值"的对象,是一种更完善的Hash结构实现.
var m = new Map();
var o = {
p: 'Hello World'
};
m.set(o, 'content');
m.get(o); // content
m.has(o); // true
m.delete(o); // true
m.has(o); // false
m.set(o, 'my content').set(true, 7).set('foo', 8);
console.log(m);
// Map/数组/对象 三者之间的相互转换
console.log([...m]);
}
六、Iterator和Generator
{
// 是一种接口,为各种不同的数据结构提供统一的访问机制.任何数据结构,只要不输Iterator接口,就可以完成遍历操作.
// 可供for...of循环消费
const arr = ['red', 'green', 'blue'];
let iterator = arr[Symbol.iterator]();
for (let v of arr) {
console.log(v); // red green blue
}
for (let i of iterator) {
console.log(i);
}
// for of 循环可以代替数组对象的forEach方法, 同样可以替代对象的for in循环
}
{
function * foo() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
return 6;
}
for (let v of foo()) {
console.log(v);
}
}
七、Promise和async
{
let getJSON = function (path, param) {
return new Promise(function(resolve, reject) {
let async = typeof param.async == 'undefined' ? true : param.async;
//let deferred = $.Deferred();
param = param || {};
param.data.auth_token = lib.getToken();
window.loading();
$.ajax({
url: path,
data: param.data,
type: 'POST',
dataType: 'json',
async: async,
timeout: 15000,
success: function (data) {
window.unloading();
if (data.code == 0) {
resolve.apply(this, [data]);
} else {
reject.apply(this, [data]);
lib.alert(data.msg, '我知道了');
}
},
error: function (xhr, type) {
window.unloading();
reject.apply(this, ['网络异常, 请稍候再试']);
lib.alert('网络异常, 请稍候再试');
}
});
});
};
getJSON('/xxx.json').then(function(rep) {
}).catch(function(rep) {
});
}
{
function timeout(ms) {
return new Promise(function(resolve) {
setTimeout(resolve, ms);
});
}
async function asyncPrint(value, ms) {
let promise = await timeout(ms);
console.log(value);
}
asyncPrint('Hello world !', 1000);
}
八、class
{
class Point {
static classMethod() {
return 'classMethod...';
}
// constructor方法是类的默认方法,通过new命令生成对象实例时自动调用该方法.
// 一个类必须有constructor方法,如果没有显示定义,一个空的constructor方法会被默认添加
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
get prop() {
return 'getter';
}
set prop(value) {
console.log('setter:' + value);
}
}
// 静态属性的处理,只能用下面这种方式
Point.foo = 1;
console.log(Point.foo); //
// 继承
class ColorPoint extends Point {
constructor(x, y, color) {
// super方法必须被调用, 否则编译不通过
// 如果super在赋值属性this.xx = xx,后边调用,会报错'this' is not allowed before super()
super(x, y);
this.color = color;
}
toString() {
return 'The color is ' + this.color + ' and the point is ' + super.toString();
}
}
var p = new ColorPoint(1, 2, 'red');
console.log(p.toString());
p.prop = 1;
p.prop;
console.log(Point.classMethod());
// 父类的静态方法可以被子类继承
console.log('ColorPoint.classMethod(): ' + ColorPoint.classMethod());
}
九、Module
{
// module
/**
* 优势:
* 1. ES6可以在编译时就完成模块编译,效率要比commonJs模块的加载方式高
* 2. 不再需要UMD模块格式,将来服务器端和浏览器都会支持ES6模块格式.目前,通过各种工具库其实已经做到了这一点
* 3. 将来浏览器的新API可以用模块格式提供,不再需要做成全局变量或者navigator对象的属性
* 4. 不再需要对象作为命名空间(比如Math对象),未来这些功能可以通过模块提供
*/
}
// profile.js
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958; // profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958; export {firstName, lastName, year}; // export命令除了输出变量,还可以输出函数或类(class)。
export function multiply (x, y) {
return x * y;
}; // export输出的变量就是本来的名字,但是可以使用as关键字重命名。 function v1() {
//...
}
function v2() {
//...
} export {
v1 as streamV1,
v2 as streamV2,
v2 as streamLatestVersion
}; // import
// main.js import {firstName, lastName, year} from './profile'; // 重命名
import { lastName as surname } from './profile'; // import命令具有提升效果,会提升到整个模块的头部,首先执行。
foo();
import { foo } from 'my_module'; // 仅仅执行lodash模块,但是不输入任何值。
import 'lodash'; // export default
// 为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。 // export-default.js
export default function () {
console.log('foo');
} // import-default.js
// 需要注意,这时import命令后面,不使用大括号。
import customName from './export-default';
customName(); // 'foo' // export default命令用在非匿名函数前,也是可以的。
// export-default.js
export default function foo() {
console.log('foo');
} // 或者写成 function foo() {
console.log('foo');
} export default foo;
十、编程风格
// 1. let取代var // 2. 全局常量
// 在let和const之间,建议优先使用const,尤其是在全局环境,不应该设置变量,只应设置常量。
// const声明常量还有两个好处,一是阅读代码的人立刻会意识到不应该修改这个值,二是防止了无意间修改变量值所导致的错误。
// 所有的函数都应该设置为常量。 // bad
var a = 1, b = 2, c = 3; // good
const a = 1;
const b = 2;
const c = 3; // best
const [a, b, c] = [1, 2, 3]; // 3. 字符串
// 静态字符串一律使用单引号或反引号,不使用双引号。动态字符串使用反引号。 // 4. 对象
//对象尽量静态化,一旦定义,就不得随意添加新的属性。如果添加属性不可避免,要使用Object.assign方法。
// bad
const a = {};
a.x = 3; // if reshape unavoidable
const a = {};
Object.assign(a, { x: 3 }); // good
const a = { x: null };
a.x = 3; // 对象的属性和方法,尽量采用简洁表达法,这样易于描述和书写。 var ref = 'some value'; // bad
const atom = {
ref: ref, value: 1, addValue: function (value) {
return atom.value + value;
},
}; // good
const atom = {
ref, value: 1, addValue(value) {
return atom.value + value;
},
}; // 5. 数组
//使用扩展运算符(...)拷贝数组。 // bad
const len = items.length;
const itemsCopy = [];
let i; for (i = 0; i < len; i++) {
itemsCopy[i] = items[i];
} // good
const itemsCopy = [...items]; //使用Array.from方法,将类似数组的对象转为数组。 const foo = document.querySelectorAll('.foo');
const nodes = Array.from(foo); // 6. 函数
//不要在函数体内使用arguments变量,使用rest运算符(...)代替。因为rest运算符显式表明你想要获取参数,而且arguments是一个类似数组的对象,而rest运算符可以提供一个真正的数组。 // bad
function concatenateAll() {
const args = Array.prototype.slice.call(arguments);
return args.join('');
} // good
function concatenateAll(...args) {
return args.join('');
} //使用默认值语法设置函数参数的默认值。 // bad
function handleThings(opts) {
opts = opts || {};
} // good
function handleThings(opts = {}) {
// ...
} // 7. 模块
//首先,Module语法是JavaScript模块的标准写法,坚持使用这种写法。使用import取代require。 // bad
const moduleA = require('moduleA');
const func1 = moduleA.func1;
const func2 = moduleA.func2; // good
import { func1, func2 } from 'moduleA'; //使用export取代module.exports。 // commonJS的写法
var React = require('react'); var Breadcrumbs = React.createClass({
render() {
return <nav />;
}
}); module.exports = Breadcrumbs; // ES6的写法
import React from 'react'; const Breadcrumbs = React.createClass({
render() {
return <nav />;
}
}); export default Breadcrumbs
//如果模块只有一个输出值,就使用export default,如果模块有多个输出值,就不使用export default,不要export default与普通的export同时使用。 //不要在模块输入中使用通配符。因为这样可以确保你的模块之中,有一个默认输出(export default)。 // bad
import * as myObject './importModule'; // good
import myObject from './importModule';
//如果模块默认输出一个函数,函数名的首字母应该小写。 function makeStyleGuide() {
} export default makeStyleGuide;
//如果模块默认输出一个对象,对象名的首字母应该大写。 const StyleGuide = {
es6: {
}
}; export default StyleGuide;
希望我所记录的,正是你所想要的。
最后,将这本书的封面放在这里——

【学习笔记】ES6标准入门的更多相关文章
- Hadoop学习笔记(1) ——菜鸟入门
Hadoop学习笔记(1) ——菜鸟入门 Hadoop是什么?先问一下百度吧: [百度百科]一个分布式系统基础架构,由Apache基金会所开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序. ...
- iOS学习笔记-地图MapKit入门
代码地址如下:http://www.demodashi.com/demo/11682.html 这篇文章还是翻译自raywenderlich,用Objective-C改写了代码.没有逐字翻译,如有错漏 ...
- tensorflow学习笔记二:入门基础 好教程 可用
http://www.cnblogs.com/denny402/p/5852083.html tensorflow学习笔记二:入门基础 TensorFlow用张量这种数据结构来表示所有的数据.用一 ...
- spark学习笔记总结-spark入门资料精化
Spark学习笔记 Spark简介 spark 可以很容易和yarn结合,直接调用HDFS.Hbase上面的数据,和hadoop结合.配置很容易. spark发展迅猛,框架比hadoop更加灵活实用. ...
- ES6标准入门之变量的解构赋值简单解说
首先我们来看一看解构的概念,在ES6标准下,允许按照一定模式从数组和对象中提取值,然后对变量进行赋值,这被称作解构,简而言之粗糙的理解就是变相赋值. 解构赋值的规则是,只要等号右边的值不是对象或者数组 ...
- ES6标准入门(第三版)学习笔记(1)
ES6声明变量的六种方法 ES5只有两种 var,function命令 ES6新增了let,const,class,import命令 验证var与let用法上的不同 var a = []; for ( ...
- [转] 《ES6标准入门》读书笔记
来源:https://segmentfault.com/a/1190000005863641 let和const命令 ES6新增let命令,用于声明变量,是块级作用域. let声明的变量不会像var声 ...
- ES6标准入门读书笔记
第一章 基础 1.let和const命令 (1).let用于声明变量,所声明的变量只在当前代码块有效 特点:不存在变量提升 所以在变量声明之前就使用会报错 暂时性死区 只 ...
- 《ES6标准入门》读书笔记 第5章 - 正则增强
第五章 - 正则增强 构造函数增强 允许覆写修饰符,如new RegExp(someRegex, 'ig') 字符串上的正则方法 原先match.replace等可以调用正则的方法在String的原型 ...
随机推荐
- inline-block元素间距
做项目过程中发现元素设置为inline-block后,彼此之间会有间距,有时候不是我们想要的效果,这时候就需要将间距去除掉. 后来上网查了下,已有前人总结了不少好的方法.这里主要借鉴了张鑫旭博客中介绍 ...
- RGW/SWIFT对象存储性能测试工具--COSBench安装
Cosbench是Intel的开源云存储性能测试软件,COSBench目前已经广泛使用与云存储测试,并作为云存储的基准测试工具使用 https://github.com/intel-cloud/cos ...
- 五种开源协议(GPL,LGPL,BSD,MIT,Apache)
什么是许可协议? 什么是许可,当你为你的产品签发许可,你是在出让自己的权利,不过,你仍然拥有版权和专利(如果申请了的话),许可的目的是,向使用你产品的人提供 一定的权限. 不管产品是免费向公众分发,还 ...
- JAVA之IO流(字节流)
输入和输出 JAVA的流分为输入流和输出流两部分, 输入流:InputStream或者Reader:从文件中读到程序中: 输出流:OutputStream或者Writer:从程序中输出到文件中: Re ...
- 使用腾讯开发平台获取QQ用户数据资料
<今天是七夕:祝大家七夕嗨皮,前可么么哒,后可啪啪啪> Tips:本篇博客将教你如何使用腾讯开发平台获取QQ用户资料 ----------------------------------- ...
- java获取当天,前天,明天,本周,本月,本年的开始日期时间和结束日期时间
package demoone; import java.sql.Timestamp; import java.text.ParseException; import java.text.Simple ...
- bzoj 1004 Cards
1004: [HNOI2008]Cards Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有 多少种染色方案,Sun ...
- 要学Java,怎么高效地学习,怎么规划
要学Java,怎么高效地学习,怎么规划? 题主是一个个例,99%的人(包括我自己)都没有题主这样的经历,也很难提出具有很强参考性的java学习建议.我倒是之前面试过一个跟题主有点类似的人,拿出来分 ...
- mysql设置远程访问权限
查一下你的MYSQL用户表里, 是否允许远程连接 1.授权 mysql>grant all privileges on *.* to 'root'@'%' identified by ...
- 使用Nominatim进行openstreetmap地址搜索/解析
Nominatim(来自拉丁语,意思是“名称”)是一个可以按名称和地址来搜索OSM中的数据,并生成OSM点的合成地址的工具(反向地理编码).可用在http://nominatim.openstreet ...