ES6笔记合集

let和const

let变量声明及声明特性

  1. 声明同var,可同时声明多个变量,可在声明时赋初始值。
  2. 【特性】变量不能重复声明。
  3. 【特性】块级作用域。在作用域中声明的变量外部不能访问。
  4. 【特性】不存在变量提升
  5. 不影响作用域链的效果

let 可用于解决闭包问题。for(var i = 0; i < 3; i++){ },由于 var 没有块级作用域,声明的 i 在全局中,循环结束后 i 都会变成 3(执行循环中的函数时,i 已经变成 3 了)。用 let 声明,相当于在三个代码块里声明了三个 i ,它们是互不影响的。

const声明及声明特性
  1. 声明同varlet
  2. 【特性】声明一定要赋初始值
  3. 【特性】常量的值不能修改
  4. 【特性】块级作用域
  5. 对于数组和对象的元素修改,不算对常量的修改,不会报错(因为常量保存的引用并没有被修改)
  6. 一般常量声明使用大写



变量的解构赋值

ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值。这称为解构赋值

  1. 数组的解构
        const nums = [1,2,3,4];
        let [one, two, three, four] = nums;
        console.log(one);       //1
        console.log(two);       //2
        console.log(three);     //3
        console.log(four);      //4
  1. 对象的解构
        const ppp = {
     
            name: 'ppp',
            num: '131509',
            game: function(){
     
                console.log("fps...");
            }
        };
        let {
     name,num,game} = ppp;
        console.log(name);      //ppp
        console.log(num);       //131509
        game();                 //fps...



模板字符串

ES6引入新的声明字符串的方式【 ` ` 】反引号

  1. 【特性】内容中可以直接出现换行符
  2. 【特性】直接变量拼接
		let num1 = `12123`;
        let num2 = `131509`;
        let num = `${
       num1}${
       num2}`;
        console.log(num);   		//12123131509



对象的简化写法

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。

        let num1 = '23';
        let num2 = '38';
        let sum = function(){
     
            console.log(num1+num2);
        }
        const math = {
     
            num1,
            num2,
            sum,
        }
        console.log(math);



箭头函数

  1. 声明一个函数:let fn = function(){ } ----> let fn = () =>{ }
  2. 【特性】this是静态的,this始终指向函数声明时所在作用域下的 this 的值。(函数直接调用时 this 是指向window的,【使用call调用方法可改变 this 指向,this可指向call()的第一个参数,但箭头函数用call调用也不会改变this指向】)
  3. 【特性】不能作为构造函数实例化对象。(实例化对象过程中 this 的作用)
  4. 【特性】不能使用 arguments 变量。
  5. 箭头函数的简写。
    1)省略小括号,当形参只有一个的时候
    2)省略花括号,当代码体只有一条语句的时候,此时 return 也要省略,语句的执行结果就是函数的返回值
  6. 应用场景:箭头函数适合与 this 无关的回调。如定时器,数组的方法回调。
        let box = document.getElementsByClassName('box')[0];
        //绑定事件
        box.addEventListener("click", function(){
     
            //保存this的值
            //let _this = this;		
            setTimeout(() => {
     
                //_this.style.backgroundColor = 'pink';
                this.style.backgroundColor = 'pink';
            },2000);
        });



函数参数的默认值

ES6允许给函数参数赋初始值

  1. 赋初始值后,如果传了参数就使用所传的参数,没传可用初始值。
  2. 具有默认值的参数,一般位置要靠后
  3. 与解构赋值结合
        function connect({
     host,username,password}){
     
            console.log(host);
            console.log(username);
            console.log(password);
        }
        connect({
     
            host:'localhost',
            username:'root',
            password:'root'
        })



rest 参数

ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments

  1. ES5 获取实参的方式
function date(){
     
      console.log(arguments);		//结果是一个类数组
}
date('1','2','3');
  1. rest 参数
function date(...args){
     
      console.log(args);		//结果是一个数组
}
date('1','2','3');
  1. 一个形参对应多个实参,rest 参数必须放到最后。
function date(a,b,...args){
     
      console.log(a);
      console.log(b);
      console.log(args);		//3,4,5,6 会给到 args
}
date(1,2,3,4,5,6);



扩展运算符

【…】 扩展运算符能将【数组】转换为逗号分隔的参数序列

        const date=[1,2,3];
        function fn(){
     
            console.log(arguments);
        }
        fn(date);           //结果中只有一个值(数组)。
        fn(...date);        //会将数组转换,结果中有三个值。

ES6笔记合集_第1张图片

【应用】

  1. 数组的合并
        const num1 = [1,2,3];
        const num2 = [4,5,6];
        const sum = [...num1,...num2];
  1. 数组的克隆
        const num = [1,2,3,7];
        const numC = [...num];
  1. 将伪数组转为真正的数组【数组的方法就都可以使用了】
        const divs = document.querySelectorAll('div');
        const divArr = [...divs];



Symbol

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值,是 JavaScript 的第七种数据类型,是一种类似字符串的数据类型。

symbol 详情指路 阮一峰的ES6

特点

  1. symbol 的值是唯一的,用来解决命名冲突的问题。
  2. symbol 值不能与其他数据进行运算
  3. symbol 定义的对象属性不能使用 for…in 循环遍历,但是可以使用Reflect.oownKeys 来获取对象的所有键名。
  4. symbol 类型用于创建对象的唯一标识符

【 创建】

        let s1 = Symbol('张三');
        let s2 = Symbol('张三');
        console.log(s1 === s2);     //false

        let s3 = Symbol.for('张三');
        let s4 = Symbol.for('张三');
        console.log(s3 === s4);     //true

【使用】
symbol 是一个独一无二的值,可给对象添加属性和方法

//想向对象中添加方法 
        let game = {
     }
        
        //1. 下面的方法不好,无法确定对象中是否已有同样命名的方法
        //game.up = function(){
     
        //}
        
        //2. 使用 Symbol 添加
        // 1) 声明一个对象
        let methods = {
     
            up: Symbol(),
            down:Symbol()
        };
        // 2) 添加方法
        game[methods.up] = function(){
     
            console.log("正在上升");
        }
        game[methods.down] = function(){
     
            console.log("正在下降");
        }
//在对象中添加 Symbol 类型的方法
        let card = {
     
            name: '狼人杀',
            [Symbol('say')]: function(){
     
                console.log("发言中...");
            },
            [Symbol('kill')]: function(){
     
                console.log("选择要杀死的玩家...");
            }
        }
        card[Symbol('say')]();      //报错
//因为Symbol('say')生成的标识不是唯一的,所以定义的在 card 里面的[Symbol('say')]是无法调用的,除非把Symbol('say')放块外面定义,并用变量保存。


        let card = {
     
            name: '狼人杀',
            [Symbol.for('say')]: function(){
     
                console.log("发言中...");
            },
            [Symbol.for('kill')]: function(){
     
                console.log("选择要杀死的玩家...");
            }
        }
        card[Symbol.for('say')]();		//发言中....
//Symbol.for('say')产生的标识是唯一的,所以可以调用定义在 card 里面的[Symbol.for('say')]方法。

Symbol 内置值

内直值
Symbol.hasInstance 当其他对象使用 instanceof 运算符, 判断是否为该对象的实例时,会调用这个方法
Symbol.isConcatSpreadable 对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于 Array.prototype.conct() 时,是否可以展开
Symbol.unscopables 该对象指定了使用 with 关键字时,哪些属性会被 with 环境排除
Symbol.match 当执行 str,match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值
Symbol.replace 当该对象被 str.replace(myObject) 方法调用时,会返回该方法的返回值
Symbol.search 当该对象被 str.search(myObiect)方法调用时,会返回该方法的返回值
Symbol.split 当该对象被 str.split(myObiect)方法调用时,会返回该方法的返回值
Symbol.iterator 对象进行 for…of 循环时,会调用 Symbol.iterator 方法,返回该对象的默认遍历器
Symbol.toPrimitive 该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值
Symbol.toStringTag 在该对象上面调用 toString 方法时,返回该方法的返回值
Symbol.species 创建衍生对象时,会使用该属性



迭代器(遍历器) Iterator

迭代器 (Iterator) 是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。

  1. ES6创造了一种新的遍历命令 for…of 循环, Iterator 接口主要供 for…of 消费
  2. 原生具备 iterator 接口的数据(可以 for of 遍历)【Array Arguments Set Map String TypedArray NodeLIst】
        const xiyou = ['tang','sun','zhu','sa']
        //使用 for...of 遍历数组,得到的是键值
        for(let v of xiyou){
     
            console.log(v);     //tang sun zhu sa
        }
        //使用 for...in 遍历,得到的是键名
        for(let k in xiyou){
     
            console.log(k);     //0 1 2 3
        }
  1. 工作原理
    1)创建一个指针对象,指向当前数据结构的起始位置
    2)第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
    3)接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
    4)每调用 next 方法返回一个包含 value 和 done 属性的对象
    【需要自定义遍历数据时,想到迭代器】
const xiyou = ['tang','sun','zhu','sa'];
let iterator = xiyou[Symbol.iterator]();
//调用对象的 next 方法
console.log(iterator.next());   //{value: "tang", done: false}
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());   //{value: undefined, done: true}
								//done 的值为 true 表示遍历完成



生成器 Generator

生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同, 可以用来进行异步编程

生成器函数声明与调用

//声明
 function * gen(){
     
     console.log("hello");
 }
 let iterator = fn();
 console.log(iterator);  //可以看到它是一个迭代器对象
 iterator.next();        //想调用这个函数,需借助迭代器中的 next 方法
//yield 函数代码分隔符,将代码分割成一块一块的
	 function * gen(){
     
	    console.log(111);
	    yield '1';
	    console.log(222);
	    yield '2';
	    console.log(333);
	    yield '3';
	    console.log(444)
	 }
	        let iterator = gen();
	        iterator.next();        //next 只执行第一个代码块的内容

生成器函数参数

  1. 函数可正常传参
  2. next 方法中也可传参
	 function * gen(arg){
     
	      console.log(arg);       //AAA
	      let one = yield 111;
	      console.log(one);       //BBB
	      let two = yield 222;
	      console.log(two);       //CCC
	      let three = yield 333;
	      console.log(three);     //DDD
	 }
	 let iterator = gen('AAA');		//正常传参
	 iterator.next('');
	 iterator.next('BBB');       //传入第一个yield中
	 iterator.next('CCC');       //传入第二个yield中
	 iterator.next('DDD');       //传入第三个yield中

【实例-1】

需求:1s 后控制台输出 111,2s 后控制台输出 222,3s 后控制台输出 333。

//定时器,产生回调地狱
        setTimeout(() => {
     
            console.log(111);
            setTimeout(() => {
     
                console.log(222);
                setTimeout(() => {
     
                    console.log(333)
                },1000)
            },1000)
        },1000)
//生成器函数
		function one(){
     
            setTimeout(() => {
     
                console.log(111);
                iterator.next();
            },1000)
        }

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

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

        function * gen() {
     
            yield one();
            yield two();
            yield three();
        }
        //调用生成器函数
        let iterator = gen();
        iterator.next();

【实例-2】

需求:模拟获取 用户数据、订单数据、商品数据(一步步获取)

        function getUsers(){
     
            setTimeout(() => {
     
                let data = '用户数据'
                //调用 next 语句,将数据传入
                //此处是第二次调用,参数传到第一个 yield 中
                iterator.next(data);
            }, 1000)
        }
        function getOrders(){
     
            setTimeout(() => {
     
                let data = '订单数据'
                iterator.next(data);
            },1000)
        }
        function getGoods(){
     
            setTimeout(() => {
     
                let data = '商品数据'
                iterator.next(data);
            },1000)
        }

        function * gen(){
     
            let user = yield getUsers();
            console.log(user);
            let order = yield getOrders();
            console.log(order);
            let good = yield getGoods();
            console.log(good);
        }

        let iterator = gen();
        iterator.next();



Promise

Promise 是ES6 引入的异步编程的新解决方案,语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。解决回调地狱的问题。

关于回调函数

  1. Promise 构造函数:Promise(excutor){}
  2. Promise.prototype.then 方法
  3. Promise.prototype.catch 方法
        //实例化 Promise 对象
        const p = new Promise(function(resolve, reject){
     
            setTimeout(function(){
     
            	// resolve 调 then 的第一个回调函数
                 let data = '数据库中的数据';
                 resolve(data);

				// reject 调 then 的第二个回调函数
                let err = '读取失败';
                reject(err);
            }, 1000);
        });
        //调用 promise 对象的 then 方法
        p.then(function(value){
     
            console.log(value);
        }, function(reason){
     
            console.error(reason);      //控制台输出有红叉是因为'console.error'
        });

Promise 封装读取文件

//1. 引入 fs 模块( fs 是 node 自带的核心模块)
const fs = require('fs');

//2. 调用方法读取文件
//第一个参数是文件路径,第二个参数是回调函数
//err 错误对象,data是读取出的结果,是一个Buffer格式的
fs.readFile('D:/Web/wenjian.md',(err, data)=>{
     
    //如果失败,则抛出错误
    if(err) throw err;
    //如果没有错误,则输出内容
    console.log(data.toString());
});

//3. 使用 Promise 封装
const p = new Promise(function(resolve,reject){
     
    fs.readFile('D:/Web/wenjian.md',(err, data)=>{
     
        //如果失败
        if(err) reject(err);
        //如果成功
        resolve(date);
    });
});

p.then(function(value){
     
    console.log(value);
},function(reason){
     
    console.log("读取失败")
})

需用到 nodejs
在这里插入图片描述

Promise 封装AJAX请求

使用原生 AJAX 向一个地址发送一个请求

        //1. 创建对象
        const xhr = new XMLHttpRequest();

        //2. 初始化
        xhr.open("Get","https://api.apiopen.top/getJoke");

        //3. 发送
        xhr.send();

        //4. 绑定事件,处理响应结果
        xhr.onreadystatechange = function(){
     
            //判断
            if(xhr.readyState === 4){
     
                //判断响应状态码 200-299
                if(xhr.status >= 200 && xhr.status < 300){
     
                    //成功
                    console.log(xhr.response);
                }else{
     
                    //如果失败
                    console.log(xhr.status);
                }
            }
        }

Promise 封装

		const p = new Promise((resolve, reject)=> {
     
            //1. 创建对象
            const xhr = new XMLHttpRequest();

            //2. 初始化
            xhr.open("Get","https://api.apiopen.top/getJoke");

            //3. 发送
            xhr.send();

            //4. 绑定事件,处理响应结果
            xhr.onreadystatechange = function(){
     
                //判断
                if(xhr.readyState === 4){
     
                    //判断响应状态码 200-299
                    if(xhr.status >= 200 && xhr.status < 300){
     
                        //成功
                        resolve(xhr.response);
                    }else{
     
                        //如果失败
                        reject(xhr.status);
                    }
                }
            }
        })
        //指定回调
        p.then(function(value){
     
            console.log(value);
        },function(reason){
     
            console.error(reason);
        })

对于异步成功和失败的结果,处理方式不同。【原来是在回调函数中处理】,【现在是在异步任务的后面,通过 then 方法来指定回调。】

Promise.prototype.then

指定成功和失败的回调

        //创建Promise对象
        const p = new Promise((resolve,reject)=>{
     
            setTimeout(()=>{
     
                resolve('shuju');
            },1000)
        });
        //调用 then 方法, then 方法的返回结果是 Promise 对象, 对象状态由回调函数的执行结果来决定。
        const result = p.then(value =>{
     
            console.log(value);
            //1. 如果回调函数中返回的结果是 非Promise 类型的属性,状态为成功,返回值为对象的成功的值(PromiseResult:"ok")。
            //return "ok";
            //2. 返回的结果是 promise 对象,此处成功的值,就是 then 方法成功返回的值(PromiseResult:"ok"),如果此处promise失败(PromiseResult:"ok"),reject中的值
            //return new Promise((resolve,reject)=>{
     
				//resolve('ok');
				//reject('error');	
			//});
			//3. 抛出错误
            //throw new Error('出错啦!');
        },reason=>{
     
            console.log(reason);
        });

        console.log(result);		//then 方法的返回结果是 Promise 对象

ES6笔记合集_第2张图片
【链式调用】then 方法的返回结果也是一个 Promise 对象

		p.then(value=>{
     
		
		}).then(value=>{
     
		
		});

Promise.prototype.catch

指定失败的回调

const p = new Promise((resolve,reject)=>{
     
            setTimeout(()=>{
     
                reject("出错了!!");
            },1000)
        });
        p.catch(function(reason){
     
            console.warn(reason);
        })



Set

ES6提供了新的数据结构 Set (集合)。类似于数组,但成员的值都是唯一的。

  1. size 【返回集合子元素个数】
  2. add 【增加一个新元素,返回当前集合】
  3. delete 【删除元素,返回 boolean值】
  4. has 【检测集合中是否包含某个元素,返回boolen值】
  5. clear 【清空】
        //声明 set
        let s = new Set();
        let s2 = new Set([1,2,3,0,0])
        console.log(s2);        //1, 2, 3, 0

        //元素个数
        console.log(s2.size);   //4
        //添加新元素
        s2.add(5);
        console.log(s2);        //1, 2, 3, 0, 5
        //删除元素
        s2.delete(0);
        console.log(s2);        //1, 2, 3, 5
        //检测
        console.log(s2.has(2)); //true
        //清空
        s2.clear();
        console.log(s2);

【应用】

 let arr = [1,2,5,6,6,7,5];
 //1.数组去重
 // let result = [...new Set(arr)];
 // console.log(result);
 //2.交集
 let arr2 = [4,5,6,5,6]
 let result = [...new Set(arr)].filter(item =>new Set(arr2).has(item));
 console.log(result);
 //3.并集
 let union = [...new Set([...arr,...arr2])];
 console.log(union);
 //4.差集
 let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
 console.log(diff);



Map

ES6 提供了 Map 数据结构。类似于对象,也是键值对的集合。【键的范围不限于字符串,各种类型的值(包括对象)多可以当作键】

  1. size 【返回 Map 的元素个数】
  2. set 【增加一个新元素,返回当前 Map】
  3. get 【返回键名对象的键值】
  4. has 【检测 Map 中是否包含某个元素,返回boolen值】
  5. clear 【清空,返回 undefined】
        //声明 Map
        let m = new Map();
        //添加元素
        m.set('name','张三');
        m.set('play',function(){
     
            console.log("playing....");
        });
        let key = {
     
            from : 'sky'
        };
        m.set(key, ['beijing', 'shanghai']);
        console.log(m);
        //size
        console.log(m.size);
        //删除
        m.delete('name');
        console.log(m);
        //获取
        console.log(m.get('play'));
        console.log(m.get(key));
        //遍历
        for(let v of m){
     
            console.log(v);
        }

ES6笔记合集_第3张图片




数值的扩展

  1. 二进制和八进制
    分别可用前缀 0b(或0B)和 0o(或0O)来表示
        let b = 0b1010;     //二进制
        let o = 0o12;      //八进制
        let d = 100;        //十进制
        let x = 0xff;       //十六进制
        console.log(b,o,d,x);		//10  10  100  255
  1. Number.isFinite
    检测一个数是否为有限数
        console.log(Number.isFinite(100));			//true
        console.log(Number.isFinite(100/0));		//false
        console.log(Number.isFinite(Infinity));		//false
  1. Number.isNaN
    检测一个数是否为 NaN
        console.log(Number.isNaN(NaN)); //true
        console.log(NaN === NaN);       //false
  1. Number.parseInt Number.parseFloat
    全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变。【字符串转整数】
        console.log(Number.parseInt('123456iii'));      //123456
        console.log(Number.parseFloat('3.1415926pai')); //3.1415926
  1. Number.isInteger
    判断一个数是否为整数
        console.log(Number.isInteger(3.2));     //false
  1. Math.trunc
    将数字的小数部分抹掉
        console.log(Math.trunc(3.2));       //3
  1. Math.sign
    判断一个数到底为正数、 负数、 还是零
        console.log(Math.sign(100));        //1
        console.log(Math.sign(-100));       //-1
        console.log(Math.sign(0));          //0
  1. Number.EPSILON 是 JavaScript 表示的最小精度(接近于2.22.4460492503130808472633361816E-16)
        console.log((0.1 + 0.2) === 0.3);       //false
        //使用 Number.EPSILON 封装函数
        function equal(a,b){
     
            if(Math.abs(a-b) < Number.EPSILON){
     
                return true;
            }else{
     
                return false;
            }
        }
        console.log(equal((0.1+0.2),0.3))       //true



对象方法扩展

  1. Obiect.is 【判断两个值是否完全相等】
    ES5 比较两个值是否相等,只有两个运算符:相等运算符 和 严格相等运算符。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。
        console.log(Object.is(+0, -0))      // false
        console.log(Object.is(NaN, NaN))    // true
  1. Object.assign()【对象的合并】
    将源对象(source)的所有可枚举属性,复制到目标对象(target)。
        const target = {
      a: 1 };

        const source1 = {
      b: 2 };
        const source2 = {
      c: 3 };

        Object.assign(target, source1, source2);
        console.log(target);          // {a:1, b:2, c:3}

1)Object.assign()方法的第一个参数是目标对象,后面的参数都是源对象。
2)如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
3)如果只有一个参数,Object.assign()会直接返回该参数。如果该参数不是对象,则会先转成对象,然后返回。
4)由于undefined和null无法转成对象,所以如果它们作为参数,就会报错。【如果非对象参数出现在源对象的位置(即非首参数),那么处理规则有所不同。首先,这些参数都会转成对象,如果无法转成对象,就会跳过。这意味着,如果undefined和null不在首参数,就不会报错。】




【内容不是很全,后续会不定时的来补充修改完善的,感谢阅读。~(~ ̄▽ ̄)~】

你可能感兴趣的:(javaScript,知识点,javascript)