es新特性学习笔记

1 let

let是var的升级版,更符合java和c的版本,以下为var与let的区别

  1. 不能重复声明一个变量,而var可以。
  2. 拥有块级作用域。就是花括号里的变量,外面不能用
  3. 不存在变量提升
  4. 有一个常见的var的bug,就是for(var i = 0; i< 3;i++){s[i].click} 这个时候只会执行s[3],因为i变成了全局的,i就是3。这就是块级作用域的问题

2 const 定义常量

const PS = “15”

  1. 必须初始化
  2. 常量无法修改
  3. 一般要大写
  4. 块级作用域
  5. 数组和对象可以修改,比如SS[5] = "541" obj.name = "44";

这个有点像c语言里的#define

3 解构赋值

3.1 数组

const score = [90, 100, 95];
let [math, English, Chinese] = score;

这个不是很常用

3.2 对象

const student = {
	name: "",
	score: 100,
	gotoschool: function(){
		console.lof("sfji");
	}
}
let {gotoschool} = student;
//或者let {name, score, gotoschool} = student;
gotoschool();

let arr = ["s", "a", "b"];let {x1, x2, x3} = arr;x123分别为s、a、b可以进行这样的赋值操作,包括对象(相当于结构体)

4 对象的简化写法

能够使用外部已经赋值的变量
能够简化对象里的函数定义,不需要再写function

let name = "xiaoming";
let score = 100;
let gotochool = function(){};
const student{
	name,
	score,
	gotoschool,
	eat(){}
}

5 ``反单引号模板字符串

和双引号一样是一种定义字符串的方式

  1. 直接可以换行
  2. 可以直接字符串拼接 例如:${X}是我喜欢的东西就是将x与汉字连接

6 => 箭头函数

  1. this是静态的,始终指向声明时的作用域,无法改变。
  2. 不能用argument变量。
  3. 形参只有一个的时候可以省略括号
  4. 只有一条语句时可以省略花括号
  5. 这条语句是return时,可以省略return;如let a = n => n*n;
let getname = () => {}

当我们在使用setTimeout这种直接调用的函数的时候,函数没有和其他的东西绑定,所以里面的this就是默认的windows,这就是箭头函数的好处setTimeout(() => {}, 2000);

7 形参赋初始值

function ss(df,dfd = 5){}
ss(5);
//55

赋初始值的要靠后,假如没有传参就会使用初始值

8 …X rest参数

可以用来替代argument,不同的是需要在函数声明的时候形参写成…X的形式,如

function fn(a, b, ...args){} fn(1,2,3,4,5);
//args[0] = 3,args就是一个数组

rest参数要放在最后

9 …扩展运算符

9.1 描述

需要将一个数组的所有元素单独作为参数传进去的时候使用
例如

const tfboys = ['yyqx', 'wy', 'wjk'];
function chunwan(){
	console.log(argument);//获取实参信息
}
chunwan(...tfboys)//这里是三个实参传进去了,而不只是一个数组

9.2 一些应用

9.2.1 数组及对象的合并

const arr1 = ["A", "B", "C"];
const arr2 = ["D", "E"];
const zuhe = [...arr1, ...arr2];

9.2.2 数组及对象的克隆

const arr3 = [...arr1];

可以直接将数组克隆而不用使用函数,相对来说更为简洁

9.2.3 将伪数组转为真正的数组

const divs = document.querrySelectorAll("div");
const divarr = [...divs];
//这里就是将divs这个对象转为数组,可以使用数组的方法

10 Symbol()数据类型

10.1 Symbol 特点

  1. symbol本质是一个唯一随机的字符串,而且我们是无法打印出来的
  2. 括号里是相当于注释的描述性文字,如Symbol(“注释”);
  3. 无法运算和比较
  4. Symbol.for(“key”),这种方法的symbol可以相等
    这一部分暂时不学了,有点难理解,又感觉用到的场景不是很多

10.2 Symbol内置属性

对象调用属性有两种方法,而symbol内置属性定义的函数只能用[]的方式来调用这个属性,用点.不行
symbol的内置属性是Symbol的一些方法,然后用在一些对象或者构造函数或者类里面,充当一些函数名,在特定的场景下面这个自己定义的,函数名为symbol内置属性的函数会被调用

11 迭代器

11.1 介绍

自带iterator接口的数据
Array StringSset Map Argument TypedArray Nodelist
iterator就是一个array自带的Symbol内置属性,当使用for in或者for of的时候就会调用。

11.2 for of 与 for in

const xiyou = ["孙悟空", "唐僧", "猪八戒", "沙和尚"];
for(let i of xiyou){//键值
	console.log(i);//孙悟空 唐僧 猪八戒 沙和尚
}
for(let i in xiyou){//键名
	console.log(i);//1234
}

11.3 自定义迭代器接口

const banji = {
      name:"终极一班",
      stus:[
        "xiaoming",
        "xiaotian"
      ]
}
for(let i of banji){
	console.log(i);//报错,会显示banji不是一个能够迭代的对象
}
for(let i in banji){
	console.log(i);//输出的时name stus
}
for(let i of banji.stus){
	console.log(i);//xiaoming xiaotian
}

此时需要的是实现第三个的功能,但是不采用这种方式,而是使用自定义迭代器的方式

name:"终极一班",
  stus:[
    "xiaoming",
    "xiaotian"
  ],
  [Symbol.iterator](){//返回的是一个next函数,
    let index = 0;
    let _this = this;
    return{
      next: ()=>{
        if(index < _this.stus.length){
          const result = {
            value: _this.stus[index],
            done: false
          }
          index++;
          return result;
        }
        else{
          return {
            value: undefined,
            done: true
          }
        }
      }
    }
  }
}
for(let i of banji  ){
  console.log(i);
}

上面代码最主要的部分就是那个Symbol.iterator{}这就是当使用for in和for of的时候会触发的函数,我们需要返回一个对象,这个对象需要包含next函数,next函数需要返回一个对象,这个对象需要包含value,done。
next一开始会指向第一个元素,返回value的值在i里面,当done变成true的时候会停止,这个的value值不会被返回,所以就是这样实现了一个自定义的迭代器。

12 生成器函数 yield

12.1 介绍

解决回调地狱的,就是函数套娃,不停回调
语法中,遇到yield就停,遇到next继续
fuction* 和普通的function 有点不一样
例子

function fun1(){}
function fun2(){}
function * getdata(){//声明方式不同
	console.log("start");
	yield fun1;//多了一个关键字yield
	yield fun2;
}	
let iterator = getdata();//也可以直接调用getdata();
itetator.next();//这个next就是调用第一个yield和fun1, 再使用iterator.next()就会调用第二个

传参问题:
使用next()传参
next就是生成器版本的return

12.2 实例

function getUsers(){
  setTimeout(() =>{
    let data = "用户数据";
    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 users = yield getUsers();
  console.log(users);
  let orders = yield getOrders();
  console.log(orders);
  let goods = yield getGoods();
  console.log(goods);
}
let iterator = gen();//这里将gen实例化,好像是必须实例化,才能在第一个函数中使用next
iterator.next();

13 Set集合

这是一个新的数据结构,内有iterator接口,所以能够使用for in和for of,当然for in是不会和数组一样有123的,声明都没有,而for of能够输出集合里的所有的元素。
会自动将重复的元素去除,就算是在声明的时候添加了多个相同的元素,它就只会保存一个

13.1 声明

let set1 = new Set();//与数组不同,必须使用new
let set2 = new Set(["1", "2"]);

13.2 部分集合的方法

  1. console.log(set.size);//返回集合大小
  2. set.add(“fsf”);//增加一个集合元素,返回集合
  3. set.delete(“sffs”);//返回boolean值,是否删除成功,有的时候可能都没有这个元素
  4. set.has(“sf”);//判断是否有这个元素,返回boolean值

14 promise

这个暂时不学

15 Map地图对象

15.1 介绍

map其实就是一个升级了的对象, 能够通过键名访问键值,与对象的区别就在于这个键名可以是对象,不只是局限于字符串

15.2 部分函数

声明
就是普通的对象声明方式

let m = new Map();

添加元素

m.set("name", "iceylia");
m.set("change", function(){});

得到大小

console.log(m.size);//2

清空地图

m.clear();

访问元素

console.log(m.get("name"));//iceylia
console.log(m.has("name"));//true;

遍历

for(let v of m){
	console.log(v);
  	console.log(v[1]);//iceylia  function
}

16 class类

16.1 介绍

类的定义在很多的语言里面都有,其实类的许多功能也能够用之前的语法实现,只是为了让js更加像是面向对象的编程。

class phone{
	constructor(brand, price){//这个函数就是在类被声明的时候会自动执行这个函数。
		this.brand = brand;
		this.price = price;	
	}
	call(){
		console.log("我可以打电话");
	}
}
let oneplus = new phone("1+", 3000);
oneplus.call();//我可以打电话
console.log(oneplus.brand);//1+

16.2 静态成员

在原本的构造函数里面也有静态对象

function phone(){
	this.brand = brand;
	this.price = price;
}
phone.call = function(){
	console.log("wfw");
}//这个时候这个call是构造函数的对象
phone.prototype.call2 = funciton(){}//这个函数实例化对象就能使用,prototype就是原型的意思,可以理解成构造对象。
let oneplus = new phone("1+", 3000);
oneplus.call();//undefined;

而我们在类里面也可以定义静态成员,就是在成员名前面加上static

class phone{
	constructor(brand, price){
		this.brand = brand;
		this.price = price;	
	}
	static call(){
		console.log("我可以打电话");
	}
}

16.3 构造函数的继承

function phone(brand, price){
	this.brand = brand;
	this.price = price;
}
function smartphone(brand, price, color, size){
	phone.call(this, brand, price);//这个是不能更改名字的
	//大概意思就是将这个构造函数的对象和与父类相同的属性传过去
	this.color = color;
	this.size = size;
}
smartphone.prototype = new phone;//这里也就是将smartphone的父类原型指定为phone
const chuizi = new smartphone("锤子", 2999, "黑色", "5inch");
console.log(chuizi.brand);//锤子
console.log(chuizi.call);//undefined;

16.4 类的继承

class phone{
	constructot(brand, price){
		this.brand = brand;
		this.price = price;
	}
	call(){
		console.log("我可以打电话");
	}
}
class smartphone extends phone{
	constructor(brand, price, color, size){
		super(brand, price);//将父类需要的参数传过去
		this.color = color;
		this.size = size;//定义子类的成员属性
	}
}
const xiaomi = new smartphone("小米", 2999, "black", "5.5inch");
xiaomi.call();//我可以打电话;

如上例子,我们可以调用父类的方法,但是当我们子类也有一个同名的方法的时候,就无法通过子类调用这个父类的同名方法,只能使用子类里面的方法.

16.5 get set

16.5.1 get

get其实就是一个特殊的class的函数的修饰词,看起来是函数,实际上是一个class里的变量或者说是属性

class phone{
	get call(){
		console.log("call1");
		return 5;
	}
}
const oneplus = new phone();
console.log(oneplus.call);//call1  5;

作用就是能够动态地改变这个变量的值,每使用一次set参数,就会调用一次set函数,将函数返回值编程set参数的值

16.5.2 set

set形式上与get相似,一般就是利用里面的函数判断是否能够实现这个赋值,如果你给变量赋值不合法,或者不符合规则,那么就可通过函数直接赋值失败

class phone{
	set call(newvalue){//必须有一个参数
		console.log("call1");
	}
}
const oneplus = new phone();
oneplus.call = "454";

17 数值扩展

17.1 Number.EPSILON 最小精度

epsilon英文中是希腊中第五个字母,小的正数的意思,再js里面就是js的最小精度。
用途,在我们进行浮点数的运算的时候,我们都知道,浮点数其实是有许多没有显示出来的位数的,一直到最小的精度,所以会出现下面的问题

console.log(2.1 - 1.1 === 1.0);//false;
//用EPLISON解决
if(Math.abs(2.1-1.1) < Number.EPLISON){
	console.log(1);
}
else{
	console.log(0);
}

17.2 变量的进制表达方式

形式都是0+字母加 数字

//二进制
let b = 0d101;//5;
//八进制
let o = 0o777;
//十六进制
let x = 0xfff;

17.3 Number.isNaN()判断是否为一个数字

在es6之前这个isNaN()就是一个单独的方法,所以我们现在也可以直接使用之前的那种形式

console.log(isNaN(13));

17.4 Number.parseInt()将字符转为整形的数字

同上,之前就是一个单独的函数

console.log(Number.parseInt("123"));//ture;
let a = Number.parseInt("123");//true;

17.5 Number.isInteger() 是否为整形

18 对象方法扩展

18.1 Object.is() 判断两个值是否相等

===相似
有一点不同,就是全等的时候NaN ===NaN是false,而is是true

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

18.2 Object.assign() 对象的合并

assign()将后面的对象覆盖到前面去,假如有冲突,那么就保留后面的对象。

const test1 = {
	name: "1",
	tel:"154"
}
const test2 = {
	name: "2",
	
}
console.log(Object.assign(test1. test2))//2 154;

18.3 Obeject.defineProperty() 对象添加属性

let object1 = {
	name: iceylia
}
Object.defineProperty(object1, 'property1', {
  value: 42,
  writable: false
});

返回值是该对象,第一个参数是对应的对象,第二个是对象的属性名,第三个参数是配置对象,配置对象里面最重要的是value的属性,也就是属性的值,
enumerable 属性是否可被枚举到,默认是false,我们想要通过for in 获取到,就需要设置这个参数为true
writable 属性是否可被修改,一开始也为false
configurable 属性是否可被删除, 默认false
get 参数是一个函数,在属性被访问的时候会调用这个函数,必须有返回值,作用就是将这个属性和一个变量动态的绑定在一起,每次读取这个属性的时候,都会调用这个参数来看看那一个变量是什么,一般叫这个函数为getter
set 参数与get差不多,当你在改变属性的值的时候,就会调用这个函数,然后就会修改对应的变量的值

let number = 18;
let x = {
    name: "iceylia",
}
Object.defineProperty(x, "age", {
    get: function() {
        return number;
    },
    set: function(value) {
        number = value;
    }
})

图

19 模块化

19.1 介绍

模块化就是将别处代码的变量能够在这里使用,而模块化的好处就是高维护,避免命名冲突,代码复用。
在使用模块化导入的时候,需要将export的type设置成module(模块)

<script type="module">
    import * as test1 from "./test.js";
    test1.test();
    console.log(test1.name);
</script>

此时同级下有个叫test1.js的文件

export let name = "iceylia";
export function test(){
	console.log("test success");
}

//结果就是test success 和iceylia

19.2 export暴露方法

  1. 分别暴露,就是将每个要暴露的对象和变量前面都加上export,如介绍中所写的那样。
  2. 统一暴露,在要暴露的文件最后面export{name, test},用这种格式将所有要暴露的对象写里面
let name = "iceylia";
function test(){
	console.log("test success");
}
export{name, test};
  1. 默认暴露,像是对象的写法,使用的时候要先用default然后才能用里面的变量
export default{
	name: "iceylia",
	test: function(){
		console.log("test success");
	}
}
<script type="module">
    import * as test1 from "./test.js";
    test1.default.test();
    console.log(test1.default.name);
</script>

19.3 import导入方式

  1. 通用方式,如介绍所写,import * as X from " "X就是自己定义的名字,*是文件里要引入的东西
  2. 解构赋值方式
import {name, test} from "./test1.js";//名字不冲突,直接用文件里的名字
import {name as name2, sss} from "./test2.js";//名字冲突,需要用as起别名,就起了一个name2
import {default as x} from "./test3.js";//默认暴露可用,此时用x.name与x.test访问文件内容
console.log(name);//iceylia
  1. 简便形式,这种方式只能对于默认暴露形式生效
import X from "./test.js";
console.log(X.name);

20 es7

20.1 includes()

判断数组里面,是否包含某个元素

const test = [1, 5, 8];
console.log(test.includes(5));//true;

20.2 ** 幂运算

2 ** 5 相当于 Math.pow(2, 5),都是二的五次方;

20.3 reduce()

将数据进行条件统计,与filter过滤不是一个概念,reduce是为了统计数组中有多少个符合条件的数据。

const arr = ["1", "ff", "55"];
let initValue = 0;
const result = arr.reduce((preValue, currElem)=>{
	return preValue + 1;
},initValue);

result一般使用两个参数,第一个是一个函数,第二个是初始值。第三个参数是currElem的index,第四个参数是arr本身
reduce执行一次,currElem就会后移一位,遍历完了reduce就结束了
preValue函数上一次指向的返回值,一开始的时候preValue是initValue,如果没写initValue,那就是arr[0],这样会使reduce少执行一次
案例中的方法,preValue初始值为0,curr为1,执行一次,preValue为1,curr为ff,再执行一次,pre为2,curr为55,最后执行一次的返回值就是reduce的返回值了,所以result为3,就是数组的长度。
reduce如何条件统计的呢

const result = arr.reduce((preValue, currElem)=>{
	return preValue + (currElem.length === 2 ? 1 : 0);
},initValue);

这样的result就是数组中长度为2有多少了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值