1.let 与块级作用域
JS中作用域有:全局作用域、函数作用域。没有块作用域的概念。ECMAScript 6(简称ES6)中新增了块级作用域。 块作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。
var elements = [{}, {}, {}];
for (var i=0; i < elements.length; i++) {
elements[i].onclick = function() {
console.log(i);
}
}
elements[1].onclick();
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
3
3
3
1.1 通过闭包
var elements = [{}, {}, {}];
for (var i = 0; i < elements.length; i++) {
elements[i].onclick = (function (i) {
return function () {
console.log(i);
}
})(i)
}
elements[0].onclick();
elements[1].onclick();
elements[2].onclick();
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
0
1
2
1.2 使用let
var elements = [{}, {}, {}];
for (let i = 0; i < elements.length; i++) {
elements[i].onclick = function () {
console.log(i);
}
}
elements[0].onclick();
elements[1].onclick();
elements[2].onclick();
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
0
1
2
2. 数组的解构
const arr = [100,200,300];
const [a,b,c] = arr;
console.log(a,b,c);
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
100 200 300
2.1 只定义一个变量 需要 把其它位置空出来
const arr = [100,200,300];
const [,,c] = arr;
console.log(c);
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
300
2.2 使用...定义剩下的变量
只能定义在最后的位置
const arr = [100,200,300];
const [a, ...rest] = arr;
console.log(rest);
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
[ 200, 300 ]
const arr = [100,200,300];
const [...rest] = arr;
console.log(rest);
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
[ 100, 200, 300 ]
const arr = [100,200,300];
const [...rest,c] = arr;
console.log(rest);
////
F:\拉钩前端\lagou\task1\task1.js:15
const [...rest,c] = arr;
^^^^^^^
2.3 解构的时候赋初始值
const arr = [100, 200, 300];
const [a, b, c = 123, d = 'defaultValue'] = arr;
console.log(c, d);
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
300 defaultValue
2.4 解构实例:解析路径
//传统写法
const path = '/foo/bar/baz';
const temp = path.split('/');
const rootdir = temp[1];
console.log(temp);
console.log(rootdir);
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
[ '', 'foo', 'bar', 'baz' ]
foo
//解构写法
const path = '/foo/bar/baz';
const [,rootdir] = path.split('/');
console.log(rootdir);
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
foo
3.对象的解构
3.1 对象是通过key,数组是通过下标
const obj = {name:'yangzhen' , age:24};
const { name , age , sex } = obj;
console.log(sex,name,age);
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
undefined yangzhen 24
3.2 不使用别名
const obj = {name:'yangzhen' , age:24};
const name = 'jack';
const { name , age , sex } = obj;
console.log(sex,name,age);
////
const { name , age , sex } = obj;
^
SyntaxError: Identifier 'name' has already been declared
3.3 使用别名 赋初始值
const obj = {name:'yangzhen' , age:24};
const name = 'jack';
const { name:myname , age , sex = 18 } = obj;
console.log(sex,myname,age);
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
18 yangzhen 24
4.字符串的扩展方法
const { log } = console
const message = 'Error: foo is noe defined.'
log (
message.startsWith('Error'),
message.endsWith('.'),
message.includes('is')
)
////
true true true
5.函数参数的默认值
5.1 原始方法(对于布尔类型)
//函数参数的默认值
function foo(enable) {
//原始方法(对于布尔类型)
enable = enable === undefined ? true : false
console.log(enable)
}
foo() //// true
foo(false) //// false
5.2 原始方法(对于其它类型)
//函数参数的默认值
function foo(enable) {
//原始方法
enable = enable || 0
console.log(enable)
}
foo() //// 0
foo(5) //// 5
5.3 ES6语法
function foo(enable = true){
console.log(enable)
}
foo() //// true
foo(false) //// false
6.剩余参数
6.1 方式一:使用arguments
function foo(){
console.log(arguments)
}
foo(1,2,3,4)
////
PS E:\lagou前端\demo> node .\part1\test1.js
[Arguments] { '0': 1, '1': 2, '2': 3, '3': 4 }
function foo(){
const [a,b,c,d] = arguments
console.log(a,b,c,d)
}
foo('a',2,3,4)
////
PS E:\lagou前端\demo> node .\part1\test1.js
a 2 3 4
6.2 方式二:使用...
...args放在最后 只能使用一次
function foo(first,...args){
console.log(first)
console.log(args)
}
foo('a',2,3,4)
////
PS E:\lagou前端\demo> node .\part1\test1.js
a
[ 2, 3, 4 ]
6.3 ···展开数组
const arr = [1,2,3,4]
console.log(...arr)
////
PS E:\lagou前端\demo> node .\part1\test1.js
1 2 3 4
7.箭头函数与this
普通函数:this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁,一定要搞清楚这个。
箭头函数没有prototype(原型),所以箭头函数本身没有this。箭头函数内部的this是词法作用域,由上下文确定,this指向在定义的时候继承自外层第一个普通函数的this。函数体内的this对象,就是定义时所在的对象,与使用时所在的对象无关。
const name = 'jack'
const person = {
name: 'tom',
sayHi: function(){
console.log(`my name is ${this.name}`)
}
}
person.sayHi()
////
PS E:\lagou前端\demo> node .\part1\test1.js
my name is tom
const name = 'jack'
const person = {
name: 'tom',
sayHi: function(){
console.log(`my name is ${name}`)
}
}
person.sayHi()
////
PS E:\lagou前端\demo> node .\part1\test1.js
my name is jack
7.1 使用箭头函数
箭头函数不会改变this的指向
const name = 'jack' //// 这个name 并不是this.name
const person = {
name: 'tom',
sayHi: () => {
console.log(`my name is ${this.name}`)
}
}
person.sayHi()
////
PS E:\lagou前端\demo> node .\part1\test1.js
my name is undefined
const name = 'jack'
const person = {
name: 'tom',
sayHi: () => {
console.log(`my name is ${name}`)
}
}
console.log(this)
console.log(this.name)
person.sayHi()
////
PS E:\lagou前端\demo> node .\part1\test1.js
{}
undefined
my name is jack
7.2 传统方式_this的使用
const person = {
name: 'tom',
sayHi: function() {
console.log(`my name is ${this.name}`)
},
sayHiAsync:function(){
setTimeout(function () {
console.log(`my name is ${this.name}`)
}, 1000);
}
}
person.sayHi()
person.sayHiAsync()
////
PS E:\lagou前端\demo> node .\part1\test1.js
my name is tom
my name is undefined
const person = {
name: 'tom',
sayHi: function() {
console.log(`my name is ${this.name}`)
},
sayHiAsync:function(){
_this = this;
setTimeout(function () {
console.log(`my name is ${_this.name}`)
}, 1000);
}
}
person.sayHi()
person.sayHiAsync()
////
PS E:\lagou前端\demo> node .\part1\test1.js
my name is tom
my name is tom
7.3 setTimeout使用箭头函数 可以避免_this
箭头函数内部的this是词法作用域,由上下文确定
const person = {
name: 'tom',
sayHi: () => {
console.log(`my name is ${this.name}`)
},
sayHiAsync:function(){
setTimeout(()=> {
console.log(`my name is ${this.name}`)
}, 1000);
}
}
person.sayHi()
person.sayHiAsync()
////
PS E:\lagou前端\demo> node .\part1\test1.js
my name is undefined
my name is tom
8.对象字面量增强
const bar = '345'
const obj = {
foo: 123,
//bar:bar
bar,
//method1:function(){
// console.log(this)
//}
method1(){
console.log(this)
},
[Math.random()]:456 // 可以直接增加
}
//在传统方法中,对象动态的增加属性
obj[Math.random()] = 123
console.log(obj)
obj.method1()
////
PS E:\lagou前端\demo> node .\part1\test1.js
{
foo: 123,
bar: '345',
method1: [Function: method1],
'0.8616180359346404': 123
}
{
foo: 123,
bar: '345',
method1: [Function: method1],
'0.8616180359346404': 123
}
9.对象扩展方法
9.1 Object.assign 将多个源对象中的属性复制到目标对象
const source1 = {
a:123,
b:123
}
const source2 = {
b:789,
d:789
}
const target = {
a:456,
c:456
}
const result = Object.assign(target,source1,source2)
console.log(target)
console.log(result === target)
////
PS E:\lagou前端\demo> node .\part1\test1.js
{ a: 123, c: 456, b: 789, d: 789 }
true
9.2 案例
function func(obj){
obj.name = 'func obj'
console.log(obj)
}
const obj = {name: 'global obj'}
func(obj)
console.log(obj)
////
{ name: 'func obj' }
{ name: 'func obj' }
function func(obj){
const funObj = Object.assign({},obj)
funObj.name = 'func obj'
console.log(funObj)
}
const obj = {name: 'global obj'}
func(obj)
console.log(obj)
////
{ name: 'func obj' }
{ name: 'global obj' }
10. Proxy代理对象
const person = {
name: 'yang',
age: 18
}
//参数1:代理对象
//参数2:代理的处理对象
const personProxy = new Proxy(person,{
//通过get方法去监视属性访问
//参数1:所代理的目标对象
//参数2:外部所访问的属性名
get(target,property){
console.log(target,property)
return 100
},
//通过set方法去完成属性设置
set(){
}
})
console.log(personProxy.name)
////
PS E:\lagou前端\demo> node .\part1\test1.js
{ name: 'yang', age: 18 } name
100
const person = {
name: 'yang',
age: 18
}
//参数1:代理对象
//参数2:代理的处理对象
const personProxy = new Proxy(person,{
//通过get方法去监视属性访问
//参数1:所代理的目标对象
//参数2:外部所访问的属性名
get(target,property){
return property in target ? target[property] : 'default'
},
//通过set方法去完成属性设置
set(){
}
})
console.log(personProxy.name)
console.log(personProxy.xxxx)
////
PS E:\lagou前端\demo> node .\part1\test1.js
yang
default
const person = {
name: 'yang',
age: 18
}
//参数1:代理对象
//参数2:代理的处理对象
const personProxy = new Proxy(person,{
//通过get方法去监视属性访问
//参数1:所代理的目标对象
//参数2:外部所访问的属性名
get(target,property){
return property in target ? target[property] : 'default'
},
//通过set方法去完成属性设置
//1.所代理的目标对象
//2.要写入的属性名
//3.要写入的值
set(target,property,value){
if(property === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError(`${value} is not an int`)
}
}
target[property] = value
}
})
personProxy.age = 30
personProxy.sex = 'man'
console.log(personProxy)
////
PS E:\lagou前端\demo> node .\part1\test1.js
{ name: 'yang', age: 30, sex: 'man' }
11.proxy 和 Object.defineProperty()
11.1 Object.defineProperty()只能监听对象的读写
const person = {
name: 'yang',
age: 18
}
const personProxy = new Proxy(person,{
deleteProperty(target,property){
console.log('delete',property)
delete target[property]
}
})
delete personProxy.age
console.log(person)
////
PS E:\lagou前端\demo> node .\part1\test1.js
delete age
{ name: 'yang' }
11.2 proxy 更好的支持数组对象的监视
const list = []
const listProxy = new Proxy(list,{
set(target,property,value) {
console.log('set',property,value)
target[property] = value
return true //表示设置成功,不写会报错
}
})
listProxy.push(100)
listProxy.push(200)
console.log('list',list)
////
PS E:\lagou前端\demo> node .\part1\test1.js
set 0 100
set length 1
set 1 200
set length 2
list [ 100, 200 ]
12.Reflect 统一的对象操作API
静态类,封装了一系列对对象的底层操作
Reflet 成员方法就是Proxy处理对象的默认实现
12.1 去掉Reflect
const person = {
name: 'yang',
age: 18
}
const personProxy = new Proxy(person,{
get(target,property) {
console.log('watch logic')
// return Reflect.get(target,property)
}
})
console.log(personProxy.age)
////
PS E:\lagou前端\demo> node .\part1\test1.js
watch logic
undefined
12.2 添加Reflect
const person = {
name: 'yang',
age: 18
}
const personProxy = new Proxy(person,{
get(target,property) {
console.log('watch logic')
return Reflect.get(target,property)
}
})
console.log(personProxy.age)
////
PS E:\lagou前端\demo> node .\part1\test1.js
watch logic
18
Reflect的作用:统一的提供一套用于操作对象的API
12.3 不使用Reflect对对象的操作
const person = {
name: 'yang',
age: 18
}
//判断 对象是否有 属性
console.log('name' in person)
//获取对象所有的Key
console.log(Object.keys(person))
//删除对象的属性
console.log(delete person['age'])
console.log(person)
////
PS E:\lagou前端\demo> node .\part1\test1.js
true
[ 'name', 'age' ]
true
{ name: 'yang' }
12.4 使用Reflect 对对象的操作
const person = {
name: 'yang',
age: 18
}
//判断 对象是否有 属性
console.log(Reflect.has(person,'name'))
//获取对象所有的Key
console.log(Reflect.ownKeys(person))
//删除对象的属性
console.log(Reflect.deleteProperty(person,'age'))
console.log(person)
////
PS E:\lagou前端\demo> node .\part1\test1.js
true
[ 'name', 'age' ]
true
{ name: 'yang' }
13.Promise 一种更优的异步编程解决方案
解决了传统异步编程中函数嵌套过深的问题
14.class关键字
14.1 传统使用prototype
function Person (name) {
this.name = name;
}
Person.prototype.say = function () {
console.log(`my name is ${this.name}`)
}
const p = new Person('tom')
p.say()
////
PS E:\lagou前端\demo> node .\part1\test1.js
my name is tom
14.2 使用class
class Person {
constructor(name) {
this.name = name
}
say() {
console.log(`my name is ${this.name}`)
}
}
const p = new Person('tom')
p.say()
////
PS E:\lagou前端\demo> node .\part1\test1.js
my name is tom
14.3 静态方法
class Person {
constructor(name) {
this.name = name
}
say() {
console.log(`my name is ${this.name}`)
}
static create(name) {
return new Person(name)
}
}
const p = Person.create('tom')
p.say()
////
PS E:\lagou前端\demo> node .\part1\test1.js
my name is tom
14.4 继承
class Person {
constructor(name) {
this.name = name
}
say() {
console.log(`my name is ${this.name}`)
}
static create(name) {
return new Person(name)
}
}
class Student extends Person {
constructor(name,number) {
super(name)
this.number = number
}
hello() {
super.say()
console.log(`my number is ${this.number}`)
}
}
const s = new Student('jack',100)
s.hello()
////
PS E:\lagou前端\demo> node .\part1\test1.js
my name is jack
my number is 100
15.Set 数据类型
const s = new Set()
//add返回的是Set 所以可以链式调用
s.add(1).add(2).add(3).add(4).add(4).add(5)
//set 元素 没有重复 所以 自动去重
console.log(s) //// Set { 1, 2, 3, 4, 5 }
//Set的遍历
s.forEach(i => {
console.log(i) //// 1 2 3 4 5
})
//Set的常用方法
console.log(s.size) //// 5
console.log(s.has(100)) ////false
console.log(s.delete(3)) ////true
console.log(s) //// Set { 1, 2, 4, 5 }
15.1 Set 对 数组的去重处理
Array.from() 可以将Set 转化为Array
const arr = [1,2,3,1,2,1,4,1]
//const result = Array.from(new Set(arr))
const result = [...new Set(arr)]
console.log(result)
PS E:\lagou前端\demo> node .\part1\test1.js
[ 1, 2, 3, 4 ]
16.Map 数据结构
16.1 普通键值对
对象的key只能是String类型,不是String类型会被自动转化为String
const obj = {}
obj[true] = 'value'
obj[123] = 'value'
obj[{ a: 1 }] = 'value'
console.log(Object.keys(obj))
////
PS E:\lagou前端\demo> node .\part1\test1.js
[ '123', 'true', '[object Object]' ]
16.2 Map 类型
const m = new Map()
const tom = { name:'tom'}
m.set(tom,90)
console.log(m)
console.log(m.get(tom))
//Map的遍历
m.forEach((value,key)=>{
console.log(value,key)
})
////
PS E:\lagou前端\demo> node .\part1\test1.js
Map { { name: 'tom' } => 90 }
90
90 { name: 'tom' }
17.Symbol 新的数据类型
17.1 最主要的作用就是为对象添加独一无二的属性名
const s = Symbol()
console.log(s)
console.log(typeof s)
console.log(Symbol() === Symbol())
//添加描述文本
//注意:即使添加同一描述文本 Symbol 也是不一样的
console.log(Symbol('foo'))
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
Symbol()
symbol
false
Symbol(foo)
17.2 设置对象私有成员
const name = Symbol();
const person = {
[name]:'yang',
say(){
console.log(this[name])
}
}
console.log(person[Symbol()])
person.say()
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
undefined
yang
18.for of 循环
是一种数据统一的遍历方式
const arr = [100,200,300,400,500]
for (item of arr) {
console.log(item) ////100 200 300 400
if(item > 300){
break
}
}
//不能跳出循环
arr.forEach(item =>{
console.log(item) ////100 200 300 400
})
//some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。
//some() 方法会依次执行数组的每个元素:
//如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
//如果没有满足条件的元素,则返回false。
//every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。
//every() 方法使用指定函数检测数组中的所有元素:
//如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
//如果所有元素都满足条件,则返回 true。
const result = arr.some((item)=>{
return item > 300
})
console.log(result) ////true
for (i in arr) {
console.log(arr[i]) ////100 200 300 400 500
}
18.1 Set的 for of 遍历
const s = new Set(['foo','bar'])
for (const item of s) {
console.log(item)
}
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
foo
bar
18.2 Map的 for of 遍历
const m = new Map()
m.set('foo','123')
m.set('bar','456')
for(const item of m ) {
console.log(item)
}
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
[ 'foo', '123' ]
[ 'bar', '456' ]
18.3 使用数组的解构得到K V
const m = new Map()
m.set('foo','123')
m.set('bar','456')
for(const [key,value] of m ) {
console.log(key,value)
}
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
foo 123
bar 456
19.实现可迭代接口 Iterable
对象是不可以直接迭代的
在对象中挂一个iterator方法,在这个方法中返回一个迭代器对象
接口约定:内部必须要有一个用于迭代的next方法
const obj = {
store: ['foo','bar','baz'],
[Symbol.iterator]: function() {
let index = 0
const self = this
return {
next: function() {
const result = {
value:self.store[index],
done:index >= self.store.length
}
index++
return result
}
}
}
}
for (const item of obj) {
console.log('循环',item)
}
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
循环 foo
循环 bar
循环 baz
20.迭代器模式
20.1 实现迭代器的目的
场景: 协同开发一个任务清单应用
//============== 我的代码 ==============
const todos= {
life:['吃饭','睡觉','打豆豆'],
learn:['语言','数学','英语'],
}
//============== 你的代码 ==============
for(const item of todos.life){
console.log(item)
}
for(const item of todos.learn){
console.log(item)
}
如果我需要在我的todos数据列表里添加数据时,你的代码就需要作出相应的更改,对于调用来说,代码耦合度太高
//============== 我的代码 ==============
const todos= {
life:['吃饭','睡觉','打豆豆'],
learn:['语言','数学','英语'],
work:['唱歌']
}
//============== 你的代码 ==============
for(const item of todos.life){
console.log(item)
}
for(const item of todos.learn){
console.log(item)
}
for(const item of todos.work){
console.log(item)
}
20.2 如何解决
如果我的代码能够对外统一提供一个遍历的接口
对于调用者而已,就不用去关心它内部的数据结构,也不用担心结构的改变
我们可以自己写一个方法来实现:
//============== 我的代码 ==============
const todos = {
life: ['吃饭', '睡觉', '打豆豆'],
learn: ['语言', '数学', '英语'],
work: ['唱歌'],
each: function (callback) {
const all = [].concat(this.life, this.learn, this.work)
for (item of all) {
callback(item)
}
}
}
//============== 你的代码 ==============
todos.each(function (item) {
console.log(item);
})
20.3 用迭代器的方法实现
//============== 我的代码 ==============
const todos = {
life: ['吃饭', '睡觉', '打豆豆'],
learn: ['语言', '数学', '英语'],
work: ['唱歌'],
[Symbol.iterator]:function() {
//使用对象展开符 等同于 [].concat
const all = [...this.life,...this.learn,...this.work]
let index = 0
return{
next:function(){
return{
value:all[index],
done: index++ >= all.length //true 就迭代完成了
}
}
}
}
}
//============== 你的代码 ==============
for(item of todos) {
console.log(item)
}
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
吃饭
睡觉
打豆豆
语言
数学
英语
唱歌
迭代器的核心 就是对外提供统一遍历接口,让外部不用去担心内部的数据结构是怎么样的
这里展示的each方法只适用于这里展示的数组结构
而ES2015种的迭代器 是从语言层面去实现的迭代器模式,所以说它适用于任何数据结构,只要实现了iterable 接口,那我们就可以实现使用for…of 遍历对象
21.生成器函数
解决异步编程回调嵌套过深所导致的问题
function * foo(){
console.log('test')
return 100
}
const result = foo()
console.log(result)
console.log(result.next())
////
Object [Generator] {}
test
{ value: 100, done: true }
21.1 惰性执行 yield
function * foo(){
console.log('111')
yield 100
console.log('222')
yield 200
console.log('333')
yield 300
}
const generator = foo()
console.log(generator)
console.log(generator.next())
console.log(generator.next())
console.log(generator.next())
console.log(generator.next())
////
Object [Generator] {}
111
{ value: 100, done: false }
222
{ value: 200, done: false }
333
{ value: 300, done: false }
{ value: undefined, done: true }
21.2 Generator 应用
案例一:发号器
function * createIdMaker(){
let id = 1
while(true) {
yield id++
}
}
const idMaker = createIdMaker()
console.log(idMaker.next().value)
console.log(idMaker.next().value)
console.log(idMaker.next().value)
console.log(idMaker.next().value)
////
PS E:\lagou前端\demo> node .\part1\test1.js
1
2
3
4
案例二:使用Generator 函数实现Iterator方法
const todos = {
life: ['吃饭', '睡觉', '打豆豆'],
learn: ['语言', '数学', '英语'],
work: ['唱歌'],
[Symbol.iterator]: function* () {
const all = [...this.life, ...this.learn, ...this.work]
for (item of all) {
yield item
}
}
}
for (const item of todos) {
console.log(item)
}
////
PS E:\lagou前端\demo> node .\part1\test1.js
吃饭
睡觉
打豆豆
语言
数学
英语
唱歌
22.ES2016
22.1 Array.prototype.includes
我们先看看indexOf方法
const arr = ['foo',1,NaN,false]
console.log(arr.indexOf('foo'))
console.log(arr.indexOf(1))
console.log(arr.indexOf(NaN))
console.log(arr.indexOf(false))
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
0
1
-1
3
indexOf 无法检查出NaN
注意点:NaN是唯一一个和自身不相等的值:NaN === NaN // false
22.2 includes 可以检查出NaN 返回布尔值
const arr = ['foo',1,NaN,false]
console.log(arr.includes('foo'))
console.log(arr.includes(1))
console.log(arr.includes(NaN))
console.log(arr.includes(false))
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
true
true
true
true
22.3 指数运算符
console.log(Math.pow(2,10))
console.log(2 ** 10)
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
1024
1024
23.ES2017
23.1 Object.values
const obj = {
foo: 'value1',
bar: 'balue2'
}
console.log(Object.values(obj))
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
[ 'value1', 'balue2' ]
23.2 Object.entries
数组形式返回键值对
const obj = {
foo: 'value1',
bar: 'balue2'
}
console.log(Object.entries(obj))
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
[ [ 'foo', 'value1' ], [ 'bar', 'balue2' ] ]
因此可以使用for of
const obj = {
foo: 'value1',
bar: 'balue2'
}
for (const [key, value] of Object.entries(obj)) {
console.log(key, value)
}
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
foo value1
bar balue2
使用entries 转化 Map对象
const obj = {
foo: 'value1',
bar: 'balue2'
}
console.log(new Map(Object.entries(obj)))
////
PS F:\拉钩前端\lagou> node .\task1\task1.js
Map { 'foo' => 'value1', 'bar' => 'balue2' }
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!