# es6 学习笔记

es6 学习笔记

let变量

let和var用法级别一样

let不能重复声明,但是var可以

var varIns = "A";
var varIns = "B"; // 合法
let letIns = "A";
let letIns = "B"; // 不合法

let具有块级作用域,var没有

const变量

const定义后不能修改

const和let一样,只能作用在局部,块级作用域

    const SCHOOL = '新蔡一高'
        // SCHOOL = 'kkkl'  报错不能修改
    const a = 123; //一般是大写
    {
        const cs = 12
    }
    // console.log(cs);  和let一样只能作用局部,在块级作用域
    const ITEM = ['lk', 'kkl', 'jkjld'];
    ITEM.push('jsj');

定义字符串补充:

``我们可以用这个定义字符串,并且换行的时候不用加引号,不会报错

用引号不行,只能用反引号才来使${}表达式转换,否则输出还是原来的样子

 console.log("=======es6的新特性===========");
    // 可以用``这个符号表示字符串,并且换行不需要加引号和++
    let str = `我是
    一个字符串`;
    console.log(str);
    var str1 = `k
    lk`;
    console.log(str1);
    let love = '小王';
    let out = `${love}是最好的人`;
    let out1 = '${love}是最好的人'; //用引号不行,只能用反引号才来使${}表达式转换,否则输出还是原来的样子
    console.log(out1);
    console.log(out);

箭头函数

  var div = document.querySelector('div');
    div.addEventListener('click', function() {
        let _this = this;
        setTimeout(function() {
            // 普通函数this指向有问题我们需要this是指向div而普通函数指向window
            //   解决方法1:在定时器外面将this指向div
            console.log(this);
            _this.style.backgroundColor = 'pink';
            console.log(_this);
        }, 1000);
        // 解决方法2: 将定时器改成箭头函数  箭头函数表示在定义时的作用域就是div
        // setTimeout(() => {
        //     this.style.backgroundColor = 'pink';
        // }, 1000);

    })

普通函数this指向有问题我们需要this是指向div而普通函数指定时器的回调函数指向window
解决方法1:在定时器外面将this指向div

箭头函数指向就是谁调用的就是谁的this,定时器没有自己的this,向外面找就是div的

rest参数

普通函数中有arguments这个搜集参数

 let fu = function() {
        console.log(arguments);
    }
    fu(1, 2, 3);

而普通方式arguments是对象,而es6中rest参数返回的字符串,而字符串有利于操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0RDncvJV-1666349132206)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20221006000026251.png)]

rest序列扩展符返回的是数组

 function data(...args) {
        console.log(args);
    }
    data('kkl', 'kk', 'huang')
    console.log("==========================");
    //序列扩展符
    const tf = ['xz', 'xl', 'xc'];

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UJ5jRGsT-1666349132207)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20221006000111274.png)]

数组的合并:

利用扩展符将数组结合

 // 1.数组的合并
    const a1 = ['xh', 'xz'];
    const b1 = ['xc', 'xk'];
    const c1 = a1.concat(b1); //数组的属性合并函数
    console.log(c1);
    const c2 = [...a1, ...b1]; 扩展符的特性
    console.log(c2);

数组的克隆

  // 2数组的克隆
    const a2 = ['E', 'G', 'M'];
    const b2 = [...a2];
    console.log(b2);

Symbol

Symbol是ES6引入的一种新的数据类型

用来表示独一无二的值

他是一种类似于字符串的值,保证值是唯一的

Symbol值不能参与任何一种运算,外部也看不到Symbol的值是多少, 只能知道分别定义两个Symbol一定是不同的

Symbol的作用非常的专一,换句话说其设计出来就只有一个目的——作为对象属性的唯一标识符,防止对象属性冲突发生。

let info1 = {
    name: '婷婷',
    age: 24,
    job: '公司前台',
    description: '平时喜欢做做瑜伽,人家有男朋友,你别指望了'
}
let info2 = {
    description: '这小姑娘挺好的,挺热情的,嘿嘿嘿……'
}

当数据繁琐多的时候

就会导致一个对象属性有两个会发生冲突

let info1 = {
    name: '婷婷',
    age: 24,
    job: '公司前台',
    [Symbol('description')]: '平时喜欢做做瑜伽,人家有男朋友,你别指望了'
}
let info2 = {
    [Symbol('description')]: '这小姑娘挺好的,挺热情的,嘿嘿嘿……'
}

这样将两个对象复制就不会出现问题,这样两个属性都会显示,不会被覆盖

let target = {};
Object.assign(target, info1, info2);

输出:
{name: "婷婷", age: 24, job: "公司前台", Symbol(description): "平时喜欢做做瑜伽,人家有男朋友,你别指望了", Symbol(description): "这小姑娘挺好的,挺热情的,嘿嘿嘿……"}

迭代器

迭代器是一种接口,各种数据结构只要在定义的时候定义了Iterator接口(就是对象就具有Iterator成员变量)就可以完成迭代操作

  • ES6原生具备Iterator的对象有
    • Array
    • Arguments
    • Set
    • Map
    • String
    • TypedArray
    • NodeList

Iterator的使用方法与c++的迭代器相似,创建的时候迭代器变量获取对象,在的迭代器.next()后,next函数返回一个指向数据结构的首地址,使用next进行指针的 移动获取值,不断调用next达到数据结构

   const xyj = ['xw', 'xz', 'xh', 'xk'];
    for (let v in xyj) { 
        for in 遍历数组v是索引
        console.log(v);
    }
    for of遍历的数组是value值
    for (let v of xyj) {
        console.log(v);
    }
     调用对象的next方法
    let iterator = xyj[Symbol.iterator]();
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next()); //结束返回value值为undefined done值为true

调用结果
{value: "A", done: false}     // 返回值是一个对象,包含value和done表示是否结束迭代
{value: "B", done: false}
{value: "C", done: false}
{value: undefined, done: true}    // 遍历结束后设置done=true

补充for循环遍历

for in 便历出来的是属性的index索引

  • for of遍历的是value
  • 手动给对象添加属性后, for in 是可以将新添加的属性遍历出来 但是for of 不行
  • for in 的属性是使用[]不可以使用 “.” eg: data[‘index’] instead of data.index

自定义迭代器

现在有一个对象其中有一个stus数组,我们想进行遍历,但是我们不想直接用foreach遍历因为这样会使school对象不安全,达不到面向对象的思想

    const school = {
        name: '28班',
        stus: [
            'xiaoh',
            'xiaosz',
            'xiaoc',
            'xiaok'
        ],

我们现在可以自己定义迭代器

在对象中都有Symbol.iterator属性,指向该对象的默认遍历器方法

我们将Symbol.iterator属性,改写输出为对象的stus的值

在根据stus的长度判断是否结束,当Symbol属性返回对象中的done属性为false就结束next的移动

[Symbol.iterator]() {
            let index = 0;
            let _this = this;
            return {
                next: function() {
                    if (index < _this.stus.length) {
                        const result = {
                            value: _this.stus[index],
                            done: false
                        };
                        index++;
                        return result;
                    } else {
                        return {
                            value: undefined,
                            done: true
                        };

                    }
                }
            }
        }
    }

生成器

生成器是一个函数,是一个ES6异步编程解决方案, 之前我们异步编程使用的是回调函数,但是容易形成回调地狱

定义: 生成器函数与就是在普通函数声明前面加入了*

function * gen(){
  console.log("hi");
  return "GEN OK"
}

我们可以把函数返回的值赋值给变量,变量是一个迭代器,当变量执行了next,如果嵌套可能还是迭代器,如果就只有一层那么就返回值return

function * gen(){
  console.log("hi");
  return "GEN OK"  返回
}

let p = gen();
console.log(p);     // p是gen {<suspended>} 是一个迭代器
let q = p.next()    // 执行next 输出hi 
console.log(p,q);   // p是gen {<closed>} 迭代器 q是迭代器结果{value: "GEN OK", done: true}

生成器函数可以被yield分割

yield是ES6的新关键字,使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。

yield关键字实际返回一个IteratorResult(迭代器)对象,它有两个属性,value和done,分别代表返回值和是否完成。

function * gen(){               
  // ====函数第1部分====
  console.log("Part 1");
  yield "P1"                  // == 返回"P1" 不得用return否则后面代码都无效了
  // ====函数第2部分====
  console.log("Part 2");
  yield "P2"                  // == 返回"P2" 不得用return否则后面代码都无效了
  // ====函数第3部分====
  console.log("Part 3");
  yield "P3"                  // == 返回"P3" 不得用return否则后面代码都无效了
  // ====函数第4部分====
  console.log("Part 4");
  yield "P4"                  // == 返回"P4" 不得用return否则后面代码都无效了
  // ====函数第5部分====
  return "AllEnd"             // == 返回"AllEnd" 不得用yield会新开一个部分
}

let f = gen();

console.log(f.next())         // { value: 'P1', done: false }
console.log(f.next())         // { value: 'P2', done: false }
console.log(f.next())         // { value: 'P3', done: false }
console.log(f.next())         // { value: 'P4', done: false }
console.log(f.next())         // { value: 'AllEnd', done: true }
console.log(f.next())         // { value: undefined, done: true }

如果想给某个函数传参数可以将参数写在next函数中,yield可以接收到

function * gen(a){
    console.log(a)
    let b = yield "===PART B==="
    console.log(b)
    let c = yield "===PART C==="
    console.log(c)
    let d = yield "===PART D==="
    console.log(d)
}

let it = gen(5);  a=5
console.log(it.next(4)) 
console.log(it.next(3)) b=3
console.log(it.next(2)) c=2
console.log(it.next(1)) d=1
console.log(it.next(0))     // over bound

现在要求1-5s分别输出1-5数字,可以使用回调函数

setTimeout(() => {
        console.log(111);
        setTimeout(() => {
            console.log(222);
            setTimeout(() => {
                console.log(333);
            }, 3000);
        }, 2000);
    }, 1000);

利用定时器,我们会发现如果要求高的话就会无限套娃,变成回调地狱

下面我们用生成器完成条件

  function one() {
        setTimeout(() => {
            console.log(111);
            iterator.next();
        }, 1000);
    }

    function two() {
        setTimeout(() => {
            console.log(222);
            iterator.next();
        }, 2000);
    };

    function three() {
        setTimeout(() => {
            console.log(333);
            iterator.next();
        }, 3000);
    };

    function* gen() {
        yield one()
        yield two()
        yield three()
    }
    let iterator = gen();
    iterator.next();
 console.log("==============每秒输出加5的数=============");

    function* gen(p1) {
        setTimeout(() => {
            console.log(p1);
            it.next(p1 + 5);
            console.log(111);
        }, 1000);
        let p2 = yield 'p2'
        setTimeout(() => {
            console.log(p2);
            it.next(p2 + 5);
        }, 1000);
        let p3 = yield 'p3'
        setTimeout(() => {
            console.log(p3);
            it.next(p3 + 5);
        }, 1000);
        let p4 = yield 'p4'
        setTimeout(() => {
            console.log(p4);
            it.next(p4 + 5);
        }, 1000);
        let p5 = yield 'p5'
        setTimeout(() => {
            console.log(p5);
            it.next(p5 + 5);
        }, 1000);
    }
    let it = gen(1);
    // it.next();

Promise

promise是异步编程的解决方案,从语法上来说promise是一个对象,从它可以获取异步操作的消息,

promise状态不受外界影响promise对象有一个异步操作,有三种状态:pending(进行时),fulfilled(已成功)reject(已失败)

一但状态改变,就不会再变,resolve(已经定型)

 const p = new Promise(function(resolve, reject) {
            setTimeout(function() {
                // let data = '数据成功';
                // resolve(data);
                let err = '读取失败'
                reject(err)
            }, 1000)
        })
        //调用prmoise对象的then方法
    p.then(function(value) {
        console.log(value); //数据成功调用resolve函数返回的then的第一个函数value值上
    }, function(reason) {
        console.log(reason);
    })

promise读取文件

const fs = require('fs');
// fs.readFile('为学.md', function(err, data) {
//     if (err) throw err;
//     console.log(data.toString());
// })

// 使用Promise封装
const p = new Promise(function(resolve, reject) {
    fs.readFile('为学.md', (err, data) => {
        if (err) reject(err)
        resolve(data);
    })

})
p.then(function(value) {
    console.log(value.toString());
}, function(err) {
    console.log(err);
})

promise的then方法

then方法是有两个参数的,而这两个参数都是函数,第一个函数是resolve状态的回调函数,

第二个函数是reject状态的回调函数

    const p = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('用户数据')
        }, 1000);
    })
    const result = p.then(function(value) {
        console.log(value);
    }, function(err) {
        console.log(err);
    })
    console.log(result);

读取多个文件

方法一:直接用readFile函数读取,在进行叠加

缺点也是嵌套麻烦

let fs = require('fs');
fs.readFile('木瓜.md', (err, data1) => {
    fs.readFile('江南.md', (err, data2) => {
        fs.readFile('为学.md', (err, data3) => {
            let value = data1 + data2 + data3;
            console.log(value);
        })
    })
})

利用promise读取多个文件

就是利用then进行链式编程

let p = new Promise((resolve, reject) => {
    fs.readFile('木瓜.md', (err, data) => {
        resolve(data);
    });
})
p.then(value => {
    //向下继续传递value
    return new Promise((resolve, reject) => {
        fs.readFile('江南.md', (err, data) => {
            resolve([value, data])
        })
    })
}).then(value => {
    return new Promise((resolve, reject) => {
        fs.readFile('为学.md', (err, data) => {
            value.push(data);
            resolve(value);
        })
    })
}).then(value => {
    console.log(value.join('\r\n'));
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值