JavaScript是ECMAScript的扩展语音
Let
- 块级作用域,{}内的成员外层访问不了。
const
- 只读、恒量。允许修改内存空间数据,不允许修改内存指向。
数组的解构
const arr = [1,2,3]
const [a,b,c] = arr
console.log(a,b,c) // 1,2,3
--------------------------------------------
const [,,c] = arr
console.log(c) //3
--------------------------------------------
const [a,...c] = arr //...包括解构的数组的最后一个成员
console.log(c) //2.3
-------------------------------------------
const [a] = arr //结构的成员个人小于被结构的数组长度
console.log(a)//1
--------------------------------------------
const [a,b,c,d] = arr //结构的成员个人大于被结构的数组长度
console.log(d)//undefined
---------------------------------------------
const [a,b,c,d = 4] = arr //结构的成员添加默认值
console.log(d) //4
对象解构
const obj = {name:'ldj',age:18}
const {name} = obj
console.log(name) //ldj
const name = 'ld'
const obj = {name:'ldj',age:18}
const {name:myName = 'l'} = obj //如果遇到解构的变量与定义的变量相同的时候,可通过:重命名 = 默认值
console.log(myName) //l
模板字符串
const str = `hello
es2015` //可换行
console.log(str)
const name = 'hello'
const str = `${name},es2015--${1+2}----${Math.random()}` //可嵌入变量,运算,方法。
console.log(str)
const name = 'hello'
const str = `${name},es2015--${1+2}----${Math.random()}` //可嵌入变量,运算,方法。
console.log(str) //hello,es2015
//带标签的模板字符串
const name = 'ldj';
const gender = true;
const mytag = (str,name,gender) =>{
let sex = gender ? "男的":"女的"
return str[0]+name+str[1]+sex+str[2]
// log(str,name,gender)
}
const str = mytag`hey, ${name} is a ${gender}.`
log(str)//hey, ldj is a 男的.
字符串的扩展方法
const message = `Error:foo is not defined.`
console.log(
message.startsWith('Error') //开头是否包含
message.endsWith('.') //结尾是否包含
message.includes('foo') //中间是否包含
)
参数默认值
function foo(enable = false){
console.log(enable)
}
foo() //enable默认值false
foo(true)传入参数改变默认展true
function foo(bar,enable = false){ //多参数的情况下,参数默认值放在最后
console.log(enable)
}
function foo (first,...args){ //如有明确形参 ...放到最后
console.log(args)
}
foo(1,2,3,4,5)//[2,3,4,5] // 不确定参数个数的情况下可以使用...
展开数组
let arr = [1,2,3,4]
console.log.apply(console,arr) //1,2,3,4
console.log(...arr)//1,2,3,4
箭头函数
const inc = n => n+1
- this区别
let obj = {
name:'lidongjun',
fn:function(){
console.log(this.name)
}
}
obj.fn() 普通函数this指向调用者obj //结果lidongjun
let obj = {
name:'lidongjun',
fn:() => console.log(this.name)
}
obj.fn() 箭头函数this指向父级作用域window,window下没有声明name //结果undefined~~~~~
let obj = {
name:'lidongjun',
fn:function(){
setTimeout(() => {
console.log(this.name)
},1000)
}
}
obj.fn() 箭头函数this指向父级作用域,如果父级作用域不是一个箭头函数,指向到obj // 结果lidongjun
let obj = {
name:'lidongjun',
fn:() => {
setTimeout(() => {
console.log(this.name)
},1000)
}
}
obj.fn() this指向到window // 结果undefined
对象字面量
const bar = 123
const obj = {
name:'lidongjun', //普通对象字面量
bar, // 变量和属性明一致的话
method1(){ //方法名成为属性名
console.log(this) //this指向当前对象obj
},
[1+1]:1234, //[表达式]成为属性名 也叫计算属性名
[Math.random()]:5566, [方法结果]成为属性名 也叫计算属性名
[bar]:123 [变量值]成为属性名 也叫计算属性名
}
console.log(obj)
//{
'2': 1234,
'123': 123,
name: 'lidongjun',
bar: '123',
method1: [Function: method1],
'0.13339600127260853': 5566
}
对象扩展方法
//Object.assign
const obj1 = {
a:1,
b:2
}
const obj2 = {
a:3,
c:4
}
let obj3 = Object.assign(obj2,obj1) //(目标对象,覆盖的对象,....若干个覆盖对象)
console.log(obj3) //{ a: 1, c: 4, b: 2 } 注:这里的obj3和目标对象obj2 是 相等的
//Object.is
Object.is(NaN,NaN) //true
对象访问代理器Proxy
//Proxy
const person = {
name:'lidongjun',
age:18
}
const peronProxy = new Proxy(person,{ //proxy
get(target,property){
//target //当前对象
//property 属性名
return property in target ? target[property] : 'default' //判断当前属性是否存在
},
set(target,property,value){
//target //当前对象
//property 属性名
//value 设置的属性值
if(property === 'age'){
if(!Number.isInteger(value)){
throw new TypeError(`${value} is not an int`)
}
}
target[property] = value
// console.log(target,property,value)
}
})
peronProxy.sex= '男'
peronProxy.age = 100
console.log(peronProxy.sex) //男
console.log(peronProxy) //{ name: 'lidongjun', age: 100, sex: '男' }
let arr = []
const arrProxy = new Proxy(arr,{
set(target,property,value){
target[property] = value
return true //设置成功
}
})
arrProxy.push(100)
console.log(arrProxy) //[100]
Reflect静态对象
- 统一提供一套用于操作对象的API
const obj = {
name:'ldj',
age:18
}
console.log(Reflect.has(obj,'name')) //判断对象当中是否存在name属性
console.log(Reflect.deleteProperty(obj,'age')) //删除age属性
console.log(Reflect.ownKeys(obj))//获取对象所有属性返回一个数组
Class 类型
class Person{
static of(value){
return new Person(value)
}
constructor(value){
this._value = value
}
say(){
console.log(`hi,my name is ${this._value}`)
}
}
Person.of('li dong jun').say()
extends 继承
class Student extends Person{
constructor(value,number){
super(value)
this._number = number
}
hello(){
super.say()
console.log(`my school number is ${this._number}`)
}
}
let e = new Student('li dong jun',100)
e.hello()
Set数据结构
const arr = [1,2,2,3,4,5,5,5,6]
const s = Array.from(new Set(arr)) //去重返回一个Array
const s = [...new Set(arr)] 返回数组
console.log(s) //[ 1, 2, 3, 4, 5, 6 ]
Map数据结构
- Map 的数据结构可以用任意类型的数据作为键,对象只能用字符串作为键
const m = new Map()
const obj = {
name:'lidongjun'
}
m.set(obj,90)
m.forEach((value,key) =>{
console.log(value,key) //90,{ name: 'lidongjun' }
})
console.log(m.get(obj)) // 90
console.log(m) //{ { name: 'lidongjun' } => 90 }
Symbol
- 创建的Symbol一定是唯一的。
- 主要作用为对象添加独一无二的属性名。
const name = Symbol()
const aa = '2222222'
const obj = {
[name]:'lidongjun',
[1+2]:'11111',
aa,
say(){
console.log(this[name])
console.log(this[1+2])
}
}
obj.say();
// lidongjun
// 11111
for of
- 内部工作原理:所有能被for of 循环遍历的数据类型 都必须实现Iterator的接口,内部要挂载一个Iterator方法,返回一个next方法的对象,不断调用next方法就可以实现遍历
const arr = [111,222,333,444,555]
for(const item of arr){
if(item>222){
break
}
}
const arr1 = [111,222,333,444,555]
const m = new Map()
m.set('2222',2222222)
m.set('3333',3333333)
for(const [value,key] of m){ //数组解构
console.log(value,key)
}
const arr = [1,2,3,4,5]
const iterator = arr[Symbol.iterator]()
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
//
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: 4, done: false }
{ value: 5, done: false }
{ value: undefined, done: true}
Iterable 实现可迭代接口
- 迭代器模式:对外统一提供便利接口,让外部不用关心内部的数据结构是什么样的。
const obj = {
store:[1,2,3,4,5,6,7],
[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)
}
//
1
2
3
4
5
6
7
生成器函数 Generator
- 生成器函数会自动返回一个生成器对象,调用对象的next方法才会让函数体执行,执行过程中遇到yield关键词函数就会暂停,而且yield后面的值将会作为next方法结果返回给下一个。特点惰性执行。
function * foo (){
console.log(1)
yield 11
console.log(2)
yield 22
console.log(3)
yield 33
}
const generator = foo()
console.log(generator .next())
console.log(generator .next())
console.log(generator .next())
ES2016新功能
const arr = ['foo',NaN]
console.log(arr.includes('foo')) //true
console.log(arr.includes(NaN)) //true
console.log(2**10) //1024 指数运算符
ES2017新功能
//.Object.entries 数组的形式返回键值对
//Object.values 对象当中所有值组成的数组
const obj = {
foo:'111',
bar:'222'
}
console.log(Object.values(obj))
for(const [key,value] of Object.entries(obj)){
console.log(key,value)
}
//Async / Await
async function foo (){
await console.log(1)
await console.log(2)
await console.log(3)
}
foo()