ES6笔记

1、变量声明

​ 弱类型

​ var: 1、重复声明 2、变量提升 3、没有局部作用域(函数)

​ let: 1、不可重复声明 2、不存在变量提升 3、存在局部作用域 4、 暂时性死区:在⼀个代码块中,let可以锁定某个变量

​ const: 1、常量,只能赋值一次的变量,其他与let保持相同特性

let a = 3;
a++;  // 4
const b = 3;
b++;  //error
const obj = {age:1}
obj.age++;  // age 2
2、解构

快速从一个对象或数组中获取某些值

使用模式匹配方式从一个对象、数组快速获取值的方式

      let obj = {
        name:"terry",
        age:12,
        gender:"male",
        telephone:"18812344321",
        email:"licy@briup.com"
      }
      let a = obj.name;
      let b = obj.age;
      let c = obj.gender;
1.对象解构

通过大括号来匹配等号右边的对象

1、匹配属性
let {
    name:name,
    age:age
} = {
    name:'hhh',
    age:18,
    gende:'male',
    telephone:'123456',
    emaile:'hhhh@qq.com'
}

2、默认值解构
//默认值解构

//gender为undefined
let {name,age,gender} = {name:"terry",age:12}
//gender为男,相当于默认值
let {name,age,gender='男'} = {name:"terry",age:12}
3、特殊值解构、值–获取某种方法
//特殊值解构 、值

//获取number 2 的object的toString方法
let {toString} = 2;
//获取数组中 push的方法
let {push} = [1,2,3]
// 自动装箱 let n = new Number(2)
let n = 2;
toString.call(n)  '2'
n.toString();   '2'

​ let {} = 2:

​ 装箱拆箱—new Number(2)

​ let {tostring} = 2;//拿到2的object的toString方法

​ let {push} = [ 1,2,3]

2.数组解构–匹配
通过中括号来匹配等号右边的数组值。
let [a,b,c] = ['terry','tom','jack']

let [a,b,c,d] = ['terry','tom','jack']

let [a,b,c='rose'] = ['terry','tom','jack']
set结构,使用数组的解构赋值

新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

// a=1   b=2   d=4
let [a, [b], d] = [1, [2, 3], 4]; // 不完全解构

let [x, y, z] = new Set(['a', 'b', 'c']); //解构set集合

…rest–解构剩余的值
let [a,...b] = [1,2,3,4]
3、字符串扩展String
1、可迭代的对象–遍历

迭代对象:可以循环遍历的对象,而不可迭代的对象只是隐藏,可以通过其他方法查看,只是不能遍历,这个属性仍然存在。

使用for-of循环遍历

let str = "hello world"
for(let s of str){
console.log(s);
}
//h  e  l  l  o
2、API扩展 lodash
  • 静态方法 声明在构造函数

  • 实例方法(成员方法):声明在原型

    实例方法功能返回值
    includes()是否找到参数字符串bool
    startWith()参数字符串是否是原字符串的头部bool
    endwith()参数字符串是否是原字符串的尾部bool
    repeat(n)连续输出n个原字符串的值返回新字符串
    ‘str1’.padStart(num,str2)以str1为结尾,前面拼接上str2,总共输出num个字母,不够num重复输入str12
    ’x’.padStart(5,‘ab’) // ababx
    返回新字符串
    padEnd()与padStart类型返回新字符串
    trimStart()去掉前面的空字符串返回新字符串
    trimEnd()去掉后面的空字符串返回新字符串
    matchAll()matchAll() 方法返回一个包含所有匹配正则表达式的结果及其分组捕获组的迭代器
    const str = ‘hello javascript hello css’ console.log(…str.matchAll(/hello/g))
    返回一个迭代器,可以使用for…of…,数组新增的扩展符(…)或Array.from()实现输出功能
    replaceAll(’str’,‘target’)替代
    ’aabbcc’.replace(‘b’, ‘’) // ‘aa_bcc’ ‘aabbcc’.replace(/b/g, '’) // ‘aa__cc’ ‘aabbcc’.replaceAll(‘b’, ‘_’) // ‘aa__cc’
    返回新字符串
4、number扩展
  • 只对数值有效:

    Number.isNaN Number.isFinite

  • ES6 将全局⽅法 parseInt() 和 parseFloat() ,移植到 Number 对象上⾯,⾏为完全 保持不变。

    Numnber.parseInt(num,进制) : 可以转换字符转,第二个参数为进制,默认为十进制,不写第二个参数时会返回去掉小数的值(向下取整)

    Number.parsetFloat :会把字符串最前面的数字提取出来

  • ​ Number.isInteger

    判断一个数是否为整数

5、对象Object

静态方法—

​ Object.assign({} ,{}) – 合并,浅拷贝

​ Object.is —与 ===类似

实例

1、对象简写

ES6 允许在⼤括号⾥⾯,直接写⼊变量和函数,作为对象的属性和⽅法。

let name = 'terry'

let obj = {name}

//将方法写在构造函数外面,直接被调用
function foo(){}
let obj = {
    name:'zhangsan'sayName(){   }   ===sayName : function(){  }
}


let url = 'http',

let  id = 1;

$.get(url, {id})


2、对象速写

-) 对象
  1. 速写
  let name = "terry"
  let age = 12;
  let sayName = function(){}

  let obj = {
    name:name,
    age:age,
    sayName:sayName
  }

  let obj = {
    name,
    age,
    sayName
  }
2、对象的扩展运算符—解构
…rest–剩余的值
1、解构赋值 …other
let {name,...other} = { name: 'terry', age: 12, gender: 'male' };
name // 'terry'
other // {age: 12, gender: 'male'}
2、扩展运算符===assign

扩展运算符 对象的扩展运算符( … )⽤于取出参数对象的所有可遍历属性,拷⻉到当前对象之 中。 对象的扩展运算符等同于使⽤ Object.assign() ⽅法。

let obj = {name: 'terry', age: 12, gender: 'male'}
let o = {...obj}
o // {name: 'terry', age: 12, gender: 'male'}

//获取name  并且把除了name以外的东西赋值给...other
let {name,...other} = {name:"",a:"",b:""}

//获取param的可遍历属性,并添加page属性 
param = {
   ...param,
   page:3
}
3、…拷贝

用此方法可以实现深拷贝

let param = {
page: 2,
pageSize: 10 ,
title: ‘新冠’
}
param = {
…param,
page:3
}

3、Object静态方法扩展
1、Object.is

⽤于⽐较两个值是否相等,与严格⽐较运算符(===)的⾏为基本⼀致。

2、assign() :

将p2赋值给p1

⽤于对象的合并,将源对象(source)的所有可枚举属性,复制到⽬标对象(target)。

.此时p1值也会发生改变,加入了p2的值,

所以合并后的对象与p1公用一个引用地址,数据会同时修改

let p1 = { page: 2, pageSize: 10 }
let p2 = { title: '新冠'}
Object.assgin(p1,p2) //{ page: 2, pageSize: 10, title: '新冠' }
let param = { 
   page: 2, 
   pageSize: 10 ,
   title: '新冠'
}

//测试值
let b = Object.assign(p1,p2) 
//{ page: 2, pageSize: 10, title: '新冠', name: 'news' }

b.text = 1 
//b的值:{ page: 2, pageSize: 10, title: '新冠', name: 'news', text: 1 }
//p1的值:{ page: 2, pageSize: 10, title: '新冠', name: 'news', text: 1 }

p1.text2 = 2
//p1的值:{ page: 2, pageSize: 10, title: '新冠', name: 'news', text: 1, text2: 2 }
//b的值:{ page: 2, pageSize: 10, title: '新冠', name: 'news', text: 1, text2: 2 }

实现深拷贝–let obj2 = Object.assign({ },obj1)
let obj1 = { name: 'terry', age: 13, gender: 'male' }
let obj2 = Object.assign({ },obj1)
obj1 === obj2 // false
obj1.age = obj.age + 1;
obj1.age // 14
obj2.age // 13
如果存在引用对象–则是浅拷贝
let o1 = {a:{age:1}}
2 let o2 = Object.assign({},o1)
o1 === o2 // false
o1.a.age = 2
o2.a.age // 
3、Object.setPrototypeOf()

为某个对象设置原型

4、可迭代对象

​ 数组

​ 字符串

5、对象API

Object.is— ===

assign–合并后的数组

keys—键的数组

values —值的数组

entries: 数组的数组—二维数组–元组 【[][][ ][ ][ ] [ ] 】

let obj = { name: 'terry', age: 14, gender: 'male' };
Object.entries(obj) //[ [ 'name', 'terry' ], [ 'age', 14 ], [ 'gender', 'male']]

Object.fromEntries() 该⽅法是entries的逆操作,⽤于将⼀个键值对数组转为对象。

setPaototypeOf

getPaototypeOf

6、原型

每个函数都有一个原型对象与之对应,函数中有个指针prototype指向这个原型,圆形中有个指针constructor指向函数(不止是构造函数,也包括普通函数)

函数调用

一个函数的特性与其调用方式有关,如果通过new来调用,这个函数理解为构造函数,如果通过()。apply,call,这个函数理解为普通函数

new Number:数值的实例对象

Number:将其他数据类型转换为Number—装箱拆箱

7、数组
1、扩展运算符

可以看作是rest的逆运算,用于将数组中的元素拆分出来

 console.log(...[1, 2, 3]) // 1,2,3
2、静态方法的扩展
Array.from:

将类数组对象(可迭代),set转换为数组

let arrayLike = {
	'0': 'a',
	'1': 'b',
	'2': 'c',
	length: 3
};
// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
Array.of:Array.of (数值) :

将数值放置到数组中

include

返回⼀个布尔值,表示某个数组是否包含给定的值,与字符串的 includes ⽅法类似。

3、实例方法的扩展
find() 和 findIndex()

find ⽅法⽤于找出第⼀个符合条件的数组成员。它的 参数是⼀个回调函数,所有数组成员依次执⾏该回调函数,直到找出第⼀个返回值为 true 的 成员,然后返回该成员。如果没有符合条件的成员,则返回undefined 。

findIndex ⽅法的⽤法与 find ⽅法⾮常类似,返回第⼀个符合条件的数组成员的位 置,如果所有成员都不符合条件,则返回 -1 。

fill

给定值,填充一个数组

flat()

该⽅法⽤于将嵌套的数组“拉平”,变成⼀维的数组。

该⽅法返回⼀个新数组,对原数据没 有影响。 flat() 默认只会“拉平”⼀层,如果想要“拉平”多层的嵌套数组,可以将 flat() ⽅ 法的参数写成⼀个整数,表示想要拉平的层数,默认为1。 如果不管有多少层嵌套,都要转成⼀ 维数组,可以⽤ Infinity 关键字作为参数。

flat(Infinity):数组扁平化或递归

flatMap()

该⽅法对原数组的每个成员执⾏⼀个函数(相当于执⾏ Array.prototype.map() ),然后 对返回值组成的数组执⾏ flat() ⽅法。该⽅法返回⼀个新数组,不改变原数组。 该⽅法只能 展开⼀层数组。

// 相当于 [[2, 4], [3, 6], [4, 8]].flat()
[2, 3, 4].flatMap((x) => [x, x * 2]) // [2, 4, 3, 6, 4, 8]

非静态:

Array.prototype.keys

Array.prototype.values

Array.prototype.entries

Array.prototype.includes

Array.prototype.flat:数组扁平化 ----flat(Infinity)

8、函数扩展
函数简写:

{foo(){} ,name:‘terry’}

1.函数默认值

声明参数的时候,可以通过’='为参数设置⼀个默认值

function log(x, y = 'World') {
console.log(x, y);
}
log('Hello') // Hello World
2、参数解构
function foo({x, y = 5}) {
console.log(x, y);
}
foo({}) // undefined 5
foo({x: 1}) // 1 5
foo({x: 1, y: 2}) // 1 2
foo() // TypeError: Cannot read property 'x' of undefined
3、rest参数

将所有参数整合到一个数组----与arguments类似

function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10

​ 扩展运算符的逆运算

​ let arr = [1,2,3]

​ let n = [9,8,7…arr] //将arr打散放到数组

​ let {a,…others} = [9,8,7,6,5,4] //集合到others

4、箭头函数

lodash

更简便的函数写法。如果箭头函数不需要参数或多个参数使用()括起来

如果箭头函数代码块多于一个一条数据;否则可省略

箭头函数内部没有this

箭头函数中的this指向包含该箭头函数的外部函数的this

// function foo(){
//   function bar(){
//     console.log('bar',this);
//   }
//   bar.call(obj);
// }

function foo(){
  // this指向
  let bar = ()=>{
    console.log('bar',this);
  }
  bar.call(obj);
}


let obj = {name:'terry'}
foo()      //global
foo(obj)   //global 
foo.call(obj) // terry 改变指向  obj

let obj1 = {
  length : 1,
  foo:function(){
    console.log(this.length);
  }
}
// obj1.foo 指向的一个匿名函数  本质是一个指针
let arr = [1,2,3,obj1.foo,5] // length=5
// arr[3]()    //   5 
// console.log(arr[4]);  
var f = v => v;
// 等同于
var f = function (v) {
return v;
};
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};

9、promise–构造函数

Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法。

原型上有then、catch等同样很眼熟的方法。

Promise的构造函数接收一个参数,是函数,并且传入两个参数:resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。

new promise (function(resolve,reject))

resolve是将Promise的状态置为fullfiled

reject是将Promise的状态置为rejected。

因为promise new出来之后就会执行,不用调用。所以我们用Promise的时候一般是包在一个函数中,在需要的时候去运行这个函数

1.包装这么一个函数有毛线用?2.resolve(‘随便什么数据’);?

resolved

调用then—进行的是resolve函数

原来then里面的函数就跟我们平时的回调函数一个意思,能够在runAsync这个异步任务执行完成之后被执行。这就是Promise的作用了,简单来讲,就是能把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数。

function runAsync(){
    var p = new Promise(function(resolve, reject){
        //做一些异步操作
        setTimeout(function(){
            console.log('执行完成');
            resolve('随便什么数据');
        }, 2000);
    });
    return p;            
}
runAsync() //调用函数,会返回一个promise对象 

//会拿到我们在runAsync中调用resolve时传的的参数
//调用promise的then方法,传入函数为参数
runAsync().then(function(data){
    console.log(data);
    //后面可以用传过来的数据做些其他操作
    //......
});

promise用于做回调,但是与setTimeout的回调函数不同,在多层回调时,可以用promise对象的then进行回调

在then方法中,你也可以直接return数据而不是Promise对象,在后面的then中就可以接收到数。

链式操作的用法

Promise的精髓是“状态”

//按顺序执行,下层可以拿到上层的数据
runAsync1()
.then(function(data){
    console.log(data);
    return runAsync2();
})
.then(function(data){
    console.log(data);
    return runAsync3();
})
.then(function(data){
    console.log(data);
});

then—>可以获得上级数据,调用then,就会就会继续执行

runAsync1()
.then(function(data){
    console.log(data);
    return runAsync2();
})
.then(function(data){
    console.log(data);
    return '直接返回数据';  //这里直接返回数据
})
.then(function(data){
    console.log(data);
});
reject的用法

eject的作用就是把Promise的状态置为rejected

在then中就能捕捉到,然后执行“失败”情况的回调。

then方法可以接受两个参数,第一个对应resolve的回调,第二个对应reject的回调。

function getNumber(){
  var p = new Promise(function(resolve, reject){
      //做一些异步操作
      setTimeout(function(){
          var num = Math.ceil(Math.random()*10); //生成1-10的随机数
          if(num<=5){
              resolve(num); //成功则修改promise的状态
          }
          else{
              reject('数字太大了',num);//失败也修改promise状态,调用reject并传递一个参数
          }
      }, 2000);
  });
  return p;            
}

// getNumber返回值是一个promise对象,调用then方法,传入两个函数的参数,
// 一个对应resolved,一个是reject  
// 运行getNumber并且在then中传了两个参数,then方法可以接受两个参数,
// 第一个对应resolve的回调,第二个对应reject的回调。
getNumber()
.then(
  function(data){
      console.log('resolved');
      console.log(data);
  },
  function(reason,data){
      console.log('rejected');
      console.log(data);
      console.log(reason);
  }
);
catch的用法

1、用来指定reject的回调

2、输出resolve的语法错误,抛出异常

效果和写在then的第二个参数(reject)里面一样。不过它还有另外一个作用:在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。

getNumber()
.then(function(data){
    console.log('resolved');
    console.log(data);
})
.catch(function(reason){
    console.log('rejected');
    console.log(reason);
});
all

Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。

用Promise.all来执行,all接收一个数组参数,里面的值最终都算返回Promise对象。这样,三个异步操作的并行执行的,等到它们都执行完后才会进到then里面。那么,三个异步操作返回的数据哪里去了呢?都在then里面呢,all会把所有异步操作的结果放进一个数组中传给then,就是上面的results。

Promise
.all([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
    console.log(results);
});

博客:https://www.cnblogs.com/lvdabao/p/es6-promise-1.html

对异步操作进行封装:主要用来封装ajax

1、异步函数封装:

  • 回调函数—无法将异步操作单独封装(ajax:success
  • promise----异步操作单独封装

2、AJAX—异步的JavaScript和XML

  • 请求报文
    • 请求行
    • 请求头
    • 请求体
  • 响应报文

状态:待定pending 成功 resolve rejecte

1、构造函数

let p = new Promise((resolve,rejected)=>{
    
})

let promise = new Promise((resolve,reject)=>{
  console.log('start');
  setTimeout(()=>{
    let random = Math.random();
    console.log(random);
    if(random>0.5){
      resolve();
    }else{
      reject();
    }
  },1000)
  console.log('end');
})

promise.then((res)=>{
  console.log('successful',res);
}).catch(()=>{
  console.log('failure');
})

2、静态方法

3、实例方法

10、symbol

它是一种新的基础数据类型,它的功能类似于一种标识唯一性的ID。

可以通过调用Symbol()函数来创建一个Symbol实例

let s1 = Symbol()
	或者,你也可以在调用Symbol()函数时传入一个可选的字符串参数,相当于给你创建的Symbol实例一个描述信息:
	let s2 = Symbol('another symbol')

	由于Symbol是一种基础数据类型,所以当我们使用typeof去检查它的类型的时候,它会返回一个属于自己的类型symbol,而不是什么string、object之类的:
	typeof s1  // 'symbol'
	
	另外 每个Symbol实例都是唯一的 ,所以当你比较两个Symbol实例的时候,将总会返回falseconst a=Symbol("name");
    const b=Symbol("name");
    console.log(a===b) //false
————————————————
版权声明:本文为CSDN博主「小时俞」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42384718/article/details/108478735
1.使用symbol作为对象属性名
    const name=Symbol();
    const age=Symbol();
    let obj={
         [name]:"已经代码"
    }
    obj[age]=18;
    console.log(obj[name]);//已经代码
    console.log(obj[age]);//18
使用了Symbol作为对象的属性key后不能使用枚举方法

1.Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
2.Object.getOwnPropertySymbols()方法返回一个给定对象自身的所有 Symbol 属性的数组。

2、使用Symbol定义类的私有属性/方法
    const Hero=(()=>{
        const getRandom=Symbol();
        return class Person{
            constructor(a,b,c){
                this.a=a;
                this.b=b;
                this.c=c;
            }
            gongji(){
                // const gj=
            }
            [getRandom](max,min){
                return Math.random()*(max-min)+min;
            }
        }
    })()
    var per=new Hero(10,20,30,40);
    console.log(per); //Person {a: 10, b: 20, c: 30}
    // console.log(per[getRandom](10,20)); //报错
    
    // 上面这种方法调用不到,因为现在的[getRandom]在Hero的原型上
    
    const sybs=Object.getOwnPropertySymbols(Hero.prototype)
    console.log(sybs); //所以要访问Hero的原型才可以调用输出到

Symbol.hasInstance:

其它对象使用instanceof运算符的时候会使用该属性名指向的内部方法。

当其他对象使⽤ instanceof 运 算符,判断是否为该对象的实例时,会调⽤这个⽅法。

Symbol.for()

会根据给定的键 key,来从运行时的 symbol 注册表中找到对应的 symbol,如果找到了,则返回它,否则,新建一个与该键关联的 symbol,并放入全局 symbol 注册表中。

	Symbol.for("foo"); // 创建一个 symbol 并放入 symbol 注册表中,键为 "foo"
	Symbol.for("foo"); // 从 symbol 注册表中读取键为"foo"的 symbol

	Symbol.for("bar") === Symbol.for("bar"); // true,证明了上面说的
	Symbol("bar") === Symbol("bar"); // false,Symbol() 函数每次都会返回新的一个 symbol

	var sym = Symbol.for("mario");
	sym.toString(); 
	// "Symbol(mario)",mario 既是该 symbol 在 symbol 注册表中的键名,又是该 symbol 自身的描述字符串

函数,无法使用new来调用,每次执行都可以产生一个唯一的值,这个值用来当作属性名

1、symbol()函数 产生唯一Symbol值

2、Symbol(flag)

​ flag标识符 表示标识

3、Symbol.for 复用


4、Symbol.keyfor:

返回⼀个已登记的 Symbol 类型值的 key

5、Object.getOwnPropertySymbols()

6、系统内置 Symbol

Symbol.hasInstance

所有构造函数都内置这个方法,阿当instanseof的时候会调用instanceof

let obj = {
    [Symbol.hasInstanse]:function(){
        
    }
}

6、Symbol.itetrator

11、迭代器 iterator

for

for of 支持es6 遍历数组

forEach Array.forEach 数组方法

for in :更多用来遍历对象

Symbol.iterator - —

类数组本身没有迭代器

使用

arrLike [Symbol.iterator] = [][ Symbol.interator ]  

一些内置类型拥有默认的迭代器行为

Array.prototype[Symbol.iterator]()TypedArray.prototype[Symbol.iterator]()String.prototype[Symbol.iterator]()Map.prototype[Symbol.iterator]()Set.prototype[Symbol.iterator]()

next()遍历:

每次next遍历:返回value 和 done 两个属性的对象。其中, value 属性是当前成员的值, done 属性是 ⼀个布尔值,表示遍历是否结束

1、执行过程

next() 调用 ->指针

2、es6可迭代对象

​ 数组、字符串、set、map

数组:

​ Array.prototype[Symbol.iterator]

​ arr.keys()—返回迭代器 Object.keys—返回一个数组

​ arr.values()

​ 实例对象可以直接访问Symbol.iterator,构造函数实现了Symbol.iterator接口

// 标准
inteface Iterator {
   [Symbol.iterator]():void;
}
 // 类 == 构造函数 Array String Set Map
class Array implements Iterator{
    [Symbol.iterator]():void{
    }
}
let arr = [1,2,3]
arr[Symbol.iterator]()
for(let a of arr){}
3、触发迭代器执行的场景

for-of

new Set /new Map()

Array.from(可迭代参数)----

Promise.all()

Promise.race()

4、迭代器方法

next—{value,done}

next(参数)—参数是上一个yield的返回值

5、迭代器实现

类数组对象

12、集合

是对数组和对象的拓展

1、set–

一种特殊的map 键===值

可以接收一个数组(或其他iterator对象)

不可以存储相同的值,不可以通过索引来访问

let arr = [1,2,3,4,5,6]

1、构造函数

new Set()

2、原型–成员方法

size

add

delete

clear

keys

values----keys = == values

entires—键值对数组—set键值相等

forEach、

数组去重

let arr = [1,2,5,3,1]
let result = [...new Set(arr)]
2、map—键值对

类似于对象,也是键值对的集合

键可以是任意值

Map可以提供额外的api

如何将一个对象转换为map

1、构造函数

参数是两个数组:entries

let map = new Map([[],[]])
2、原型方法

set

delete

clear

has

13、proxy 代理
1、对象 setter/getter

let obj = { }//目标对象

let proxy = new Proxy(obj,{
  set(target,key,val){
    console.log('setter----');
    target[key] = val;
  },
  get(target,key){
    console.log('getter----');
    return target[key];
  }
})


proxy.name = 'terry'

console.log(proxy.name);
2、 函数 apply
let foo = function(msg){
  console.log('hello',this.name,msg);
}

let proxy = new Proxy(foo,{
  apply(target,that,args){
    //console.log(target); //function:foo
    //console.log(that);  //name
    //console.log(args);  //参数
     target.apply(that,args)
  }
})
proxy('terry');
proxy.call({},'terry')
proxy.apply({},['terry'])


proxy.call({name:"terry"},'good day')
3、构造函数constructor

构造函数劫持,当通过new来调⽤代理的时候会触发contructor函数的执⾏

let Person = function(name){this.name = name}
let proxy = new Proxy(Person,{
   constructor(target,args){
       //返回所有的构造函数的属性
   return new target(...args)
  }
})



function Foo(name){
	this.name = name;
}
let pp = new Proxy(Foo,{
	construct(target,args){
	return new target(...args)
	}
})
//当new一个代理时,会调用构造函数,然会所有属性
console.log(new pp('terry').name);

14、反射

反射:它提供了一个Reflect对象API;该对像中的方法默认特性与底层的操作对应;而每一个代理陷阱会对应一个命名和参数都相同的Reflect方法(其实就是每个代理陷阱都会对应一个Reflect api接口供覆写JavaScript底层操作)

调用Reflect的api方法

Reflect:配合反射。 是⼀个内置的对象,它提供拦截 JavaScript 操作的⽅法。

与代理一一对应,为代理提供方法,操作set/操作get/操作apply/操作constructor操作

1、set/get

调用Reflect的set/get方法

        let proxy = new Proxy(obj, {    // 代理          set(target,key,val){              // target[key] = val;            Reflect.set(target,key,val)          },          get(target,key){              // return target[key]             return Reflect.get(target,key)          }        })
2、apply
let foo = function(msg){
  console.log('hello',this.name,msg)
}
// foo.call({name:"terry"},'good day')
let proxy = new Proxy(foo, {
  apply(target,that,args){
    //target.apply(that,args)
    Reflect.apply(target,that,args)
  }
})
proxy.call({name:"terry"},'good day')
3、constructor

对构造函数进⾏ new 操作,相当于执⾏ new target(…args) 。

function Foo(name){
	this.name = name;
}
let proxy = new Proxy(Foo,{
	construct(target,args){
  //调用Reflect的constructot  new target(...args) 。
	return Reflect.construct(target,args)
	}
})

console.log(new proxy('terry').name);

15、promise

异步操作的解决方案,常用于封装ajax

axios就是基于promise对ajax的封装

1、axios
  • 特点

    axios.get(url[,options])

    axios.post(url,data[,options])

    xmlhttpRequest(浏览器) http(nodejs)

    默认将data(param)(post)转换为json

    params(get)

    支持promise

  • nodejs中的应用

    cnpm install axios  --save  :--save:安装记录保存
    
    安装cnpm
    $ npm install cnpm -g --registry=https://registry.npm.taobao.org
    
    $ npm init
    $ cnpm install axios --save
    
  • 实例化

    axios({
        url
        method,
        data(post),
        params(get),  
    })
    

3、配置

4、拦截器

5、快捷方法

2、原生ajax的封装
function loadArticle(){
    return new Promise((resolde,reject)=>{
        let xhr = new XHRHttpRequest();
        xhr.open();
        xhr.setRequestHearders()
        xhr.send();
        xhr.onreadystatechange = function(){
            if(this.readyState===4){
                if(this.status === 200){
                    resolve(this.response)
                }else{
                    reject(this.response)
                }
            }
        }
    })
}

// promise对象可以调用 then。catch。finally
loadArticles().then().catch().finally()
3、成员方法

then/catch/finally 返回值都是promise对象

promis.prototype.then(success,error)

promise.prototyoe.catch(error) === promis.prototype.then(null,error)

promise.prototype.finally(handller):释放一些对象。

4、静态方法
promise.all([p1,p2------]):

当方法返回值是promise,当p1,p2----全部执行完毕后并且状态为resolved的时候,promise的then才会被调用,该then的回调函数的参数是p1,p2-----的运行结果

案例:当查询所有的班级,取到后再调用查询学生的接口,默认查询第一个班级的学生

let promise = Promise.allSettled([p1,p2])
promise.then(result =>{
  console.log('--------------结束-----------');
  console.log(result);
})
promise.race(iterable)

只要状态改变就调用then 返回率先改变状态的promise结果,谁先执行完毕就返回谁

let promise = Promise.race([p1,p2])
promise.then(result =>{
  console.log(result);
})
promise.allSettled(iterable)

等待所有执行完成并返回所有结果,不论成功还是失败。

返回值为promise,与all不同,当所有的promise对象状态被确认的时候会执行then,then的参数为结果

等到所有promises都已敲定(settled)(每个promise都已兑现(fulfilled)或已拒绝 (rejected))。返回⼀个promise,该promise在所有promise完成后完成。并带有⼀个对象数 组,每个对象对应每个promise的结果。

let promise = Promise.allSettled([p1,p2])
promise.then(result =>{
  console.log('--------------结束-----------');
  console.log(result);
})
promise.resolve()

直接返回一个promise对象,状态为成功

promise.reject()

直接返回一个promise对象,状态为失败

promise.any(iterable) —实验性的

(iterable) 可迭代对象,常见的数组或set 可迭代对象中的元素是promise

16、generator函数

Generator 函数是⼀个普通函数,但是有两个特征。

Generator特征

1、 function 关键 字与函数名之间有⼀个星号;

2、函数体内部使⽤ yield 表达式,定义不同的内部状态,yield :产出

functon*(){ }

1、执行
  • 调⽤ Generator 函数,返回⼀个迭代器对象,代表 Generator 函数的内部指针。以后,每 次调⽤遍历器对象的 next ⽅法,就会返回⼀个有着 value 和 done 两个属性的对象。

  • 迭代器是通过generator函数实现的,generator还可以实现异步函数同步化。但是他的执行很麻烦,通常借助co模块。async函数与generator函数非常相似,内置了执行器

迭代器本质上就是一个generator函数

yield :产出

function* foo(){
    yield 'terry',
    yield 'tarry',
    yield 'jacky'
}
2、next参数

next⽅法可以带⼀个参数,该参数就会被当作上⼀个yield表达式的返回值。

next参数可以作为上一个yield的返回值

function* foo(){
  let resp = yield 'hello';
  console.log('foo-',resp);
  yield 'world';
}
let iterator = foo();
iterator.next();  // {value:'hello',done:false}
iterator.next(888); // foo- 888
function* gen(x){
	let y = yield x+1;
	return y
}
let iterator = gen(5);
iterator.next() // 6
iterator.next(8) //8  //这里写的参数被当作上一个的返回值
3、generator函数实现⾃定义迭代器
class ArrayLike{
  constructor(args){
    for(let i=0;i<args.length;i++){
      let val = args[i]
      this[i] = val;
    }
    Object.defineProperty(this,'length',{
      configurable:true,
      enumerable:false,
      value:args.length
    })
  }
  // 请你实现迭代函数
  * [Symbol.iterator](){
    for(let k in this){
      let v = this[k]
      let index = parseInt(k)
      console.log('自定义迭代器',v,index);
      yield {value:v,done:index<this.length?false:true}
    }
  }
}
let arr = new ArrayLike(['terry','larry','tom']);
// console.log(arr);

//使用for-of 会调用迭代器
for(let a of arr){
  console.log(a);
}

4、异步任务封装

axios的get⽅法可以返回⼀个promise对象,

通过yield表达式可以阻塞ajax代码的执⾏

let axios = require('axios');
let p1 = axios({
  url:'http://121.199.29.84:8001/index/carousel/findAll',
  method:'GET'
});

let p2 = axios({
  url:'http://121.199.29.84:8001/index/category/findAll',
  method:'GET'
});
function* foo(){
  let resp1 = yield p1;
  console.log(resp1.data);
  let resp2 = yield p2;
  console.log(resp2.data);
}


let iterator = foo();
// 当p1执行完毕后,我再执行p2
// {value:p1,done:false}
iterator.next().value.then(resp=>{
  //{value:p2:done:false}
  iterator.next(resp).value.then(res=>{
    iterator.next(res);
  })
})
5、co模块

co模块是著名程序员 TJ Holowaychuk 于 2013 年 6 ⽉发布的⼀个⼩⼯具,⽤于 Generator 函数的⾃动执⾏。该函数返回⼀个 Promise 对象,因此可以⽤ then ⽅法添加回 调函数。

let axios = require('axios');
let co = require('co')
let p1 = axios({
  url:'http://121.199.29.84:8001/index/carousel/findAll',
  method:'GET'
});

let p2 = axios({
  url:'http://121.199.29.84:8001/index/category/findAll',
  method:'GET'
});
function* foo(){
  let resp1 = yield p1;
  console.log(resp1.data);
  let resp2 = yield p2;
  console.log(resp2.data);
}
co(foo)
17、异步函数async

1、内置了执行器

2、语法特点

​ async function foo(){ }

​ async ()=>{}

​ await

3、返回值 : promise

async 函数就是 Generator 函数的语法糖。使得异步操作变得更加⽅便。

async 函数就 是将 Generator 函数的星号( * )替换成 async ,

将 yield 替换成 await ,仅此⽽已。

let axios = require('axios');
let p1 = axios({
  url:'http://121.199.29.84:8001/index/carousel/findAll',
  method:'GET'
});

let p2 = axios({
  url:'http://121.199.29.84:8001/index/category/findAll',
  method:'GET'
});
async function foo(){
//加入await  变成同步
//await 命令后⾯是⼀个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。
  let resp1 = await p1;
  console.log(resp1.data);
  let resp2 = await p2;
  console.log(resp2.data);
}
foo();

18、面向对象

ES6 的 class 可以看作只是⼀个语法糖,它的绝⼤部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像⾯向对象编程的语法⽽已。

function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);

等价写法

class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}

成员属性

成员方法

静态属性 static num= 10;

静态方法 static baz(){ }

1、构造函数

coustructor()方法是类的默认方法,通过new 命令生成对象实例时,自动调用该方法,一个类必须有constructor,如果没有显示定义,一个空空的constructor会被自动添加。

function Animal(name,age){
    this.name = name;
    this.age = age;
}
let animal = new Animal('terry','18')
-------------------------------------
 class Animal{
     //构造函数
     constructor(namem,age){
         this.name = name;
         this.age = ahe;
     }
 }

class 为关键字

Animal:类名,驼峰命名法

{}为类体:其中可以包含构造函数、成员属性,静态方法,静态属性、

2、实例对象—非纯对象

通过构造函数创建的对象

plain object 纯对象 ({},new Object())

3、原型方法 —成员方法 实例方法
class Animal{
    name; //成员本身中
    sayName(){  //方法放在原型
        
    }
}
4、构造函数方法 --静态方法
class Animal{
    name; //成员本身中
    sayName(){  //方法放在原型
        
    }
    static foo(){  } //类  通过类直接访问
}
5、继承

es5实现继承:修改原型链

​ 1、原型链继承:dog.prototype = new Animal() 子构造函数的原型指向父构造函数的实例

​ 如果⼦类提供了constructor,那么必须在 constructor ⽅法中调⽤ super ⽅ 法,

​ 2、借用构造函数:

//ES5
function Dog(age,name,gender){
    Animal.call(this,name,age)
    this,gender = gender;
}

Dog.prototype = new Animal()
Dog.prototype.constructor = Dog;
Dog.prototype.xxx   //实例方法
Dog.xxx             //构造函数方法  静态帆帆发
///ES6
class Dog extends Animal{
    constructor(name,age){
        super(name,age)
    	this.gender = gender;
    }
    sayGender(){

     }
}
19、模块化

任何一个js文件或者是目录都可以是一个模块秒如果目录作为一个模块,那么,目录应该出现一个package.json

$ npm init -y   ---生成一个package.json文件

$ npm install qs --save

链接互联网,获取qs库?中央仓库,下载当前目录的node_modules

​ --save :本地安装并且将依赖版本号写到package.json

1、commonJS 模块化

​ 社区提供的

在⼀个⽂件⾥⾯定义的变 量、函数、类,都是私有的,对其他⽂件不可⻅。每个模块内部,

暴露属性方法:

加载属性方法

​ var example = require(’./example.js’);

1、模块的暴露

模块内部的变量其他模块不能访问,如果想要其他模块进行访问,需要进行接口的暴露。

  • ​ module 变量代表当前模 块。这个变量是⼀个对象,
  • ​ 它的 exports 属性(即 module.exports )是对外的接⼝。
  • ​ module.exports.XXX :是变量或者方法

modules.export

​ module是一个对象,每个模块都拥有这个对象,

​ exports相当于将当前目录信息传递到其他模块,其默认值是一个空对象。

​ module.export.xxx

​ module.export = {}

2、模块引用

​ 当模块为自定义的时候,参数为文件路径

​ require(’./a.js’)

​ 当模块为内置模块时,参数为模块名称

​ require(‘http’)

​ 当模块为第三方模块时,参数为模块名称,但是需要先进行模块的安装

 $ cnpm install axios --save
 require('axios');
2、ES6模块化

在ES6中每⼀个模块即是⼀个⽂件,在⽂件中定义的变量,函数,对象在外部是⽆法获取 的。如果你希望外部可以读取模块当中的内容,就必须使⽤export来对其进⾏暴露(输出)。

​ 官方提供的

​ 如果想要让node.js支持es6模块化,:nodejs v14.0+

​ package.json添加一个配置项 type:“module”

模块暴露export:

export声明

  • 多次使用,使用哪个变量暴露哪个,就要使用哪个变量获取export default声明

  • 尽可使用一次,可以使用任意变量名来获取

  • 一个模块中可以既使用export又使用export default

var firstName = 'Michael';
var lastName = 'vicky';
export { firstName, lastName }; //列表导出
export { firstName as first, lastName as last}; //重命名导出
export var a = 3; //导出单个属性
export function multiply(x, y) { return x * y; }; //导出单个属性
//默认导出,一个模块只能有一个默认导出,不能使用 var、let 或 const 用于导出默认值 ex
export default {}
export default function foo(){}
var a = 1;
export a; //报错,因为没有提供对外的接口。应该export var a = 1; 或者export {a}
export defalt
  • export default命令,为模块指定默认输出。
  • export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字
  • export default命令用于指定模块的默认输出。显然,一个模块只能有一个默认输出,因此export default命令只能使用一次。所以,import命令后面才不用加大括号,因为只可能唯一对应export default命令。
  • export default 命令的本质是将后面的值,赋给default变量,所以可以直接将一个值写在export default之后
导入import
import * as person from './person.js' //导入整个模块内容
import {firstName,lastName} from './person.js' //导入多个接口
import {firstName as name} from './person.js' //重命名
import '/modules/my-module.js'; //运行整个模块而不导入任何值
import myDefault from './my-module.js'; 
浏览器导入ES6模块

浏览器加载 ES6 模块,也是使⽤ script标签

等同于script标签的defer属性

<script type="module">
import utils from "axios";
// other code
</script>

CommonJS模块与ES 模块区别

CommonJS 模块输出的是⼀个值的拷⻉,ES6 模块输出的是值的引⽤。

CommonJS 模块是运⾏时加载,ES6 模块是编译时输出接⼝。

CommonJS 模块的 require() 是同步加载模块,ES6 模块的 import 命令是异步加载, 有⼀个独⽴的模块依赖的解析阶段。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值