let
1.作用域在代码快中 外部无法获取let声明的变量
2.不存在变量提升 var声明变量前 输出变量undefined let声明变量前输出变量 直接报错
3.let const 这个区块声明变量 从一开始就形成了封闭作用域 凡是在声明之前使用这些变量 就会报错
也就是说 在let命令声明变量之前 该变量都是不可用的 语法上称为‘暂时性死区’
4.typeof a a是不存在的变量 // undefined
如果 typeof在死区内 也就是 typeof b let b = 1 typeof直接报错
5.不允许重复声明同一个变量 也不能在函数内部重新声明 参数名和函数体内let的变量名 不能相同
ES6的块级作用域
1.let实际上为js新增了块级作用域
2.{{{{{{作用域可以任意嵌套 let a = 1}} 外层作用域无法读取内层作用域的变量 console.log(a) // 报错}}}}}
外层作用域可以定义内层同名变量
不再需要立即执行函数表达式 (function(){}())
3.ES6函数声明和let类似 允许块级作用域声明函数
函数调用也只会在当前自己的作用域内找声明的函数调用
找不到就找外层的 不会找不相干的层
const命令
1.const只读 常量不能改变
const必须赋值 只声明会报错
并且之后不能重复赋值 不可重复声明
只在作用域内有效
ES6共有6种声明方式
var let const import class function
顶层对象的属性
浏览器环境中指的是window对象 node环境中指的是global对象
var function 声明全局变量 等同于window.变量名
let const class不是
global 对象
es5 顶层对象 浏览器中是window
浏览器和web Worker 里 self也指向顶层对象 但是Node没有self
Node 顶层对象是global 但其它环境都不支持
没看懂
数组的解构赋值
按照一定模式从数组和对象中提取值 对变量进行赋值 被称为结构
let [a,b,c] = [1,2,3]
上面代码表示从数组中提取值 按照对应位置 对变量赋值
本质上属于’模式匹配‘ 只要等号两边的模式相同 左边的变量就会被赋予对应的值
let [foo, [[bar], baz]] = [1,[[2],3]] //一一对应
let [, , third] = ['foo','bar','baz'] //third baz
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefinedz // []
结构不成功 变量的值就是undefined
...z 没有时为空数组 ...是数组
不完全解构
let [x, y] = [1, 2, 3];
x // 1y // 2
let [a, [b], d] = [1, [2, 3], 4];
a // 1b // 2d // 4
按照结构赋值
let [x,y,z] = new Set(['a','b','c'])
x //a
set解构也可以使用数组解构赋值
解构赋值允许指定默认值
let [foo = true] = []
foo // true
let [x,y='b'] = ['a'] // x = 'a' y = 'b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
赋值 === undefined默认才会生效
赋值null则默认不生效 =号左侧被赋值null
有默认值的情况下 赋值的过程
先按照结构 = 右侧向左侧赋值 当右侧!== undefined时赋值成功 否则是默认值 默认值如果是变量 未被声明会报错
function f() { console.log('aaa');}
let [x = f()] = [1];
解构赋值过程
let x;if ([1][0] === undefined)
{ x = f();}
else { x = [1][0];}
对象的解构赋值
与数组的不同之处 数组的元素是按照次序排列的 变量取值由位置决定 而对象的属性没有次序 变量必须与属性同名才能取到正确的值
对象赋值是先找到对应的属性 对属性值进行赋值
对象也可以指定默认值 ===undefined 默认值生效
let {foo} = {bar: 'bar'} 解构失败 foo//undefined
let {foo: {bar}} = {baz: 'baz'}; 属性不存在 取子属性会报错
由于数组本质是特殊对象 因此可以对数组进行对象属性的解构
let arr = [1,2,3,]
let {0:first, [arr.length-1]: last} = arr
first // 1
last //3
索引相当于是属性名
字符串的结构赋值
字符串会被转换成一个类似数组的对象
const [a,b,c,d,e] = 'hello'
类似数组的对象都有一个length属性 因此还可以对这个属性解构赋值
let {length: len} = 'hello'
len //5
数值和布尔值的解构赋值
数值和布尔值会转为对象
let {toString: s} = 123
s === Number.prototype.toString // true
相当于 123变成了Number对象 s是toString 这个方法
let {toString: s} = true;
s === Boolean.prototype.toString // true
同上 被转换成了Boolean对象 s为方法
解构赋值的规则是 只要等号右边的值不是对象或数组就将其转换为对象
undefined 和 null 无法转为对象 所以对他们进行解构赋值 都会报错
函数参数的结构赋值
function add([x,y]) {
return x + y
}
add([1,2]) // 3
圆括号的问题
建议不要再模式中放置圆括号
不能使用圆括号的情况
(1) 变量的声明语句
let [(a)] = [1] 报错
(2) 函数参数
函数参数也属于变量声明 因此不能带有圆括号
(3)赋值语句的模式
({p: a}) = {p: 42} 报错
圆括号不是很理解 奇奇怪怪
用途
(1)交换变量
let x = 1
let y = 2
[x,y ] = [y,x]
(2)从函数返回多个值
function example() {
return [1,2,3];
}
let [a,b,c] = example()
function example() {
return {
foo: 1,
bar: 2
}
}
let {foo, bart} = example()
(3)函数参数的定义
解构赋值可以方便的将一组参数与变量名对应起来
// 参数是一组有次序的值function f([x, y, z]) { ... }f([1, 2, 3]);
// 参数是一组无次序的值function f({x, y, z}) { ... }f({z: 3, y: 2, x: 1});
(4)提取json数据
解构赋值对提取json对象中的数据尤其有用
let jsonData = {
id: 42,
status:'OK',
data: [867,5309]
}
let {id, status, data: number} = jsonData;
(5)函数参数的默认值
(6)遍历Map结构
const map = new Map()
map.set('first','hello')
map.set('second','world')
字符串的拓展
for of 遍历字符串
let str = 'abc'
for(let v of str) {
` console.log(v)
}
// a
// b
// c
at()
‘abc’.at(0) // a
浏览器支持度不高 建议还是使用charAt()
includes() 返回布尔 表示是否找到了参数字符串
startsWith() 返回布尔 表示参数字符串是否在原字符串头部
endsWith() 返回布尔 表示参数字符串是否在原字符串尾部
第二个参数标识开始搜索的位置
let s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false
上面代码表示,使用第二个参数n时,endsWith的行为与其他两个方法有所不同。它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束。
repeat() 返回一个新字符串 标识将原字符串重复n次
‘x’.repeat(3) ‘xxx’
'hello'.repeat(2) 'hellohello'
'na'.repeat(0) ''
参数如果是小数点会被取整
‘na’.repeat(2.9) 'nana'
参数为负数或Infinity 会报错
参数在0-1和 0到-1之间 以及 NaN等同于0
如果参数是字符串 会被转换成数字
‘na’.repeat('na') '' //'na'转换为字符串是NaN所以结果是‘’
'na'.repeat('3') // 'nanana'
padStart 常见用途 为数值补全指定位数
下面代码生成10位
‘1’.padStart(10,'0') // 0000000001
'12'.padStart(10,'0') // 0000000012
‘123456’.padStart(10, '0') //0000123456
另一个用途 提示字符串格式
‘12’.padStart(10, 'YYYY-MM-DD') // 'YYYY-MM-12'
'09-12'.padStart(10, 'YYYY-MM-DD') // YYYY-09-12
数组的扩展 扩展运算符
主要用于函数调用
扩展运算符的应用
复制数组
const a1 = [1,2]
const a2 = [...a1]
或
const [...a2] = a1
合并数组
[1,2].concat(more)
[1,2,...more]
[...arr1, ...arr2, ...arr3]
扩展运算符用于数组赋值 只能放在参数最后一位 否则会报错
字符串转换数组
[...'hello']
// ['h','e','l','l','o']
Map 和 Set 结构
映射 和 集合 // 不是很懂
Array.from()
将类似数组的对象和可遍历的对象(包括Map和Set)转为数组
let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3};
Array.from(arrayLike) ['a', 'b', 'c']
NodeList对象[...document.querySelectorAll('div')]
直接得到一个NodeList集合
Array.from(NodeList) 转换为真正的数组
可以将字符串转换为数组
let str = 'sdfsdf35165'
Array.from(str)
// ['s', 'd', 'f'....]
Array.of() 返回参数组成的数组
Array.of() // []
Array.of(undefined) //[undefined]
Array.of(1) // [1]
find() 找到第一个符合条件的数组成员
参数为回调 第一个满足回调返回true的成员 返回该成员
[1,4,-5,10].find(n => {n<0}) // -5
回调有三个参数 value 当前值 index 当前索引 arr 原数组 ↓
[1, 5, 10, 15].find(function(value, index, arr) { return value > 9; }) // 10
findIndex 与find类似 返回索引
这两个方法 可以接受第二个参数 find(f,person) 回调中的this指向第二个参数
function f(v){ return v > this.age; } let person = {name: 'John', age: 20}; [10, 12, 26, 15].find(f, person); // 26
fill() 给定值填充一个数组
['a','b','c'].fill(7) // [7,7,7]
new Array(3).fill(7) // [7,7,7]
还可以接受第二第三个参数 起始位置和结束位置(包头不包尾)
[‘a’, 'b', 'c'].fill(7,1,2) // ['a', 7, 'c']
如果参数类型是对象 那么被赋值的是同一个内存地址的对象 而不是深拷贝的对象
let arr = new Array(3).fill({name: "Mike"});
arr[0].name = "Ben"; arr
// [{name: "Ben"}, {name: "Ben"}, {name: "Ben"}] l
et arr = new Array(3).fill([]);
arr[0].push(5); arr // [[5], [5], [5]]
entries() keys() values()
遍历数组 键值对遍历 键遍历 值遍历
[1, 2, 3].includes(2) 返回布尔
数组的空位ES6方法会解析成undefined
Object.is()
类似于全等 ===
区别在于 全等 +0 === -0 // true
Object.is(+0, -0) // false
全等 NaN === NaN // false
Object.is(NaN, NaN) // true
对象的合并 Object.assign()
第一个参数 目标对象 后面都是源对象
如果有同名属性 后面的会覆盖前面的
const target = { a: 1, b: 1 }; const source1 = { b: 2, c: 2 }; const source2 = { c: 3 }; Object.assign(target, source1, source2); target // {a:1, b:2, c:3}
如果只有一个参数 会直接返回该参数
如果该参数不是对象则会转成对象 然后返回
undefined和null做参数 会报错
如果undefined和null不在第一个参数位置 则不会报错
字符串做参数 会以数组的形式拷贝入对象 数值和布尔 没效果
const v1 = 'abc';
const v2 = true;
const v3 = 10;
const obj = Object.assign({}, v1, v2, v3);
console.log(obj); // { "0": "a", "1": "b", "2": "c" }
Object.assign() 拷贝的属性是有限的 只拷贝源对象自身属性 不拷贝继承属性 不拷贝不可枚举属性
注意点
Object.assgin()实现的是浅拷贝 拷贝的是对象的引用
同名属性会替换
数组视为对象
Object.assign([1, 2, 3], [4, 5])
// [4, 5, 3]
数组视为对象则是索引做键值做值的对象
所以4在0的位置 会覆盖1 ,5覆盖2
函数的处理
Object.assign()参数如果有函数 则是先运行只会拿到值再复制
常见用途
ES6的遍历
for...in 遍历对象自身和继承的可枚举属性
Object.keys(obj) 返回一个数组 包含对象自身可枚举属性不含继承的键名
Object.getOwnPropertyNames(obj)
返回一个数组 包含对象自身所有属性 包含不可枚举属性的键名
ES6
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...