ES5和ES6笔记

JS对象

JSON.stringify(obj/arr) //js对象或数组转换为json对象或数组

JSON.parse(json) //json对象或数组转换为js对象或数组

var obj = {name: 'Tom'}
 obj = JSON.stringify(obj)
 console.log(obj); //{"name":"Tom"} String
 obj = JSON.parse(obj)
 console.log(obj); //{ name: 'Tom' } Object

  

JS数组

Array.prototype.indexOf(value) //得到值在数组中的第一个索引

Array.prototype.LastIndexOf(value)  //得到值在数组中的最后一个索引

Array.prototype.forEach(function(item,index){}) //遍历数组

Array.prototype.map(function(item,index){ return item+1 }) //遍历数组返回一个新的数组,返回加工之后的值
//item每个+1

Array.prototype.filter(function(item,index){}) //遍历过滤出一个新的子数组,返回条件为true的值

  

JS函数

区别bind()与call()和aplly()?

  1. 都能指定函数中的this
  2. call和apply是立即调用函数
  3. bind是将函数返回
  4. 传入参数的形式
Function.prototype.bind(obj) //将函数内的this绑定为obj,并将函数返回

    foo.call(obj,33,44)
    foo.apply(obj,[33,44])
    foo.bind(obj,33,44)() //得到返回的函数,需要再后面加括号才能立即调用
    //bind传参方式和call一样

    setTimeout(function(){
        console.log(this)
    }.bind(obj),1000) //这里的this指向obj

  

let关键字

特点: 在块级作用域内有效 不能重复声明 不会预处理,不存在提升

应用: 循环遍历加监听

console.log(i) //报错
let i = 1
let i = 1 //报错

 

const关键字

作用:定义一个常量

特点: 不能修改 其他特点同let

应用: 保存不用改变的数据

变量的解构 赋值

从对象或数组中提取数据,并赋值给变量(多个)

let obj = {name:'Tom' , age:12}
let {name , age} = obj //等于赋obj.name和obj.age中的值

let arr = [1,3,5,'abc',true]
let [a,b,c,d,e] = arr //根据下标来给值
let[,,a,b] = arr //a==5,b=='abc

function foo({name,age}){  // let {name,age} = obj
    console,log(name , age)
}
foo(obj)

  

模板字符串

简化字符串的拼接 模板字符串必须用到``包含 变化的部分用${xxx}定义

let obj ={name:'Tom' ,age:12}
let str = `我的名字叫:${obj.name},我的年龄是:${obj.age}`

  

简化的对象写法

省略同名的属性值 省略同名的function

let name = 'Tom'
let age =39
let obj = {
    name:name,
    age:age,
    getName: function(){
        return this.name
    }
}

//在es6中
let obj = { //同名的属性可以省略不写
    name,
    age,
    getName(){ //可以省略函数的:function
        return this.name
    }
}

  

箭头函数详解

作用:定义匿名函数

基本语法: 没有参数:()=> console.log('xxxx) 一个参数:i=>i+2 大于一个参数:(i,j)=> i+j 函数体不用大括号:默认返回结果 函数体如果有多个语句,需要用{}包围,若有需要返回的值,需要手动返回

使用场景:多用于定义回调函数

箭头函数的特点:

1.简洁

2.箭头函数没有自己的this,箭头函数的this不是调用时候决定的,而是在定义的时候处在的对象就是他的this

3.扩展理解:箭头函数的this看外层是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有则this是window

let fun = ()=> console.log('xxx')
fun() //xxx

let fun = (i,j)=> console.log(i+j) 
fun(1,2) //3

let fun = (x,y) => {
    x+y  //undefined

    return x+y //3
    //只有一条语句时通常把{}省略,会自动返回执行结果
}
fun(1,2)

btn1.onclick = () =>{
            alert(this) //点击btn1之后发现this指向window
}
let obh = {
    name:'Tom'
    getName(){
        btn1.onclick = () =>{
            alert(this)
        }
    }
}
obj.getName() //点击btn1之后发现this指向obj

  

点点点运算符

用途:

1.rest(可变)参数,用来取代arguments,但比arguments灵活,只能是最后部分形参参数,后面不能跟其他形参

2.扩展运算符

何为arguments

funciton foo(a,b){
    console.log(arguments)
    arguments.callee() //指向函数本身
    arguments.forEach(function(item,index){
        console.log(item,index) //报错
    })
}
foo(1,2) 
//arguments是个伪数组

funciton foo(...value){ //通过三点运算符收集的实参形成数组赋给value
    console.log(arguments)
    console.log(value) //真数组,取代了arguments
    value.forEach(function(item,index){
        console.log(item,index) // 1,0
    })
}
foo(1)

funciton foo(a,...value){ //通过三点运算符收集的实参形成数组赋给value
    console.log(arguments)
    console.log(value) //真数组,取代了arguments,[2]
    value.forEach(function(item,index){
        console.log(item,index) // 2,0
    })
}
foo(1,2) //第一个1给了形参a

let arr = [1,6]
let arr1 = [2,3,4,5]
//console.log(...arr1) 相当于把arr1数组遍历把每个值拿出来变成2,3,4,5
arr = [1, ...arr1,6]  //[1,2,3,4,5,6]

  

形参默认值

function Fun(x=0,y=0){
    this.x=x
    this.y=y
}
let fun = new Fun(1,2)
fun.x //1
fun.y //2

let fun1 = new Fun()
fun.x //0
fun.y //0

  

Promise对象

理解:

1.Promise对象:代表了未来某个将要发生的事件(通常是一个异步操作)

2.有了Promise对象,可以将异步操作以同步的流程表达出来,避免了层层嵌套的回调函数(回调地狱:回调函数多的时候有很多嵌套,中间某个环节出了问题,不好解决,因为回调函数无法控制。还有一种回调函数之间的耦合度比较高,互相有依赖关系,导致不可预期的错误发生)

3.ES6的Promise是一个构造函数,用来生成promise实例

使用promise的基本步骤(2步)

//创建promise对象
    let promise = new Promise((resolve,reject)=>{
        //初始化promise状态为pending
        //执行异步操作,通常是发送ajax请求,开启定时器
        console.log(111)
        setTimeout(()=>{
            console.log(333) 
            //根据异步任务的返回结果来去修改promise状态
            //异步任务执行成功
            resolve('hh成功了') //自动修改promise的状态为fullfilled 成功状态
            //异步任务执行失败
            reject('失败了~') //修改promise的状态为rejected 失败状态
        },2000)
    })
    console(222) // 111 222 333 

    //调用promise的then()
    promise.then((data)=>{
        //成功的回调,当状态还为初始化时,不会调用,状态变为成功时调用
        console.log(data) //hh成功了
    } , (error)=>{
        //失败的回调,状态变为失败时调用
        console.log(error) //失败了~
    })

  

promise对象的3个状态 1.pending:初始化状态 2.fullfilled:成功状态 3.rejected:失败状态

应用: 使用promise实现超时处理

使用promise封装处理ajax请求

symbol

概念:ES6中添加了一种原始数据类型symbol

特点:

1.symbol属性对应的值是唯一的,解决命名冲突问题

2.symbol值不能与其他数据进行计算,包括同字符串拼串

3.for in,for of遍历时不会遍历symbol属性

使用:

//调用symbol函数得到symbol值
let symbol = Symbol()   //不像构造函数要去new
console.log(symbol) //Symbol()
let obj ={name:'Tom',age:12}
//obj.sex = '男'
//obj.symbol = 'hello' 只是给obj添加了一个叫symbol的属性
obj[symbol] = 'hello'  //obj多了symbol():'hello' 

//for in , for of不能遍历symbol属性
for(let i in obj){
    console.log(i) //没有symbol
}


//可以去定义常量
const Person_key = Symbol('person_key')
console.log(Person_key) //Symbol(person_key)


//传参标识
let symbol2 = Symbol('one')
let symbol3 = Symbol('two')
console.log(symbol2 == symbol3) //false
console.log(symbol2,symbol3)  //Symbol(one) Symbol(two)

  

内置symbol值 ES6提供了11个内置的Symbol值,指向语言内部的使用方法 Symbol.iterator属性指向该对象的默认遍历器方法

iterator遍历器

概念:iterator是一种借口机制,为各种不同的数据结构提供统一的访问机制

作用

1.为各种数据结构提供一个统一的,简便的访问接口

2.使得数据结构的成员能够按某种次序排列

3.ES6创造了一种新的遍历命令for of循环,iterator接口主要供for of消费

工作原理:

1.创建一个指针对象(遍历器对象),指向数据结构的起始位置

2.第一次调用next方法,指针自动指向数据结构的第一个成员

3.接下来不断调用next方法,指针会一直往后移动,直到指向最后一个成员

4.每调用next方法返回的是一个包含value和done的对象,{value:当前成员的值 , done:布尔值} *value表示当前成员的值,done对应的布尔值表示当前的数据结构是否遍历结束 *当遍历结束的时候value返回undefined,done返回true

原生具备iterator接口的数据(可用for of遍历)

扩展理解: 1.当数据结构上部署了Symbol.iterator接口,该数据就是可以用for of遍历 2.当使用for of去遍历目标数据时,该数据会自动寻找Symbol.iterator属性

//模拟指针对象(遍历器对象)
function myIterator(arr){ //iterator接口
    let nextIndex = 0 //记录指针位置
    return {
        //遍历器对象
        next: function(){
            return nextIndex < arr.length?{value:arr[nextIndex++],done:false}:{value:undefined,done:true}            
        }
    }
}
let arr = [4,1,65,'abc']
let iteratorObj = myIterator(arr)
console.log(iteratorObj.next()) //4
console.log(iteratorObj.next())  //1
console.log(iteratorObj.next())  //65
console.log(iteratorObj.next())   //'abc' 
console.log(iteratorObj.next())   //undefined true

//将iterator接口部署到指定的数据类型上,可以使用for of去循环遍历
//数组,字符串,arguments,set容器,map容器
//对象没有iterator接口

for(let i of arr){
    console.log(i) //4,1,65,'abc'
}

let str = 'abcdefg'
for(let i of str){
    console.log(i) //a,b,c,d,e,g
}

function fun(){
    for(let i of arguments){
        console.iog(i)
    }
}
fun(1,4,5,'abc') //1,4,5,'abc'


let targetData = { //等同于在指定的数据内结构上部署了iterator接口
                    //当使用for of去遍历某一个数据结构时,首先去找Symbol.iterator,找到了就去遍历,没有就报错
    [Symbol.iterator]:function(){
        let nextIndex = 0 //记录指针位置
        return {
        //遍历器对象
        next: function(){
            return nextIndex < this.length?{value:this[nextIndex++],done:false}:{value:undefined,done:true}            
        }
    }
    }
}

//使用三点运算符,解构赋值,默认调用iterator接口
let arr2 = [1,6]
let arr3 = [2,3,4,5]
arr2 = [1,...arr3,6]
let [a,b] = arr2
console.log(a,b) //1,2

  

Genrator函数

概念:

1.ES6提供的解决异步编程方案之一

2.Genrator函数是一个状态机,内部封装了不同状态的数据

3.用来生成遍历器对象 4.可暂停函数(惰性求值),yield可暂停,next方法可启动。每次返回的是yield后的表达式结果

特点:    1.function与函数名之间有个*号

    2.内部用yield表达式来定义不同的状态

    3.generator函数返回的是指针对象,而不会执行函数的内部逻辑

    4.调用next方法函数内部逻辑开始执行,遇到yield表达式停止,返回{value: field后的表达式结果,done:布尔值}

    5.再次调用next方法会从上一次停止时的yield处开始,直到最后 6.yield语句返回结果通常为undefined,当调用next方法时,传参内容会作为启动时yield语句的返回值

function* generatorExample(){
        console.log(1)
        let result = yield 'hello'  //状态值为hello
        console.log(result) //aaaaaaa 不传的话为undefined
        console.log(2)
        yield 'generator'  //状态值为generator
        return '3'
    }
    let MG = generatorExample()
    //MG.next() //1  没有2第一次在'hello'暂停了
    console.log(MG.next()) //{value: 'hello',done:false}
    console.log(MG.next('aaaaaaa'))  //2 {value:'generator',done:false}
    console.log(MG.next())  //{value:3,done:true}

    //对象的symbol.iterator属性 指向遍历器对象
    let obj ={name:'Tom',age:39}
    for(let i of obj){
        console.log(i) //报错
    }
    obj[symbol.iterator] = function* myTest(){
        //返回一个遍历器对象,相当于给对象认为部署了一个iterator接口
        yield 1
        yield 2
        yield 3
    }
    for(let i of obj){
        console.log(i) //1 2 3 
    }

  

async函数

概念: 真正意义上去解决异步回调的问题,同步流程表达异步操作

本质:Generator的语法糖

语法: async function foo(){ await 异步操作; await 异步操作; }

特点:    1.不需要像Generator去调用next方法,遇到await等待,当前的异步操作完成就往下执行

    2.返回的总是Promise对象,可以用then方法进行下一步操作

    3.async取代Generator函数的星号*,await取代yield

    4.语意上更为明确,使用简单,暂时没有任何副作用

function foo(){
    return new Promise(resolve => {
        setTimeout(resolve,2000)
    })
}
async function test(){
    console('开始执行',new Date().toTimeString())
    await foo()
    console('执行结束',new Date().toTimeString())
}
text() //开始执行 隔了两秒 执行结束

//async里的await返回值
function fun1(){
    return 1
}
async function fun(){
    let result = await fun1()
    console.log(result)
}
fun() //1

async function fun(){
    let result = await Promise.resolve('aaa') //直接把Promise对象改为成功状态
    console.log(result) //aaa
    result = await Promise.reject('bbb')
    console.log(result) //报错
}
fun()

  

class类使用

1.通过class定义类,实现类的继承

2.在类中通过constructor定义构造方法

3.通过new来创建类的实例

4.通过extends来实现类的继承

5.通过super调用父类构造方法

6.重写从父类继承的一般方法

function Person(name,age){
    this.name = name 
    this.age = age
}
let person = new Person('Tom',12)
 
//定义一个人物的类
class Person {
    //类的构造方法
    constructor(name , age){
        this.name = name
        this.age = age
    }
    //类的一般方法
    showName(){
        console.log(this.name)
    } //放在实例对象的隐式原型上
}
let person = new Person('Tom',12)
person.showName() //Tom

class StarPerson extends Person{
    constructor(name,age,salary){
        super(name,age)//调用父类的构造方法
        this.salary = salary
    }
    showName(){
        //父类的方法重写
        console.log(this.name,this.age,this.salary)
    }
}
let p1 = new StarPerson('Jack',20,5000) 
console.log(p1)
p1.showName()

  

字符串扩展

1.includes(str):判断是否包含指定的字符串

2.startsWith(str):判断是否以指定字符串开头

3.endsWith(str):判断是否以指定字符串结尾

4.repeat(count):重复指定次数

let str = 'a'
console.log(str.includes('a')) //true
console.log(str.startsWith('b')) //false
console.log(str.endsWith('a')) //true
console.log(str.repeat(5)) //aaaaa

  

数组方法的扩展

1.Array.from(v):可以将伪数组或可遍历对象转换成真实数组

2.Array.of(v1,v2,v3):将一系列值转换成数组

3.find(function(value,index,arr){return true}):找出第一个满足条件返回true的元素

4.findIndex(function(value,index,arr){return true}):找出第一个满足条件返回true的元素下标

let arr = [2,3,4,3,6]
let a = arr.find(function (item,index){
    return item>=4
})
console.log(a) //4

  

对象方法扩展

1.Object.is(v1,v2) 判断两个数据是否完全相等

2.Object.assign(target,source1,source2) 将源对象的属性复制到目标对象上

3.直接操作__proto__属性

console.log(0 == -0) //true
console.log(Object.is(0,-0)) //flase
console.log(Object.is(NaN,NaN))//true 因为是用字符串的形式来判断

let obj = {}
let obj1 = {name:'Tom' , age:12}
let obj2 = {name:'Jack' , age:20}
let obj3 = {salary:5000}
Object.assign(obj,obj1,obj2,obj3)
console.log(obj) //{ name: 'Jack', age: 20, salary: 5000 }

let obj1={}
let obj2 ={money:50000}
obj1.__proto__ =obj2
console.log(obj1.money); //obj1.__proto__指向了obj2这个对象,obj1可以通过原型链寻找得到这个对象的属性

  

深度克隆

let str = 'abcd'
let str2 = str
str2 = ''
console.log(str) //abcd

//拷贝数组/对象 没有生成新的数据,而是复制了一份引用
let arr = {1,4,{name:'Tom',age:12}}
let arr2 = arr
arr2[0] = 'abcd'
console.log(arr[0]) //abcd 

  

浅拷贝(对象/数组): 特点:拷贝的是引用,修改拷贝以后的数据会影响原数据,使得原数据不安全

深拷贝(深度克隆): 特点:拷贝的时候生成新数据,修改新数据不会影响原数据

拷贝数据: 基本数据类型:拷贝后生成一份新的数据,修改拷贝以后的数据不会影响原数据

对象数组:拷贝后不会生成新的数据,而是拷贝的是引用。修改拷贝之后的数据会影响原来的数据

拷贝数据的方法:

1.直接赋值给一个变量 浅拷贝

2.Object.assign() 浅拷贝

3.Array.prototype.concat() 浅拷贝

4.Array.prototype.slice(startIndex,endIndex) 截取子数组 浅拷贝

5.ISON.parse(JSON.stringify()) 深拷贝(深度克隆),拷贝的数据里不能有函数,处理不了,因为这两个方法只能传入原生的JS对象或数组,传入函数转过来发现函数变成null

let obj = {name:'Tom'}
let obj2 = Object.assign(obj)
console.log(obj2)
obj2.name = 'Jack'
console.log(obj.name) //Jack

let arr = [1,2,{name:'Tom'}]
let arr2 = arr.concat() 
arr2[2].name = 'a'
console.log(arr[2].name) //a
let arr3 = arr.slice() //相当于传整个数组[1,2,{name:'a'}]
arr3[2].name = 'b'
console.log(arr[2].name) //b

let arr = [1,2,{name:'Tom'}]
let arr2 = JSON.stringify(arr) //arr2是个JSON数组,是个字符串
arr2 = JSON.parse(arr2)
arr2[2].name = 'Jack'
console.log(arr[2].name) //Tom

  

如何实现深度克隆? 拷贝数据里有对象或数组,还要继续遍历对象或者数组拿到里面的每一项的值,一直到拿到的都是基本数据类型,然后再去复制,这就是深度克隆

知识点储备: 如何判断数据类型:arr ---> Array null--->Null

1.typeof返回的数据类型:String Number Boolean Undefined Object Function

2.Object.prototype.toString.call(obj)

let result = 'abcd'
resunlt = null
result = [1,2,3]
console.log(Object.prototype.toString.call(result)) //[Object String] [Object Null] [Object Array]
console.log(Object.prototype.toString.call(result).slice(8,-1)) //String Null Array
for in 循环对象的到属性名 数组得到下标
    function checkType(tarhet){
        return Object.prototype.toString.call(target).slice(8,-1)
    }
    console.log(checkType(result)) //Array

    //实现深度克隆 针对对象数组
    function clone(target){
        //判断拷贝的数据类型
        //result是最终克隆的数据
        let result,targetType = checkType(target)
        if(targetType === 'Objcect'){
            result = {}
        }
        else if(targetType ==='Array'){
            result = []
        }
        else{
            return target
        }

        //遍历目标数据
        for(let i in target){
            //获取遍历数据结构的每一项值
            let value = target[i]
            //判断目标结构里的每一值是否存在对象/数组
            if(checkType(value) ==='Object' || checkType(value) === 'Array'){
                //继续遍历取到的value值
                result[i] = clone(value)
            }else{ //获取到的value是基本数据类型或者函数
                 result[i] =value
            }
           
        }
        return result
    }

let arr = [1,2,{age:12}]
let arr2 = clone(arr)
arr2[2] = 'a'
console.log(arr , arr2); //[ 1, 2, { age: 12 } ] [ 1, 2, 'a' ]

  

Set和Map容器

1.Set容器:无序不可重复的多个value的集合体 Set() Set(array) add(value) delete(value) has(value) clear() size()

2.Map容器:无序的key不重复的多个key-value的集合体 Map() Map(array) set(key,value) //添加 get(value) delete(value) has(value) clear() size()

let set = new Set([1,2,3,4,2,1])
console.log(set) //[1,2,3,4]
set.add(7)
console.log(set.size)//5 
set.clear()//清空set

let map = new Map([['key','value'],[36,'age']])
map.set(78,'hh')
console.log(map) //Map { 'key' => 'value', 36 => 'age', 78 => 'hh' }
map.delete(36)
console.log(map)//Map { 'key' => 'value' , 78 => 'hh' }

  

Array.prototype.includes(value) :判断数组中是否包含指定value

let arr = [1,2,3,4,'abc']
console.log(arr.includes('a')) //false

  

 
 

猜你喜欢

转载自www.cnblogs.com/Gzzzh/p/10526012.html
今日推荐