ES5、6、7最常用的知识点概括总结

ECMAScript

  1. 它是一种由ECMA组织(前身为欧洲计算机制造商协会)制定和发布的脚本语言规范
  2. JavaScript 是ECMA的实现
  3. JS 包含三个部分
    1. ECMAScript(核心)
    2. 扩展==》浏览器端
      • BOM (浏览器对象模型)
      • DOM(文档对象模型)
        3.扩展==》服务器端
      • Node
  4. ES的几个重要版本
    • ES5:09年发布
    • ES6(ES2015):15年发布,也称为ECMA2015
    • ES7(ES2016):16年发布,也称为ECMA2016(变化不大)

ES5严格模式

  1. 目的
    • 消除JavaScript语法的一些不合理性,不严谨之处,减少一些怪异行为
  2. 使用
    • 在全局或函数的第一条语句定义为:'use strict';
    • 如果浏览器不支持,只解析为一条简单的语句,没有任何副作用
  3. 语法和行为改变
    • 必须使用 var 声明变量
    • 禁止自定义的函数中的 this 指向 window
    • 创建 eval 作用域
    • 对象不能有重名的属性

ES_5_json对象扩展

  1. JSON.stringify(obj/arr)
    • js 对象(数组)转换为 json 对象(数组)
  2. JSON.parse(json)
    • json 对象(数组)转换为js对象(数组)

ES_5 Object 对象扩展

ES5 给 Object 扩展了一些静态方法,常用的2个:

  1. Object.creat(prototype, [descriptors])
    • 作用:以指定对象为原型创建新的对象
    • 为新的对象指定新的属性,并对属性进行描述
      value: 指定值
      writabkle: 标识当前属性值是否是可修改的,默认为 false
      configurable: 标识当前属性是否可以被删除,默认为 false
      enumerable: 标识当前属性是否能用 for in 枚举,默认为false
var obj = {username: 'damu', age: 30}
var obj1 = {}
obj1 = Object.creat(obj, {
    set: {
        value: 'nan',
        writable: true,
        configurable: true
    }
})
  1. Object.defineProperties(object, descriptors)
    • 作用:为指定对象定义扩展多个属性
      get: 用来获取当前属性值的回调函数
      set: 修改当前属性值触发的回调函数,并且实参即为修改后的值
    • 存取器属性:setter,getter 一个用来存值,一个用来取值
Object.defineProperties(obj2, {
    fullName: {
        get: function () {
            return this.firstName + ' ' + this.lastName;
        }
        set: function (data){
            console.log('set()', data);
            var names = data.split(' ')
            this.firstName = names[0]
            this.lastName = names[1]
        }
    }
})
  1. 对象本身的两个方法
    • get propertyName(){} 用来得到当前属性值的回调函数
    • set propertyName(){} 用来监视当前属性值变化的回调函数
var obj = {
    firstName = 'curry',
    lastName = 'stephen',
    get fullName(){
        return this.firstName + ' ' + this.lastName
    },
    set fullName(data){
        var names = data.split(' ')
        this.firstName = names[0]
        this.lastName = names[1]
    }
}

ES5 数组的扩展

  1. Array.prototype.indexOf(value) :得到值在数组中的第一个下标
  2. Array.prototype.lastIndexOf(value) :得到值在数组中的最后一个下标
  3. Array.prototype.forEach(function(item, index){}): 遍历数组
  4. Array.prototype.map(function(item, index){}):遍历数组返回一个新的数组,返回加工之后的值
  5. Array.prototype.filter(function(item, index){}):遍历过滤出一个新的子数组,返回条件为true的值

ES5 call,apply,bind用法详解

  1. Function.prototype.bind(obj):
    • 作用:将函数内的 this 绑定为 obj,并将函数返回
  2. 面试题:区别bind() 与 call() 和 apply()?
    1. 都能指定函数中的this
    2. call()/apply()是立即调用函数
    3. bind() 是将函数返回

ES6

let 和 const

let
  1. 作用:
    1. 与 var 类似,用于声明一个变量
  2. 特点:
    1. 在块作用域内有效
    2. 不能重复声明
    3. 不会预处理,不存在变量提升

预处理又叫预解析

  1. 应用:
    1. 循环遍历加监听
    2. 使用 let 取代 var 是趋势
const
  1. 作用:
    1. 定义一个常量
  2. 特点:
    1. 不能修改
    2. 其他特点同 let
  3. 应用:
    1. 保存不用改变的数据

变量的解构赋值

  1. 理解:
    1. 从对象或数组中提取数据,并赋值给多个变量
  2. 对象的解构赋值
    let {n, a} = {n:'tom', a:12}
  3. 数组的解构赋值
    let [a,b] = [1, 'atguigu'];
  4. 用途
    1. 给多个形参赋值

模板字符串

  1. 模板字符串:简化字符串的拼接
    1. 模板字符串必须用 反引号 包含
    2. 变化的部分使用 ${xxx} 定义
let obj = {username: 'kobe', age: 39}
str = `我的名字叫: ${obj.username}, 我今年的年龄是: ${obj.age}`

对象的简写方式

简化的对象写法

  • 省略同名的属性值
  • 省略方法的 function
  • 例如:
let x = 1
let y = 2
let point = {
    x,
    y,
    setX (x) {this.x = X}
}
let username = 'kobe'
let age = 39
let obj = {
    username, //同名的属性可以省略不写
    age,
    getName() { //可以省略函数的function
        return this.username;
    }
}
console.log(obj) //kobe 39

箭头函数

  • 作用:定义匿名函数

  • 基本语法:

    • 没有参数:() => console.log('xxx')
    • 一个参数:i => i+2
    • 大于一个参数:(i,j) => i+j
    • 函数体不用大括号:默认返回结果
    • 函数体如果有多个语句,需要用 {} 包围,若有需要返回的内容,需要手动返回
  • 使用场景,多用来定义回调函数

  • 箭头函数的特点:

    1. 简洁
    2. 箭头函数没有自己的 this,箭头函数的 this 不是调用的时候决定的,而是在定义的时候处在的对象就是它的 this
    3. 扩展理解:箭头函数的 this 看外层是否有函数
      如果有,外层函数的 this 就是内部箭头函数的this
      如果没有,则 this 就是 window
let fun = () => console.log('hello')
fun() //hello

//函数体只有一条语句或者是表达式的时候,{} 可以省略,同时也会自动返回语句执行的结果或者是表达式的结果 
let fun1 = (x,y) => x + y
console.log(fun1(1, 2)); //3
let obj = {
    name: '箭头函数',
    getName: () => {
        btn2.onclick = () => {
            console.log(this) //window
        }
    }
}
obj.getName() //等同于 obj.getName() = () => {} 本质也是在 window 下定义的

三点运算符

用途:

  1. rest(可变)参数
    • 用来取代 arguments 但比 arguments 灵活,只能是最后部分形参参数
    • arguments 内部有一个 callee 方法,arguments.callee就是指向函数本身
function fun(...values) {
    console.log(arguments);//伪数组
    arguments.forEach(function (item, index) {
        console.log(item, index)//报错
    })
    console.log(values);//真数组
    values.forEach(function (item, index) {
        console.log(item,index)
    })
}
fun(1,2,3)
let arr = [1,6]
let arr1 = [2,3,4,5]
arr = [1, ...arr1, 6]
console.log(arr) //[1,2,3,4,5,6]
console.log(...arr) //1 2 3 4 5 6

形参默认值

形参的默认值:当不传入参数的时候默认使用形参里的默认值

function Point(x = 1,y = 2) {
    this.x = x
    this.y = y
}
let point = new Point()

Promise 对象

  1. 理解:
    • Promise对象,代表了未来某个将要发生的事件(通常是一个异步操作)
    • 有了 promise 对象,可以将异步操作以同步的流程表达出来,避免了层层嵌套的回调函数(俗称“回调地狱”)
    • ES6的 Promise 是一个构造函数,用来生成 promise 实例
  2. 使用 promise 基本步骤(2步):
    • 创建 promise 对象
let promise = new Promise((resolve, reject) => {
    //初始化promise 状态为 pending
    //执行异步操作
    if(异步操作成功){
        resolve(value)//修改promise的状态为fullfilled
    } else {
        reject(errMsg)//修改promise的状态为rejected
    }
})
  • 调用promise的then()
promise.then(function{
    result => console.log(result)
    errorMsg => alert(errorMsg)
})
  1. promise对象的3个状态
    • pending:初始化状态
    • fulfilled:成功状态
    • rejected:失败状态
  2. 应用:
    • 使用 promise 实现超时处理
    • 使用 promise 封装处理 ajax 请求
let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve()
        reject()
    }, 2000)
})

promsie
    .then((data) => {//成功的回调
        console.log('success')
    }, (error) => {//失败的回调
        console.log('error')
    })
function getNews() {
    let promise = new Promise((resolve, reject) => {
        let xmlHttp = new XMLHTTPRequest()

        xmlHttp.onreadystatechange = function () {
            if(xmlHttp.readyState === 4) {
                if(xmlHttp.status === 200) {
                    resolve(xmlHttp.responseText)
                } else {
                    reject('error')
                }
            }
        }
        xmlHttp.open('GET', url)
        xmlHttp.send()
    })
    return promise
}

getNews('http://localhost:3000/news?id=2')
    .then({data} => {
        console.log(data)
        
        let commenUrl = JSON.parse(data).commentsUrl
        let url = 'http://localhost:3000' + commentsUrl;
        
        return getNews(url)
    }, (error) => {
        console.log(error)
    })
    .then((data) => {
        console.log(data)
    }, () => {
        console.log('error')
    })

symbol

前言:ES5中对象的属性名都是字符串,容易造成重名,污染环境
Symbol:

  • 概念:ES6中的添加了一种原始数据类型symbol(已有的原始数据类型:String, Number, boolean, null, undefinded, 对象)
  • 特点:
    1. Symbol属性值对应的值是唯一的,解决命名冲突问题
    2. Symbol 值不能与其他数据类型进行计算,包括字符串拼接
    3. for in, for of遍历时不会遍历symbol属性
  • 使用:
    1. 调用Symbol函数得到 symbol 值
let symbol = Symbol()
let obj = {}
obj[symbol] = 'hello'
2. 传参标识
let symbol = Symbol('one')
let symbol2 = Symbol('two')
console.log(symbol);//Symbol('one')
console.log(symbol2);//Symbol('two')
3. 内置Symbol值
  • 除了定义自己使用的Symbol 值以外,ES6 还提供了11个内置的 Symbol 值,指向语言内部使用的方法
    Symbol.iterator
  • 对象的Symbol.iterator 属性,指向该对象的默认遍历器方法

iterator接口机制

  • 概念:iterator 是一种接口机制,为各种不同的数据结构提供统一的访问机制
  • 作用:
    1.为各种数据结构,提供一个统一的,简便的访问机制
    2.使得数据结构的成员能够按某种次序排列
    3.ES6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费
  • 工作原理:
    • 创建一个指针对象(遍历器对象),指向数据结构的起始位置
    • 第一次调用next方法,指针自动指向数据结构的第一个成员
    • 接下来调用next方法,指针会一直往后移动,直到指向最后一个成员
    • 每调用next方法返回的是一个包含value的done的对象,{value: 当前成员的值, done: 布尔值}
      • value表示当前成员的值,done对应的布尔值表示当前的数据是否遍历结束。
      • 当遍历结束的时候返回的value值是underfinded,done值为false
        原生具备iterator接口的数据(可用for of遍历)

扩展理解

  1. 当数据结构上部署了Symbol.iterator接口,该数据就是可以用 for of遍历
  2. 当使用for of去遍历目标数据的时候,该数据会自动去找Symbol.iterator 属性
    1.Array
    2.arguments
    3.set容器
    4.map容器
    5.String
//将iterator接口部署到指定的数据类型上,可以使用 for of 去循环遍历
//数组,字符串,arguments,set容器,map容器

let str = 'abcdegf'
for(let i of str){
    console.log(i)
}

    // 对象的Symbol.iterator属性;
    let myIterable = {};
    myIterable[Symbol.iterator] = function* () {
      yield 1;
      yield 2;
      yield 4;
    };
    for(let i of myIterable){
      console.log(i);
    }
    let obj = [...myIterable];
    console.log(obj);
  • 当使用for of 去遍历某一个数据结构的时候,首先去找Symbol.iterator,找到了就去遍历,没有找到的话不能遍历 xxx is not iterable
  • 使用三点运算符,解构赋值,默认去调用iterator接口

Generator函数简介

  • 概念:
    1. ES6提供的解决异步编程的方案之一
    2. Generator函数是一个状态机,内部封装了不同状态的数据
    3. 用来是生成遍历器对象
    4. 可暂停函数(惰性求值),yield 可暂停,next 方法可启动。每次返回的是 yield 后的表达式结果
  • 特点
    1. function 与函数名之间有一个星号
    2. 内部用 yield 表达式来定义不同的状态
    3. generator函数返回的是指针对象(iterator),而不会执行函数内部逻辑
    4. 调用 next 方法函数内部逻辑开始执行,遇到yield 表达式停止,返回{value: yield后的表达式结果/undefined, done
    5. 再次调用next方法会从上一次停止时的 yield 处开始,直到最后
    6. yield 语句返回结果通常为 undefined,当调用 next 方法时传参内容会作为启动时 yield 语句的返回值
function* generatorExample(){
    let result = yield 'hello'; // 状态值为 hello,result 为 undefined,除非启动时 next() 有传参进来
    yield 'generator'; //状态值为generator
}

  • 应用
function getNews(url) {
    $.get(url, function (data) {
        console.log(data)
        let url = 'http://localhost:3000' + data.commentsUrl;
        SX.next(url)
    })
}

function* sendXml() {
    let url = yield getNews('http://localhost:3000/news?id=3')
    yield getNews(url)
}

let SX = sendXml()
SX.next()

async 函数(源自与ES2017)

  • 概念:真正意义上去解决异步回调的问题,同步流程表达异步操作
  • 本质:Generator的语法器
  • 语法:
async function foo(){
    await 异步操作;
    await 异步操作;
}
  • 特点:
    1. 不需要像 Generator 去调用 next 方法,遇到await 等待,当前的异步操作完成就往下执行
    2. 返回的总是 Promise 对象,可以用 then 方法进行下一步操作
    3. async 取代 Generator 函数的星号*, await 取代 Generator 的 yield
    4. 语意上更为明确,使用简单,经临床验证,暂时没有任何副作用以及不良反应
    // 案例演示
    async function sendXml(url) {
      return new Promise((resolve, reject) => {
        $.ajax({
          url,
          type: 'GET',
          success: data =>  resolve(data),
          error: error => reject(error)
        })
      })
    }

    async function getNews(url) {
      let result = await sendXml(url);
      let result2 = await sendXml(url);
      console.log(result, result2);
    }
    getNews('http://localhost:3000/news?id=2')

应用技巧

async function sendXml() {
    let result = await getNews('http://localhost:3000/news?id=7')
    if(!result) {
        alert('暂时没有新的新闻')
        return
    }
    result = await getNews('http://localhost"3000' + result/commentsUrl);
}
sendXml();

class

  1. 通过class 定义类/实现类的继承
  2. 在类中通过 constructor 定义构造方法
  3. 通过 new 来创建类的实例
  4. 通过 extends 来实现类的继承
  5. 通过 super 调用父类的构造方法
  6. 重写从父类中继承的一般方法
  • 在类里面定义的所有方法都会放在原型上
class Person {
    //类的构造方法
    constructor(name, age) {
        this.name = name
        this,age = age
    }
    
    //类的一般方法
    //必须用简写方式
    showName() {
        console.log(this.name)
    }
}

let person = new Person('kobe', 39)
person.showName() //kobe
class StarPerson extends Person {
    constructor(name, age, salary){
        super(name, age) //调用父类的构造方法
        this.salary = salary
    }
}

let p1 = new StarPerson('wade', 36, 10000000000000)

字符串的扩展

  1. includes(str): 判断是否包含指定的字符串
  2. starsWith(str): 判断是否以指定的字符串开头
  3. endWith(str): 判断是否以指定的字符串结尾
  4. repeat(count): 重复指定次数
let str = 'ab'
console.log(str.includes('t'))//false

数值的扩展

  1. 二进制与八进制数值表示法:二进制用 0b,八进制用 0o
  2. Number.isFinite(i):判断是否是有限大的数
  3. Number.isNan(i):判断是否为 NaN
  4. Number.isInterger(i):判断是否是整数
  5. Number.parseInt(str):将字符串转换为对应的数值
  6. Math.trunc(i):直接去除小数部分
console.log(0b1010) //10
console.log(o056) //46

数组的扩展

  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 btns = documents.getElementsByTagName('button')
Array.from(btns).forEach....

let arr2 = [2, 3, 4, 2, 5, 7, 3, 6, 5]
let result = arr2.find(function (item, index) {
    return item > 4
})
console.log(result)

对象方法的扩展

  1. Object.is(v1, v2)
    • 判断两个数据是否完全相等
    • 底层是用字符串来判断
  2. Object.assign(target, source1, source2..)
    • 将原对象的属性复制到目标对象上
  3. 直接操作 __proto__ 属性
    • 以前不能(以前只能操作 prototype 属性)
    • let obj2 = {};
      obj2.__proto__ = obj1
console.log(0 == -0) //true
console.log(NaN == NaN) //false
console.log(Object.is(0, -0)) //false
console.log(Object.is(NaN, NaN))//true

深度克隆

在堆中,对基本数据类型的复制,是生成一段新的内存
对对象的复制操作,是指向原来的对象(复制了一份引用)
拷贝数组/对象,没有生成新的数据而是复制了一份引用

  • 拷贝数据:

    1. 基本数据类型:
      拷贝后会生成一份新的数据,修改拷贝以后的数据不会影响元数据
    2. 对象/数组:
      拷贝后不会生成新的数据,而是拷贝引用,修改拷贝以后的数据会影响原来的数据
  • 拷贝数据的方法:

    1. 直接赋值给一个变量 (浅拷贝)
    2. Object.assign() (浅拷贝)
    3. Array.prototype.concat() (浅拷贝)
    4. Array.prototype.slice() (浅拷贝)
    5. JSON.parse(JSON.stringify()) (深拷贝),拷贝的数据里不能有函数
      要求放入的原生的js对象(obj/arr)
  • 浅拷贝(对象/数组):

    • 特点:拷贝的引用,修改拷贝以后的数据会影响原数据
  • 深拷贝(深度克隆)

    • 特点:拷贝的时候会生成新数据,修改拷贝以后的数据不会影响原数据
  • 思考:

    • 如何实现深度拷贝(克隆)
    • 拷贝的数据里有对象/数组
    • 拷贝的数据里不能有对象/数组,几时有对象/数组可以继续遍历对象,数组拿到里边每一项值,一直到拿到的是借本数据类型,然后再去复制,这就是深度拷贝。
  • 知识点储备

    • 如何判断数据类型,arr—>Array null —> Null
    1. typeof 返回的数据类型:String,Number,Boolean,Undefined,Object,Function
    2. Object.prototype.toString.call(obj)
let result = 'abcd'
result = [1, 3]
console.log(Object.prototype.toString.call(result).slice(8, -1))
  • for in 循环
    • 循环对象时拿到属性名
    • 循环数组时拿到下标
function checkeType(target) {
    return Object.prototype.toString.call(target).slice(8, -1)
}

//实现深度克隆 ---> 对象/数组
function clone(target) {
    //判断拷贝的数据类型
    let result, targetType = checkType(target)
    if(targetType === 'Object'){
        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'){
            result[i] = clone(value)
        } else {
            result[i] = value
        }
    }
    return result
}

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(key)
    • delete(key)
    • has(key)
    • clear()
    • size
let map = new Map([['aaa', 'username', 25], [36, 'age' ]])
console.log(map) //{"aaa" => "username", 36 => "age"}

for of 详解

  1. 遍历数组
  2. 遍历 Set
  3. 遍历 Map
  4. 遍历字符串
  5. 遍历伪数组
  • 去重
let arr = [1, 2, 4, 5, 5, 6, 3]
let arr1 = arr
arr = []
let set = new Set(arr1)
for(let i of set){
    arr.push(i)
}
console.log(arr)

ES7

  1. 指数运算符(幂):**
  2. Array.prototype.includes(value):判断数组中书否包含指定的value
console.log(3 ** 3);

猜你喜欢

转载自blog.csdn.net/qq_42496307/article/details/90245943