ES6-11随手记(1)

ES6

let变量声明以及声明特性

使用let同一个作用域声明变量时不可以重复声明,使用var重复声明是可以的。使用let就可以防止变量重复或被污染。

块级作用域:

只在代码块内有效(如if、swich、for、while等)

不影响作用域链

函数内部的变量(子作用域)和循环变量(父作用域)不在同一个作用域。

(var声明的是全局变量) 

不存在变量提升:即不允许在变量声明前使用该变量。(若是var则是显示undefined)

const声明常量以及特点

一定要赋初始值。

常量的值不能修改,也不可以重复声明。

块级作用域且同样不能提升。

对于数组和对象的元素修改,不算做对常量的修改,不会报错(地址没有改变)。如果想将对象冻结,应该使用Object.freeze方法。

变量的解构赋值

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

1、数组的解构

const a=[1,2,3,4];
let[一,二,三,四]=a;
//此时相当于把1,2,3,4分别赋值给一、二、三、四

2、对象的解构

const xu={
    name:'徐',
    age:'17',
    chi:function(){
        console.log("123");
    }
}
let{name,age,chi}=xu;
//此时分别把对象中的name,age,chi赋值给了对应的变量

模板字符串

ES6引入新的声明字符串的方式[' ']、‘ ’ 、 “ ”

特性:

  1. 内容中可以直接出现换行符,此前需要引号和加号连接
  2. 可以直接进行变量的拼接
let str1='西瓜';
let str2='很好吃!';
//最初的方式
let str2='str1'+'str2';
//直接拼接
let str2='${str1}很好吃!';

数值拓展

  1. Number.EPSILON是js表示的最小精度,若误差小于该值则视为相等
  2. ES6中二进制用0b(0B)表示,八进制用0o(0O)表示
  3. Number.isFinite()用来检查一个数值是否为有限的( finite )
  4. Number.isNaN()用来检查一个值是否为NaN
  5. Number.isInteger()用来判断一个值是否为整数,在js中整数和浮点数储存方法一致,被视为一个值
  6. 整数范围在-253到253之间(不含两个端点)是安全整数,Number.isSafeInteger()则是用来判断一个整数是否落在这个范围之内。
  7. Math.trunc除去小数部分,Math.sign方法用来判断一个数到底是正数、负数、还是零。
  8. 指数运算符(**),新的赋值运算符(**=)

对象方法的拓展(6-11)

  1. Object.is(,) 判断两个值是否完全相等,该方法与===在判断两个NaN是恶分别得到的是true和false
  2. Object.assign(对象1,对象2),如果对象1的属性对象2也有,对象2的属性就会覆盖对象1的属性,如果对象1的属性对象2没有就会显示对象1的属性。若只有一个参数直接返回,若不是对象则先转成对象再返回(undefined、null除外)
  3. Object.setPrototypeof设置原型对象格式Object.setPrototypeof(对象1,对象2)将对象2设置为对象1的原型,对象2的原型为Object对象。
  4. Object.values 返回一个给定对象自身的所有可枚举属性值的数组,Object.entries 返回一个数组,其元素是与直接在object上找到的可枚举属性键值对相对应的数组。
  5. Object.getOwnPropertyDescriptors 返回对象属性的描述对象。
  6. Object.fromEntries(),这个方法和之前的Object.entries()是两个互逆的操作,将二维数组转换为对象。

对象的简化写法

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

let name='xu';
let haha=funxtion(){
    console.log('hahaha');
}
const xu={
    name,//实际上为name:name,但是ES6允许直接写入
    haha,
    import(){}//此时原本为import:function(){},但是在ES6中可以简化为前面的写法
}

箭头函数以及声明特点

ES6允许使用箭头(=>)定义函数。

特性

  1. this是静态的,无论使用什么方式(直接调用或call调用)this始终指向函数声明时所在作用域下的this的值。
  2. 不能作为构造实例化对象(个人简单理解为var persion = new Person('xu','17')就是对象实例化)
  3. 不能使用arguments变量(该变量用来保存实参)
  4. 箭头函数的简写:当形参有且只有一个时可以省略小括号;当代码提只有一条语句时可以省略花括号(此时return必须省略,且执行结果就是返回值)。

函数参数的默认值设置

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

具有默认值的参数,一般位置靠后(潜规则)。

默认值可以与解构赋值结合使用。

function connect({name='李四',age,job}){
    console.log(name)
    console.log(age)
    console,log(job)
}
coonect({
    name:'张三',
    age:'20',
    job:'学生'
})
//这里给name赋予初始值,如果没有传入则默认为李四

rest参数

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

function data(...args){
    console.log(args);
}
data('zs','ls','ww');

得到的结果是数组。

rest参数必须要放在参数的最后。

拓展运算符

拓展运算符(...)能将数组转化为逗号分隔的参数序列。

const zuhe=['张三','李四','王五'];
function haha(){
    console.log(srguments);
}
haha(...zuhe);//haha('张三','李四','王五')

虽然拓展运算符和rest符号一样,但是rest是写在形参的位置,拓展运算符是写在调用的实参位置。

拓展运算符的运用:

1、数组的合并

const zuhe = ['一号','二号'];
const zuhe2 = ['三号','四号'];
const zuizhongzuhe = [...zuhe, ...zuhe2];
//最终的结果就是['一号','二号','三号','四号']

2、数组的克隆:直接运用运算符写入即可

3、将伪数组转化为真正的数组

const divs = document.querySelectorAll('div');
const divarr = [...divs]

Symbol的介绍与创建

数据类型Symbol表示独一无二的值,是一种类似于字符串的数据类型。

特性:

  1. Symbol的值是唯一的,用来解决命名冲突的问题
  2. Symbol值不能与其他数据进行运算、对比、拼接(与自身也不行)
  3. Symbol定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
//创建Symbol
let s=Symbol();
let s1=Symbol('hhhhh');//此时若再创建一个s2也为Symbol('hhhhh'),要注意s1,s2是不一样的
//Symbol.for(()创建
let s3=Symbol.for('hhhhhh');//此处的Symbol是一个对象,上方的Symbol是函数
//若用此方法再创建一个s4也为Symbol.for('hhhhhh'),s3,s4是相等的

Symbol的内置值

迭代器 

迭代器是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口,就可以完成遍历操作。(在JS中所说的接口其实就是对象的一个属性:Symbol.Iterator) 

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

原生具备Iterator接口的数据(可用for...of遍历)有Array, Arguments, Set, Map, Striing, TypedArray, NodeList。

 注意:for...in循环保存的是键名,即1,2,3...,而for...of循环保存的是键值,即数据的内容。

工作原理

  1. 创建一个指针对象,指向当前数据结构的起始位置
  2. 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
  3. 接下来不断调用next方法,指针一致往后移动,直到指向最后一个成员
  4. 每调用next方法返回一个包含value和done属性(当该属性为true时表示遍历结束)的对象

生成器

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

声明方式:function *go(){yield},其中yield是函数代码分隔符

function * go(){
    console.log(1);
    yield '我爱吃西瓜';
    console.log(2);
    yield '我爱吃苹果';
    console.log(3);
    yield '我爱吃草莓';
}
let iterator = go();
iterator.next();//控制台打印1
iterator.next();//控制台打印2
iterator.next();//控制台打印3
//若将上面三行分别打印则控制台显示的是{value:(yield后面的内容),done:true/false}

由代码输出结果可见,并不同于先前的函数直接运行全部,而是通过next方法来控制代码向下执行。

也可以使用for...of遍历,但是每次返回的结果是yield后面的内容。

生成器函数的参数传递

若直接用生成器函数传入参数则至少需要运行第一个next方法,否则不会执行。

next方法可以传入实参,第二次next方法传入的实参将作为第一个yield语句的返回结果。

 Promise函数

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

构造函数:Promise(){}

const p = new Promise(function(resolve,reject){
    setTimeout(functon(){
        let data = '数据库中的用户数据';
        resolve(data)//此时p的状态变为成功
        let err = '数据读取失败';
        reject(err);//此时p的状态为失败
    ),1000);
});
//调用promise对象的then方法
p.then(function(value){
    console.log(value);//打印结果为数据库中的用户数据
},function(reason){
    console.error(reason);//打印结果为数据读取失败
})

promise.prototype.then方法

该方法返回的结果实际上也是一个promise对象,其对象状态由回调函数的执行结果决定。如果回调函数中返回的结果是非promise类型的属性,状态为成功,返回值为对象的成功的值。如果是一个promise对象,则该promise对象的返回状态决定外部promise对象的返回状态,且其值就是then方法返回的值。若为抛出错误则then返回的对象的状态是失败的状态,值就是抛出的错误的值。

由于then方法返回的是promise对象,则可以实现链式调用,即在then中嵌套then。then方法的链式调用可以解决回调地狱问题(一个异步请求套着另一个异步请求,一个异步请求依赖于另一个异步请求的结果)

promise.prototype.catch()方法

catch方法只能指定发生错误时的回调函数,返回值也是promise对象

如果Promise对象状态变为resolved,则会调用then方法指定的回调函数,如果异步操作抛出错误,状态就会变成rejected,就会调用catch方法指定的回调函数,如果运行中抛出错误也会被catch捕获

由于promise的状态一旦改变就永久 保持该状态不会再改变。所以若promise状态以及变成resolved,则再抛出错误是无效的。

promise对象的错误会一直向后传递直至被捕获,即错误只会被下一个catch捕获。

promise读取文件(多个)

//引入fs模块
const fs = require('fs');
//使用promise封装读取方法
const p = new Promise(function(resolve,reject){
    fs.readFile("路径1",(err,data)=>{
        resolve(data)
    });
});
p.then(value =>{
    return new Promise(resolve,reject)=>{
       fs.readFile("路径2",(err,data)=>{
        resolve([value,data]);
    });
}).then(value=>{
    return new Promise(resolve,reject)=>{
       fs.readFile("路径3",(err,data)=>{
            //压入
            value.push(data);
            resolve(value);      
        });
    });  
}).then(value=>{
    console.log(value);
});

fs模块是Node.js的一个核心模块,专门用来操作系统中的文件,常用的操作方式是对文件的读取和写入使用require('fs')载入fs模块,模块中所有方法都有同步和异步两种形式。异步方法中回调函数的第一个参数总是留给异常参数(exception),如果方法成功完成,该参数为null或undefined

pomise封装AJAX

const p = new Promise((resolve,reject)=>{
    //1、创建对象
    const xhr = new XMLHttpRequest();
    //2、初始化
    xhr.open("GET","接口地址");
    //3、发送
    xhr.send();
    //4、绑定事件,处理响应结果
    xhr.onreadystatechange = funxtion(){
        if(xhr.readyState ===4)
            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);
});   

Set

set(集合)类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用拓展运算符和for...of进行遍历。

属性与方法:

  1. 返回集合的元素个数,size
  2. 添加一个新元素,返回当前集合,add
  3. 删除元素,返回boolean值,delete
  4. 检测集合中是否包含某个元素,返回boolean值,has
  5. 清空集合,clear

实践:

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

Map

类似于对象,也是键值对的集合,但是”键“的范围不限于字符串,各种类型的值(包括对象)都可以当作键,Mapye也实现了iterator接口,所以可以使用拓展运算符和for...of遍历。

let m=new Map();   m.set('键名','键值');

属性和方法:

  1. Map的元素个数,size
  2. 新增一个新元素,返回当前Map,set
  3. 返回键名对象的键值,get
  4. 检测是否包含某个元素,返回boolean值
  5. 清空,返回undifined,clear

Class类

class phone{
    //构造方法,默认返回实例对象
    constructor(){//constructor不可更改,当执行"new+类名"时会自动执行
        this.brand=brand;//this关键词代表实例对象
        this.price=price;
    }
    //在class中必须使用下列语法,不可以使用ES5的对象完整形式,即call:function(){}
    call(){
        console.log("");
    }
}
let iphone = new phone("iphone",6000);//类必须使用new调用
console.log(iphone);
    

静态方法

在方法前加上static关键字表示该方法不会被实例继承,且该方法直接通过类来调用。

静态方法中若包含了this,该this制的是类而非实例。

静态方法可以与非静态方法重名。

静态属性是class本身的属性,而不是定义在实例对象上的属性。

继承

//父类
class phone{
    constructor(brand,price){
        this.brand = brand;
        this.price = price;
    }
    ...
}
//子类
class smartphone extends phone{//此处语法固定,不可更改
    constructor(brand,price,color,size){
        super(brand,price);//此处的super就是父类的constructor方法
        this.color = color;
        this.size = size;
    }
    photo(){
        console.log("拍照");
    }
}

子类可以对父类方法进行重写,但是不可以直接调用父类的方法。

get和set

在类的内部可以使用set和get关键字对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

get通常对对象的动态属性做封装,而set则可以添加更多的控制和判断。

get一般是要返回的,set不用返回,set函数必须写上参数,否则会报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值