1,let与块级作用域
for(let i =0;i<3;i++){ let i = "foo"; console.log(i)}
打印输出是
它等同于
let i = 0;if (i < 3) { let i = "foo"; console.log(i);}i++;if (i < 3) { let i = "foo"; console.log(i);}i++;if (i < 3) { let i = "foo"; console.log(i);}i++;
2,const
const申明的常量不能批改指的是申明之后的常量不能从新指向一个新的地址,并不是指不能批改成员数据。
最佳实际:不必var,尽量应用const,配合应用let
3,数组
数组解构
const arr = [1, 2, 3]const [a, b, c] = arr;console.log(a, b, c)
打印1,2,3
const arr = [1, 2, 3]const [,,c] = arr;console.log(c)
打印3
const arr = [1, 2, 3]const [a,...rest] = arr;console.log(rest)
打印[2,3]
这里的...
操作符只能放在最初一位应用
const arr = [1, 2, 3]const [a, b, c, d = 4] = arr;console.log(a, b, c, d)
大于数组长度解构,如果不给默认值,会提醒undefined。
4,对象解构
const obj = {name:'a',age:1};const name ="b";const {name:objName} = obj;console.log(name)
当对象解构与定义常量重名时,能够给解构变量重命名objName
。这时候打印的name为b
,程序不会报错。
5,模板字符串
带标签的模板字符串const str = console.log
`how are you`
打印出一个数组
标签就是一个函数。
为什么打印的会是一个数组
const print = (strs)=>{ console.log(strs)}const name1 = 'jim'const name2 = 'tom'const str = print`${name1} how are you,${name2}`
打印
打印内容是模板标签宰割过后的内容,模板标签中可能存在嵌入的表达式,数组其实是依照表达式宰割之后动态的内容,所以是一个数组。模板标签函数还能接管到模板字符串中可能呈现的表达式的返回值
const name1 = 'jim'const name2 = 'tom'const print = (strs,name1,name2)=>{ console.log(strs,name1,name2)}const str = print`${name1} how are you,${name2}`
打印
6,字符串扩大办法
字符串的头尾,中部查找办法startsWith()
,endsWith()
, includes()
.
const str = 'he is a man.'console.log( str.startsWith('he'), str.endsWith('.'), str.includes('is'),)
7,参数默认值
当函数参数是可选参数值。函数体内判断形式应该判断是否是undefined
function foo(para) { para = para === undefined ? true : false}
8,箭头函数与this。
箭头函数内的this始终指向以后作用域。
const person = { name:"tom", say: function (){ console.log(`my name is ${this.name}`) }, arrowSay:()=>{ console.log(`my name is ${this.name}`) }}person.say();person.arrowSay()
打印如下
另一个案例
const person = { name: "tom", asyncSay: function () { setTimeout(function () { console.log(`my name is ${this.name}`) }, (1000)); }, asyncArrowSay: function () { setTimeout(() => { console.log(`my name is ${this.name}`) }, (1000)); }}person.asyncSay();person.asyncArrowSay()
第一行打印是undefinde
是因为setTimeout
内的函数最终会放在全局对象对象下来调用,拿不到以后作用域的对象,拿到的是全局作用域的对象。
个别解决办法是增加一个_this
保留以后this
。借助闭包机制
const _this = this;console.log(`my name is ${_this.name}`)
第二行能打印出tom
是因为以后this
始终指向以后作用域。
9,计算属性名
能够用[]
蕴含用来示意一个动静属性名。
const obj = { [Math.random()]: 1, method() { console.log(this); }}obj.method()
10,Object.assign办法Object.assign()
办法用于合并对象。第一个参数为指标对象,办法的返回值就是指标对象。
const source = { a:1, b:2, } const target = { a:3, c:4 } const result = Object.assign(target,source); console.log(result) console.log(result === target)
这个办法罕用于复制一个对象
11,Object.isObject.is()
用于判断两个对象是否相等
console.log(0 == false, 0 === false, +0 === -0, NaN === NaN, Object.is(+0, -0), Object.is(NaN, NaN))
12,proxy
目前接触的不多。
const person = { name: "tom", age: 18,}const personProxy = new Proxy(person, { // 监听对象拜访 get(target, property) { return property in target ? target[property] : "default" }, // 为代理指标设置属性 set(target, property, value) { if (property === "age") { if (!Number.isInteger(value)) { throw new TypeError(`${value} is not integer`) } } target[property] = value }})personProxy.age = 20personProxy.gender = trueconsole.log(personProxy.name)console.log(personProxy.any)
他比defineProperty更为弱小,后者只能监听对象读写,前者能监听的操作更多
此外还能监听数组变动。
const arr = [];const arrProxy = new Proxy(arr, { set(target, property, value) { console.log("监听到:", property, value); target[property] = value; return true; // 示意设置胜利 }})arrProxy.push(1);arrProxy.push(2)
可能判断出下标
13,for...of循环for...of
循环内能够应用break
关键字,forEach
则不行。for...of
不仅能够遍历数组,还能够遍历伪数组对象
遍历map对象
const m = new Map();m.set('a', 1);m.set('b', 2);for (let i of m) { console.log(i)}//使用数组构造办法for (let [key, value] of m) { console.log(key, value)}
14,生成器Generator
实现一个发号器
//惰性执行function * createidMaker(){ let id = 1; while(true){ yield id++; }}const idMaker = createidMaker();console.log(idMaker.next());console.log(idMaker.next().value);console.log(idMaker.next().value);console.log(idMaker.next().value);console.log(idMaker.next().value);
应用Generator
函数实现iterator
办法
const obj = { value: [1, 2, 3], english: ['a', 'b', 'c'], word: ['一', '二', '三'], [Symbol.iterator]: function* () { const all = [...this.value, ...this.english, ...this.word] for (const item of all) { yield item } }}for (const item of obj) { console.log(item)}
15,ES2016includes()
办法
用于数组查找,indexOf
办法无奈查找NaN
const arr = ['a',1,NaN,false]console.log(arr.indexOf('a'));console.log(arr.indexOf(NaN));console.log(arr.indexOf(false));console.log(arr.includes(NaN))
指数运算符
console.log(Math.pow(2, 10));console.log(2 ** 10)
16,ES2017Object
扩大办法
const obj = { a: 1, b: 2}//Object.values() 对象值汇合console.log(Object.values(obj))// Object.entries()数组办法返回对象中的键值对,转换成Map构造console.log(Object.entries(obj))for (let [key, value] of Object.entries(obj)) { console.log(key, value)}console.log(new Map(Object.entries(obj)))
String.property.padStart,String.property.padEnd
当打印对象时,因为长度不一样,看起来不统一。
// String.property.padStart,String.property.padEndconst person = { tom: 5, jerry: 16, williams: 120}for (let [name, age] of Object.entries(person)) { console.log(name, age)}console.log('String.property.padStart,String.property.padEnd')console.log('用给定的字符串来填充指标字符串的开始和完结地位')for (let [name, age] of Object.entries(person)) { // padEnd固定字符15个长度,空白地位用-填充 console.log(`${name.padEnd(15,'-')} | ${age.toString().padStart(3,'0')}`)}