Day 81 ES6

ES6

var a = 2; 
var a = 5;
console.log(a);   // 5

let

1、let 声明变量,没有变量提升

console.log(b)    // Uncaught ReferenceError: Cannot access 'b' before initialization
let b = 3
console.log(b)    # 3

2、是一个块作用域

if(1===1){
     let c = 10;
     console.log(c)    // 10
 }
 console.log(c)        // Uncaught ReferenceError: c is not defined

3、不能重复声明

let d = 10;
let d = 20;
console.log(d)        // Uncaught SyntaxError: Identifier 'd' has already been declared

const

声明常量,一旦被声明,无法修改
const 声明变量,没有变量提升;是一个块作用域;不能重复声明

const max = 10;
const max = 20;        // Uncaught SyntaxError: Identifier 'max' has already been declared
console.log(max)

const 可以修改常量内的值

const dit = {
    "name":'ysg'
}
dit.name='ysging'
console.log(dit)    // {name: "ysging"}

作用

作用一:for循环的经典例子

var arr = []
for (var i = 0; i < 10; i++) {
    arr[i] = function () {
        return i
    }
}
console.log(arr[5]())    // 10

const arr = []
for (let i = 0; i < 10; i++) {
    arr[i] = function () {
        return i
    }
}
console.log(arr[5]())    // 5

作用二:不会污染全局变量

var count = 10;
console.log(count)               // 10
console.log(window.count)        // 10

let count = 10;
console.log(count)               // 10
console.log(window.count)        // undefined

建议:一般情况下使用 count 来声明变量,而只有你在知道变量值需要被修改的情况下使用 set 。

模板字符串

模板字符串:使用反引号,插入值:${}

const Box = document.querySelector('#box')
let name = 'ysg'
let id = 16
let htmlstr = `
    <ul>
        <li>
            <p id=${id}>${name}</p>
        </li>
    </ul>
`
Box.innerHTML = htmlstr

函数之默认值

function add(a=10,b=20){
    return a + b
}
console.log(add())

剩余参数

剩余参数:...参数名,解决了 arguments 的问题

function add(a,...keys){
    let res = Object.create(null);
    for(let i=0; i<keys.length; i++){
        res[keys[i]] = a[keys[i]]
    }
    return res        # {name: "ysg", age: "16", city: "新乡"}
}
let dit = {
    'name':'ysg',
    'age':'16',
    'city':'新乡'
}
console.log(add(dit,'name','age','city'))

扩展运算符:将一个数组分割,并将各个项作为分离的参数传递给函数

const arr = [12,485,85,156,54,1,6,]
console.log(Math.max(...arr))

箭头函数

箭头函数:使用 => 来定义,相当于 function(){} 等于 ()=>{}

// 无参数
let fun = () => "Hello world" + ' 123'
console.log(fun())

let fun = () =>({'name':'ysg','age':'16'})
console.log(fun())


// 一个参数
let fun = val => val
console.log(fun(10))

// 两个参数
let add = (a,b) => {
    return a + b
}
console.log(add(10,20))


let add = (a,b) => a + b
console.log(add(10,20))

// 闭包函数
let fn = (()=>{
    return ()=>{
        console.log('hello world')
    }
})();

fn();

 

箭头函数没有 this 指向,箭头函数内部 this 值只能通过查找作用域链接来确定

let PageHandle = {
    id:123,
    init:function(){
        // 箭头函数没有 this 指向,箭头函数内部 this 值只能通过查找作用域链接来确定
        document.addEventListener('click',(event)=>{
            this.dcSomeThings(event,type)
        },false)
    },

    dcSomeThings:function(type){
        console.log(`事件类型:${this},当前id:${this.id}`);
    }
}
PageHandle.init();

注意:

使用箭头函数注意事项:

1、函数内部没有 arguments

2、不能使用 new 关键字实例化对象

解构赋值

解构赋值是对赋值运算符的一种扩展,它针对数组和对象进行操作;优点:代码书写更简洁易读。

let dit = {
    'name':'ysg',
    'age':'17'
}
let {name,age} = dit
console.log(name,age)  // ysg 17


let list = [1,2,3];
let [a,b,c] = list
console.log(a,b,c)    // 1 2 3

对象的扩展功能

 ES6 允许直接写入变量和函数,作为对象的属性和方法

const name = 'ysg',age = 20
const person = {name,
                age,
                sayName(){
                    console.log(this.name)
}}
person.sayName()
let cart={
    wheel:4,
    set(newVal){
        if (newVal < this.wheel) {
            throw new Error('轮子太少了')
        }
        this.wheel = newVal;
    },
    get(){
        return this.wheel;
    }

}
cart.set(7);
console.log(cart.get());
View Code

对象的方法

is() 等价于 === ,比较两个字是否严格相等

console.log(NaN === NaN)  // false
console.log(Object.is(NaN,NaN))  // true

assign() 用户对象的合并

let newObj = Object.assign({c:3},{a:1},{b:2})
console.log(newObj)     # {c: 3, a: 1, b: 2}

Synbol 类型

原始数据类型,它表示独一无二的值,最大的用途:用来定义对象的私有变量
独一无二意味着内存地址不同

// 定义
const name = Symbol('name')
const name2 = Symbol('name')
console.log(Object.is(name,name2))    // false

// 取值
let s1 = Symbol('ysg')
console.log(s1)        // Symbol(ysg)
let obj = {
    [s1] : '小马哥' 
}
console.log(obj)    // {Symbol(ysg): "小马哥"}
// 方法一:
console.log(obj[s1])    // 小马哥

// 方法二:
let s = Object.getOwnPropertySymbols(obj)
console.log(s[0])

// 方法三:反射
let m = Reflect.ownKeys(obj);
console.log(m)
View Code

Set 集合

是一组无重复的有序列表

// 新建集合
    let set = new Set()
    console.log(set)  // Set(0) {}
      
    // 添加数据
    set.add(1)
    set.add(2)
    set.add(2)
    console.log(set)    // {1, 2}

    // 校验数据
    console.log(set.has(2))  // true

    // 查看长度
    console.log(set.size)  // 2

    // 删除数据
    set.delete(2);
    console.log(set)  // Set(1) {1}

    // 将 set 转为数组
   let set2 = new Set([1,2,4,5,6])
   let lsit = [...set2]
   console.log(lsit)  // [1, 2, 4, 5, 6]
View Code

 

注意:Set 中对象的引用无法被释放,一般是 WeakSet() 来引用

weakSet

1、不能传入非对象类型的参数

2、不可迭代

3、没有 forEach()

4、没有 size 属性

Map 类型

是一组键值对的有序列表,键和值可以是任意类型

let map2 = new Map([
    ['张三','zhangsan'],
    ['李四','lisi']
]);
console.log(map2);

let map = new Map()
map.set('name','ysg')
map.set('age','16')
console.log(map)

console.log(map.get('name'))
console.log(map.has('name'))
console.log(map.size)

map.delete('name')
console.log(map)

map.clear()
console.log(map)
View Code

数据的扩展

from() 将维数组转为真正的数组

<div id = 'box'>    
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</div>


# 简单实例
   function add(){
       let arr = Array.from(arguments)
       console.log(arr);
   }

   add(1,2,3)

   let li = document.querySelectorAll('li')
   
   // from 
   let list = Array.from(li)
   console.log(list)

   // 扩展运算符
   let lis = [...li]
   console.log(lis)

   // from 还可以传递第二个参数,用来对每个元素进行处理
   let list2 = Array.from(li,li=>li.textContent)
   console.log(list2)
View Code

of() 将任意一组数值,转换为数组

of_list = Array.of('1','2','3')
console.log(of_list)
View Code

copyWithin() 数组内部将指定位置的元素复制到其它的位置,返回当前数组

list = [1,2,3,4,5,6,7,8].copyWithin(0,3)
console.log(list)
View Code

find() 查找元素,返回第一个符合条件的元素

findindex() 查找索引,返回第一个符合条件的元素下标

let num = [1,2,3,4,5,6,7,8].find(n => n > 6)
console.log(num)    // 7

let num2 = [1,2,3,4,5,6,7,8].findIndex(n => n > 6)
console.log(num2)    // 6
View Code

keys()、values()、entries() 遍历器,可以使用 for ... of 循环进行遍历

   for(let index of ['a','b'].keys()){
       console.log(index)  // 索引:0 1 
   }

   for(let index of ['a','b'].values()){
       console.log(index)  // 值:a b
   }

   for(let index of ['a','b'].entries()){
       console.log(index)  // 索引,值:(2) [0, "a"]  (2) [1, "b"]
   }
View Code

includes() 返回一个布尔值,表示某个数组是否包含指定的值

console.log([1,2,3].includes(3))  // true
console.log([1,2,3].includes(4))  // false
View Code

迭代器

1、迭代器是一个接口,能快捷的方位数据,通过 Symbol.iterator 来创建迭代器,通过迭代器的 next() 获取值
2、迭代器是用于遍历数据结构的指针(类似于数据库中的游标)

const items = ['ysg','ysging','czx']
const ite = items[Symbol.iterator]();

console.log(ite.next());        // {value: "ysg", done: false} done 如果为 false,表示遍历继续,为 true 表示遍历完成 
console.log(ite.next());
console.log(ite.next());
console.log(ite.next());

生成器

generator 函数,可以通过 yield 关键字,将函数挂起,为了改变执行流提供了可能,同时为异步编程提供了方案
语法:function* add() { yield x}

function* add() {
    console.log('one')
    let x = yield '2';
    console.log('one:' + x)
    let y = yield '3';
    console.log('two:' + y)
    return x + y;
}

const fn = add();            // one
console.log(fn.next());        // {value: "2", done: false}
console.log(fn.next(30));      // {value: "3", done: false}
console.log(fn.next(20));    // {value: 50, done: true}
View Code

使用场景,为不具备 Interator 接口的对象提供了遍历操作。

Promise 承诺

相当于一个容器,保存着未来才会结束的事件(异步操作)的一个结果
各种异步操作都可以用同样的方法进行处理 axios
特点:
  1.对象的状态不受外部影响 处理异步操作,三个状态 Pending(进行) Resolved(成功) Rejected(失败)
  2.一旦状态改变,就不会在变,任何时候都可以得到这个结果。

function timeOut(ms) {
    return new Promise((resolved,Rejected)=>{
        setTimeout(() => {
            resolved('hello promise success!!!')
        },ms);
    })
}

timeOut(2000).then((val)=>{
    console.log(val)     // hello promise success!!!
})
View Code

Promise对象的其它用法

resolve()  reject()  all()  race()  done()  finally()

resolve() 将任意类型的对象转为 promise 对象
reject() 与 resolve() 效果一样

let p = new Promise(resolve=>resolve('foo'));
p.then((data)=>
    console.log(data)    // foo
)
console.log(p)    // Promise {<resolved>: "foo"}
View Code

all() 所有异步 Promise 方法执行成功,才执行后续内容

应用:一些游戏类的素材比较多,等待图片、flash、静态文件 都加载完成,才进行页面的初始化

let p1 = new Promise((resolve,reject)=>{});
let p2 = new Promise((resolve,reject)=>{});
let p3 = new Promise((resolve,reject)=>{});

let p = Promise.all([p1,p2,p3])
p4.then(()=>{
    // 三个都成功,则成功

}).catch(err=>{
    // 如果一个失败,则失败
})
View Code

race() 用于设置超时时间,并在超时后执行相应的操作
请求图片资源

function requestImg(imgSrc) {
    return new Promise((resolve,reject)=>{
        const img = new Image()
        img.onload = function() {
            resolve(img)
        }
        img.src = imgSrc
    });
}

function timeout(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            reject('图片请求超时')
        },1000)
    })
}
Promise.race([requestImg('https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1594089011992&di=9847cc1d804fbccdf77e67d9bcdc61aa&imgtype=0&src=http%3A%2F%2Fi4.17173.itc.cn%2F2010%2Fnews%2F2010%2F03%2F01%2Ft0301syu01s.jpg'),timeout()]).then(res=>{
    console.log(res)
}).catch(err=>{
    console.log(err);
})
View Code

done() finally() 无论 Promise 成功与否,都执行其中的内容,比较少用

async的用法

作用:使得异步操作更加方便
基本操作:async 它会返回一个 Promise 对象,then catch
async 是 Generator 的一个语法糖

// 成功的操作
async function fun() {
    let s = await 'hello world'
    let data = await s.split('')
    return data;
}
fun().then(v=>{console.log(v)}).catch(e=>console.log(e))


// 失败的操作
async function fun2() {
    try{
        throw new Error('出错了')
    }catch(errer){

    }
    return await Promise.resolve('hello')
}

fun2().then(v=>{console.log(v)}).catch(e=>console.log(e))
View Code

class类的用法

class Person {
        // constructor 实例化的时候会立即被调用
        constructor(name,age){
            this.name = name
            this.age = age
        }
        // 添加方法 方法一
        // getName(){
        //     return this.name
        // }
        // getAge(){
        //     return this.age
        // }
   }

   // 添加方法 方法二
   // 通过 Object.assign() 一次性向类中添加多个方法(用的不多)
   Object.assign(Person.prototype,{
           getName(){
               return this.name
           },
           getAge(){
               return this.name
           }
   })


   let p = new Person('ysg',16)
   // console.log(p)  // Person {name: "ysg", age: 16}
   console.log(p.getName())  // ysg
View Code

类的继承  

class Animal{
    constructor(name,age){
        this.name = name
        this.age = age
    }
    getName(){
        return this.name
    }
    getAge(){
        return this.age
    }
}

class Dog extends Animal{
    constructor(name,age,color){
        super(name,age);
        this.color = color;
    }
    // 新建类
    getColor(){
        return this.color
    }

    // 重写类
    getName(){
        return this.name + this.age + this.color
    }
}

let d = new Dog('小左',3, 'red')
console.log(d.getName())
console.log(d.getColor())
View Code

ES6的模块化实现

es6主要有两个命令构成:export 和 import

exprot:用于规定模块的对外接口

import:用于输入其它模块提供的功能

一个模块就是一个独立的文件

模块文件:index.js

// 方法一
export name = 'ysg'
export function fun() {
        // body...
        return 'my name is ' + name
    }

// 方法二
age = '16'
function fun2(){
    return '年龄: ' + age
}
export{
    age,fun2
}

// 方法三,使用别名
class Person(){
    constructor(){

    }
    getAge(){
        console.log(age)
    }
    getName(){
        console.log(name)
    }
    
}

export default Person
View Code

调用文件:model.html

import {name} from './index.js'
console.log(name)

// 使用别名调用
import Person from './index.js'
const p = new Person();
console.log(Person(p.getName))
View Code

 

posted @ 2020-07-07 10:15  亦双弓  阅读(143)  评论(0编辑  收藏  举报