05.Es6入门学习笔记(阮一峰教程)

Es6学习笔记

一、let和const


1. let,const不存在变量提升,只在声明所在的块级作用域中有效。
var tmp = 123
if(true)
{
    let tmp = 'abc'
    console.log(tmp)
}
console.log(tmp)
2. Es5只有全局作用域和函数作用域,Es6添加了块级作用域
3. 考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句。
4. 对于复合类型的变量,变量指向数据所在的地址,不保证该地址的数据不变,所以在将对象声明为常量时必须特别小心。
const foo = {name:'zhangsan'}
foo.age = 18
console.log(foo) // Object { name: "zhangsan", age: 18 }
5.let, const, class定义的全局变量与顶层对象脱钩

二、变量的解析赋值


1. 对象的解析赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。如:
var {foo:bar, bar:foo} = {foo:'hello', bar:'world'}
console.log(foo, bar) // 输出world hello

解析过程:先找到变量foo,其值为bar,将后面bar对应的值'world'赋给了foo。

2. 解析也可用于嵌套结构的对象,如
var obj = {p: ['hello', {y: 'world'}]}
var {p:[x, {y}]} = obj
console.log(x, y) // hello world

注意这里的p是模式,不是变量,因此不会被赋值

let node = {loc: {start: {line: 1, column: 5}}}
let {loc: { start: {line, column}}} = node
console.log(line, column) // 1, 5

这里loc和start都是模式,不会被赋值

3. 对象的解析赋值,可以很方便的将现有对象的方法,赋值到某个变量,如
let {log, sin, cos} = Math

上面代码将Math的对数,正弦,余弦三个方法赋值到了对应的变量上,使用起来就会方便很多。

4. 圆括号问题,解析赋值解析圆括号时很麻烦,只要由可能,就不要在模式中放置圆括号。另外:
* 变量声明语句中,不能带有圆括号
* 函数参数中,模式不能带有圆括号
* 赋值语句中,不能将整个模式,或嵌套模式中的一层,放在圆括号中

三、字符串的扩展


1. JS内部,字符以UTF-16的格式存储,每个字符固定为2个字节。对于那些需要4个字节存储的字符(Unicode码大于0xFFFF的字符),JS会认为它们是两个字符。
2. Es6提供的codePointAt方法,直接使用时参数也不能正确识别,如下面的字符串中,a的位置应该是1,但必须传入2才能取到字符,解决的办法是使用for...of循环,它能正确识别32位的UTF-16字符。
var s = "𠮷a"
console.log(s.codePointAt(0)) // 134071
console.log(s.codePointAt(1)) // 57271
console.log(s.codePointAt(2)) // 97
console.log(s.codePointAt(0).toString(16)) // 20bb7
console.log(s.codePointAt(2).toString(16)) // 61
for(let ch of s)
{
  console.log(ch.codePointAt(0).toString(16))// 20bb7  61
}
3. Es6中提供了另外操作32位的UTF-16的函数:String.fromCodePoint(), at(), includes(), startsWith(), endsWith()如
console.log(String.fromCodePoint(0x20BB7))

let s = 'Hello World!'
console.log(s.includes('W')) // true
console.log(s.startsWith('H')) // true
console.log(s.endsWith('d')) // false

当前的FireFox50.1和最新的360极速浏览器(内核为Chromium50.0.2661.102)均不支持at()函数

4.模板字符串
var s = `<span>这是一个
  模板字符串!
  </span>
`
console.log(s)

四、数值


1. 二进制和八进制的表示法分别使用前缀0b/0B和0o/0O。
2. 新的函数Number.isFinite(), Number.isNaN(), Number.parstInt(), Number.parseFloat(), Number.isInteger(),
console.log(Number.isInteger(3)) // true
console.log(Number.isInteger(3.0)) // true

在JS内部,整数和浮点数是同样的存储方法,所以3和3.0被视为同一个值。

3. 安全整数检测Number.isSafeInteger(), Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER。
console.log(Number.MAX_SAFE_INTEGER) // 9007199254740991
console.log(Number.MIN_SAFE_INTEGER) // -9007199254740991

在使用Number.isSafeInteger()时,不能只验证运算结果,而要同时验证参与运算的每个值。

4. ES6在Math对象上新增了17个与数学相关的方法。

五、数组


1. Array.from()用于将类似数组的对象(含有length属性)和可遍历的对象(包括ES6新增的数据结构Set和Map)转换为数组
let a = {'0':1, '1':2, '2':3, 'length':3}
console.log(Array.from(a)) // [1, 2, 3]
console.log([].slice.call(a)) // [1, 2, 3]

let s = new Set(['a', 'b', 'c'])
console.log(Array.from(s)) // ["a", "b", "c"]
2. Array.of()用来将一组值转换为数组,主要目的是弥补Array()和new Array()由于参数的不同导致的行为的差异,如
console.log(Array.of()) // []
console.log(Array.of(3)) // [3]
console.log(Array.of(3, 4)) // [3, 4]
console.log(Array()) // []
console.log(Array(3)) // [ , , ,]三个空的存储位置
console.log(Array(3, 4)) // [3, 4]
console.log(new Array()) //[]
console.log(new Array(3)) // [ , , , ]三个空的存储位置
console.log(new Array(3, 4)) // [3, 4]
3. 数组实例的copyWithin(),在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员)。
console.log([1,2,3,4,5].copyWithin(0, 3,4)) // 4,2,3,4,5
4. 数组实例的find()和findIndex()函数
console.log([1, 4, -2, 5].find((n) => n < 0))
5. 数组实例的includes()函数
console.log([1, 2, 3].includes(2))

同Set结构的has()方法一样,数组的includes()函数是用来查找值的;而Map结构的has()方法是用来查找键名的。

6. 由于空位的处理规则非常不统一,所以要避免出现空位的情况。

六、函数


1. 函数默认值
function log(x=0, y=0)
{
  console.log(x, y)
}
log()
2. 函数的length属性,表示该函数预期传入的参数个数。如果参数有默认值,则length不包含这个参数。同理,rest参数也不会计入length属性
3. 如果将参数默认值设为undefined,表明这个参数是可以省略的。
function foo(bar = undefined){......}
4. rest参数,形式为“...变量名“,用于获取函数的多余参数,这样就不需要使用arguments对象了。
function add(...args)
{
  let sum = 0;
  for(let v of args)
  {
    sum += v;
  }
  console.log(sum)
}
add(2,3,4)
5. 扩展运算符“...” ,它的作用是将一个数组转为用逗号分隔的参数序列。
console.log(...[1, 2, 3])

扩展运算符内部调用的是数据结构的Iterator借口,因此只要具有Iterator接口的对象,都可以使用扩展运算符,比如Map结构。

let map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
])
console.log(...map.values()) // one two three
6. 箭头函数
var f = v => console.log(v);
f('hello world')
等价于
var f = function(v){
  console.log(v);
}

let f = n => n % 2 == 0;
等价于
let f = function(n)
{
  return n % 2 == 0
}

如果没有参数,或多个参数,就使用一个圆括号代表参数部分

var f = (name) => console.log('hello' + name)
f('world!')

var f = (string, name) => console.log(string + " " + name)
f('hello', 'world!')

感觉添加一个小括号比较好,这样可以统一起来

7.箭头函数中的this,指向固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。
function foo()
{
  return () => {
    return () => {
      return () => {
        console.log('id:', this.id)
      }
    }
  }
}
var f = foo.call({id:1})
var t1 = f.call({id:2})()()
var t2 = f().call({id:3})()
var t3 = f()().call({id:4})

上面的代码中,只有一个this,就是函数foo的this,所以t1,t2,t3输出同样的结果,因为内部所以的箭头函数都没有自己的this,他们的this实际都是最外层foo函数的this。

长期以来,Js的this对象一直都是一个令人头疼的问题,在对象方法中使用this,必须非常小心,箭头函数“绑定”this,很大程度上解决了这个困扰。

7.尾调用优化和尾递归

七、对象,允许使用变量和函数,作为对象的属性和方法


1.简洁表示法
let birthday = '2010/10/10'
let Person = {
  name: '张三',
  birthday,
  happy() {console.log('Happy Birthday ' + this.name)}
}
Person.happy()
2.判断两个值是否相等使用Object.is()
3.Object.assign()方法用于对象的合并,将源对象source的所有可枚举属性,复制到目标对象target。
var target = {a: 1}
var source1 = {b: 2}
var source2 = {c: 3}
console.log(Object.assign(target, source1, source2))

var target = {a:{b:'222', d:'333'}}
var source = {a:{b:'hello'}}
console.log(Object.assign(target, source)) // {a: {b: 'hello'}}

如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性

Object.assign方法是浅拷贝,如果源对象某个属性的值是对象,则目标对象拷贝得到的是这个对象的引用。

Object.assign()的用途

  • 为对象添加属性
  • 为对象添加方法
  • 克隆对象
  • 合并多个对象
  • 为属性指定默认值
4.遍历对象 Object.keys, Object.values, Object.entries
5.扩展运算符
let clone = {...a}
等价于
let clone = Object.assign({}, a)

八、Set和Map


1. Set类似于数组,但它的成员值都是唯一的。
* keys():返回键名的遍历器
* values():返回键值的遍历器
* entries():返回键值对的遍历器
* forEach():使用回调函数遍历每个成员
> 扩展运算符...内部使用for...of循环,所以也可以用于Set结构

九、一些不常用的功能


1. SIMD(Single Instruction/Multiple Data),即单指令,多数据

它是JS操作CPU对应指令的接口,可以使用一个指令,完成多个数据的运算,所以被广泛用于3D图形运算、物理模拟等运算量超大的项目之中。
SIMD是数据并行处理(parallelism)的一种手段,可以加速一些运算密集型操作的速度。

十、编程风格


1. let和const
  • let取代var
  • 所有的函数都应该设置为常量
  • 长远来看,JS可能会有多线程的实现,let表示的变量,这时let表示的变量,只应出现在单线程运行的代码中,不能是多线程共享的,这样有利于保证线程安全。
2. 字符串
  • 静态字符串一律使用单引号或反引号,不使用双引号
  • 动态字符串使用反引号
3.解构赋值
  • 使用数组成员对变量赋值时,优先使用解构赋值
  • 函数的参数如果是对象的成员,优先使用解构赋值
function getFullName({firstName, lastName}){ }
  • 如果函数返回多个值,优先使用对象的解构赋值,而不是数组的解构赋值
function getInput(input) {
    return { left, right, top, bottom};
}
4. 对象
  • 单行定义的对象,最后一个成员不以逗号结尾。多行定义的对象,最后一个成员以逗号结尾
  • 对象尽量静态化,一旦定义,就不得随意添加新的属性。如果添加属性不可避免,要使用Object.assign方法
  • 如果对象的属性名是动态的,可以在创造对象的时候,使用属性表达式定义。
const obj = {
    id: 5,
    name: 'Tom',
    [getKey('enabled')]: true,
};
5.数组
  • 使用扩展运算符(...)拷贝数组
  • 使用Array.from方法,将类似数组的对象转为数组
6.函数
  • 立即执行函数可以写成箭头函数的形式
(() => {
    console.log(' Hello World');
})();
  • 简单的、单行的、不会复用的函数,建议采用箭头函数。如果函数体较为复杂,行数较多,还是应该采用传统的函数写法
7. Map和Object
  • 只有模拟现实世界的实体对象时,才使用Object。如果只是需要key : value的数据结构,使用Map结构。因为Map有内建的遍历机制

8. 使用ESLint

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

推荐阅读更多精彩内容

  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,151评论 0 4
  • 三,字符串扩展 3.1 Unicode表示法 ES6 做出了改进,只要将码点放入大括号,就能正确解读该字符。有了这...
    eastbaby阅读 1,442评论 0 8
  • 从大哥大到单色屏,从彩色屏幕到智能手机,手机的变得轻薄,外观也随着人们的需求变大变小。仅仅是通讯功能的手机早已不能...
    onecharlotte阅读 358评论 0 0
  • 真心觉得简述里能学的知识挺多的,之前看了关于自学英语的,可是还是不得要领,文章太多眼花缭乱,我们机械老师说的对,对...
    惜灬月阅读 330评论 1 0