【无标题】

ES6

防抖和节流

防抖

function debounce(delay,fun){
let timmer=null;

return function(){
    if(timmer){
        clearTimeout(timmer);
    }
    timmer = setTimeout(function(){
        fun && fun();
    },delay);
    
}

};

节流

function throttle(delay,fun){
let startTimmer = 0;//设置开始时间
return function(){
    let currTime = new Date();
    //计算时间差
    if(currTime - startTimmer >= delay){
        startTimmer = currTime;
        fun && fun();
    }
};

}

扩展运算符

概念

在对象中使用扩展运算符(…),用来取出参数对象的所有可以遍历的属性,复制到当前对象中

扩展运算符的功能

1.它可以将数组转化为逗号分隔的参数序列
2.可以复制数组,也是一个深拷贝
3.可以把一个字符串,转化为数组
4.扩展运算符和结构赋值结合在一起,用来生成数组
扩展运算符使用在函数中,一定是最后一个参数使用,表示把剩余的参数存放到一个数组中(此刻也叫rest参数)


function sum3(str1,str2,…arg){
console.log( str1 );
console.log( str2 );

let total = 0;
for(let i=0;i<arg.length;i++){
    total += arg[i];
}
console.log( total );

}
sum3(‘hello’,‘world’,1,2,3,4,5,56);

解构赋值

概念

模式匹配:等号两边的数据模式相同,那么左侧的变量名,会被对应的右侧内容赋值

	let [v1,v2,v3] = ['朝鲜','韩国','日本'];
	console.log( v1,v2,v3 );

结合扩展运算符使用

let [s5,s6,...s7] =['土耳其','巴黎','迈阿密','泰国','新加坡'];
console.log(  s5,s6,s7 );

对对象进行解构赋值,只和对象的属性名有关,和次序无关

	let { age,name,job } = { name:'甲乙丙',job:'村支书',age:40 };
	console.log( age,name,job );

实际上上面的写法,可以理解为下面写法的简写形式,也就是说,对象形式的解构赋值的内部机制是,先找到同名属性,然后再赋值给对应的变量,真正被赋值的是左侧属性名所对应的属性值,此时属性值是一个变量

用途

//交换变量

let num1 = 20;
let num2 = 30;

// let temp = num1;
// num1 = num2;
// num2 = temp;
[num2,num1] = [num1,num2];
console.log( num1,num2 );

同时接收函数返回的多个值

function test(){
return ['孙悟空',230,'男'];
}
let [name2,age2,sex] = test();
console.log( name2,age2,sex );

//json解析

let json = {
name3:name2,
age3:age2,
sex1:sex
};
let {name3,age3,sex1} = json;
console.log( name3,age3,sex1 );

拷贝对象

在对象中使用扩展运算符,用来取出参数对象中所有的可遍历属性和方法,复制到当前对象中,这是一个深拷贝

let obj = {
name:'许仙',
age:20,
};
let obj1 = { ...obj,son:'许士林' };
obj1.job = '医生'
console.log( obj,obj1 );//不会影响obj

Object.assign(参数1,参数2,参数3) 把从参数2开始的所有对象的属性,都复制到参数1中,如果右相同属性,则覆盖,得出的参数1,是合并后的结果
返回值也是合并后的结果·

let abc = Object.assign(obj,obj1,obj2);
console.log( obj );
console.log( abc );
//常用放法
let obj3 = Object.assign({},obj,obj1,obj2);

字符串操作

includes(‘目标字符串’):返回一个布尔值,表示当前字符串中是否含有目标字符串
stratsWith(‘目标字符串’):返回一个布尔值,表示当前字符串是否以目标字符串开头
endsWith(‘目标字符串’):返回一个布尔值,表示当前字符串是否以目标字符串结尾

let str1 = '民国万税,天下太贫';
console.log( str1.indexOf('万税') );
console.log( str1.includes('万税') );
console.log( str1.startsWith('民国') );
console.log( str1.endsWith('天下') );

数组操作

1.Array.from() 用来将两类对象转化为真正的数组,第一是类似数组的对象第二是可遍历的对象(包含 ES6新增的 Set 和 Map)

2.Array.from() 还可以接受第二个参数,作用和map类似,可以对可遍历的对象中的数据加以操作,返回到数组中对应的位置

3.Array.of() 它可以将一组数据,转化为数组

数组实例的方法

find() 它的参数是一个回调函数,该回调函数的参数是每一次查找的数组元素,该回调该函数返回一个判断条件。find()方法返回的是满足该判断条件的第一个数组元素。如果没有符合条件的元素,返回一个undefined。

findIndex 使用方式和find()类似,返回第一个满足条件的数组元素的下标,如果没有符合条件的元素,返回-1。

fill(填充内容) 用来填充数组的值,返回填充后的数组(原数组)

fill(填充内容) 用来初始化空数组,他会把原数组中的所有内容清空

fill(填充内容) 还可以接受第二个和第三个参数,用来指定填充的起始位置和结束位置

includes() 方法返回的是一个布尔值,表示是否含有指定的数组元素,和字符串的includes()方法一致,都是属于ES7中的方法

该方法还有第二个参数,第二个参数代表开始查找的位置,如果为负数,则表示倒着数,如果负数的绝对值大于数组的长度,则从0开始查找

indexOf() 的两个缺点,第一是不够语义化,他的真正用途是用来查找某一个数据值在数组中的下标,并且每一次比较都是数据和-1的比较表达不够直观。第二,它的内部是严格使用全等运算符(===)进行判断,这样会导致NaN的误判,
includes使用的是不同的判断方法,不会有这个问腿

函数操作

设置函数参数的默认值
设置的方式是参数=默认值,如果在函数调用的时候,传入了实参,该参数的值就是实参值,如果没有传入实参,则该参数的值就是默认值

函数作用域:一旦设置了参数的默认值,函数就会进行声明初始化的时候,参数会形成一个单独的作用域,如果初始化结束,则这个作用域消失。这个作用域在不设置默认参数值的时候是没有的

箭头函数

如果箭头函数体中,只有一个返回语句,则可以把 {} 和 return 都省略
给箭头函数传参,
如果箭头函数只有一个参数,则可以省略包裹参数的()

由于{} 括号会被解析为代码块,所以如果箭头函数返回一个对象的话,必须在对象外面包裹一个(),否则会报错

箭头函数注意

使用箭头函数需要注意的问题
1.箭头函数中的this,指的是箭头函数创建时候所在对象的this,不是使用时候所在对象的this(其实箭头函数没有this)
2.箭头函数不能当作构造函数,也就是说箭头函数不能使用new操作符,否则报错
3.箭头函数没有arguments,如果需要使用类似功能,则可以使用rest参数
4.箭头函数不能作构造器函数

由于箭头函数中没有自己的this,因此就不能使用 call() apply() bind() 等方法改变this的指向

//箭头函数不能用作构造函数
// let My = ()=>{
// this.name=‘蚩尤’;
// this.age=200;
// };
// let my = new My();

// console.log( my );

//箭头函数没有arguments,因此以下箭头函数中的arguments使sum的arguments

对象操作

1.对象的简写,如果属性名和属性值的外形一致的时候,可以简写为一个
对象方法简写,直接写如下形式
obj = {
msg(){

}

}

2.Object.is(obj1,obj2) 用来比较两个对象是否相等

返回true的情况
两个参数都是 undefined,或者一个是undefined,一个为空
两个参数都是 null
两个参数都是 NaN
两个参数都是 相同的字符串
两个参数都是 指向同一个对象
两个参数都是 相同的布尔值(同true或者同false)
两个参数都是 +0 或者都是 -0

3.Object.defineProperty(属性所在的对象,属性名,属性的配置项)
用来修改或者添加一个对象的属性,如果该属性存在,则是修改,否则为添加属性

属性配置项 是一个对象,用来给属性配置更加完善的信息
configurable:表示设置是否通过 delete 关键字删除该属性,默认为false
writable:表示设置是否可以 修改 该属性的值,默认是 false
enumerable:表示设置是否可以 通过 for-in 循环访问该属性,默认是 false
value:设置该属性的值,默认是 undefined

get方法:读取该属性的时候,执行的方法,默认是 undefined
set方法:外部设置(修改)该属性值的时候,执行的方法,默认是 undefined

注意,设置 get 和 set 方法的时候,不能同时设置 value 和 writable 属性

Set数据

概念

Es6提供了新的数据结构 Set ,它类似于数组,但是它里面的元素都是唯一的,没有重复的值,Set 是一个构造函数,用来实例化Set 数据对象

通过 add方法添加set数据

let arr1 = [1,2,3,4,1,2,3,4];
arr1.forEach(item=>s1.add(item));

把 set 转化为 数组

let arr2 = Array.from(s1);
console.log( [...s1] );
console.log( arr2 );

Set 可以接收一个数组或者类似数组的对象,用来初始化实例对象

let s2 = new Set([1,2,3,1,2,3,'刘备','刘备']);
console.log( [...s2] );

Set 数据结构的实例具有以下属性 和方法

size属性,返回实例的数据总数

操作方法
add(添加的内容) 添加某个值,返回的是 实例本身
delete(删除的内容) 删除某个内容,返回的是一个布尔值,表示删除是否成功
has(查询的内容) 返回一个布尔值,表示实例中是否含有 查询的内容
clear() 清空所有内容
遍历方法
keys() 返回所有数据的键名
values() 返回所有数据的键值
entries() 返回所有数据的键值对
forEach() 使用该方法遍历实例中所有的数据

Promise

概念

Promise 他是异步编程的一个优化方案,他比传统的方法更加合理,更加强大
Promise 对象,可以把异步操作 以 同步操作的形式展示出来,避免了回调地狱(指的是回调函数相互嵌套多层)的出现。Promise 对象提供了很多方法,使其控制异步操作更加方便

Promise 是一个构造函数,用来生成一个Promise 实例对象

一个Promise是一个异步操作,它具有三种状态:Pending(进行中),Resolve(操作已完成,也叫fulfilled) 和Rejected(已失败)。只有在异步操作结束的时候,才会知道当前是哪一个状态,任何操作都无法改变操作结果的状态。

创建一个Promise实例,在构造函数的回调中具有两个参数,第一个参数叫resolve,他是 异步操作成功执行后 执行的方法,可以把成功的数据传递出去,第二个参数叫reject,他是异步操作执行失败后 执行的方法,用来提示操作失败。这两个参数是由js引擎提供的,所以不需要开发者自己绑定

Promise实例

resolve 函数的作用是,将 promise对象的状态从pendig(进行中) 变成 fulfilled(已完成),并且会将异步操作的结果通过参数的形似,传递出去
reject 函数的作用是,将 promise对象的状态从pendig(进行中) 变成 rejected(已失败),并且会将异步操作失败的结果,通过参数的形式,传递出去

通过promise实例传递出去的数据,可以使用promise实例的then方法来接收
then方法可以接受两个参数,每一个参数都是一个回调函数。第一个回调函数是promise对象的状态变化为fulfilled的时候调用。第二个回调函数是 promise对象的状态变化为rejected时候调用。可以简单理解为,promise对象中的 异步操作执行成功,调用第一个参数,否则调用第二个参数
第二个参数是可以省略的。
两个回调函数都接受来自promise对象传递的值作为参数。

then的理解

then方法中的回调函数,返回的是一个新的promise实例。不是原来的那个实例
then方法也可以写成链式操作。

then的回调函数一般返回三种情况

  1. 函数中返回的是一个 非 promise实例,默认通过then之后会变成一个promise实例,并且实例的状态是fulfilled,因此通过下一个下一个then() 直接获取返回的数据
  2. 函数直接返回一个promise实例
  3. 抛出一个错误 throw new Error(‘失败是成功之母’)

Promise的方法

通过 catch() 可以直接接收 rejected 状态的信息,简单理解为专门处理异步操作错误时候的方法,用法和then一样

promise原型对象具有的方法,用来直接处理promise
all() 他是promise的静态方法,并且它返回一个新的promise,当前参数数组中的所有Promise都是成功状态的时候,返回的是一个所有数组成员的返回值 组成的数组。如果数组中有一个是 rejected状态,则返回一个rejected,并且带有错误信息。特点是按次序执行数组中所有的 Promise实例

race() 他是promise的静态方法,并且它返回一个新的promise,参数也是一个Promise实例数组,他只返回一个最先完成异步操作的Promise。如果数组中有一个是 rejected状态,则返回一个rejected,并且带有错误信息。(有一个错误就返回错误信息)

any() 特点和race一致,不同的是,只有当 数组中和所有的 Promise都是rejected 状态的时候,才返回rejected。

resolve() 该方法直接返回一个状态时 fullfilled Promise实例
具有4种参数
1.无参数
2.参数时普通数据
3.参数是一个 thenable对象
thenable = {
then:()=>{}
}
4.参数是一个 Pomise 实例

reject()

类的继承

es6中创建类的关键字时 class

class 类名 {
constructor(){
类的构造函数
}
类的属性
类的方法

} 类名首字母大写

constructor() 构造方法,他是类的默认方法,在类实例化对象的时候,会自动调用该方法。一个类必须有 constructor 方法,如果constructor方法没有被显式声明,那么他会在执行的时候隐式声明。constructor() 方法的返回值是实例对象.

类也具有原型对象,可以在原型属性上设置方法
在类的实例上调用方法,其实就是在调用原型上的方法,因为所有的类的方法都会被定义在原型上

同ES5不同的是,类没有变量提升的概念,必须在声明之后才能使用类

class Animal {
//类的属性,实例化的时候无法传入
sex='母';
//构造函数
constructor(type,name,color,sex=this.sex){
    //构造函数中的this代表的是 实例对象
    //类的属性
    this.type = type;
    this.name = name;
    this.color = color;
    this.sex = sex;
}

//创建类的方法
show(){
    console.log( this.type+':这是一个动物'+this.name );
}
run(){
    console.log( '动物都会跑' );
}
}

//实例 Animal 类 的 对象
let ani = new Animal('狗','旺财','黑色','其他');

ani.show();
ani.run();

console.log( ani.sex );
//类也具有原型属性
class Food{
name='胡辣汤';
price = 3;

show(){
    console.log( this.name+'真好喝' );
}
}

Food.prototype.love = function(){
console.log( this.name+'很爱喝' );
}
let f = new Food();
f.love();
f.show();

console.log( f.love === Food.prototype.love );
console.log( f.show === Food.prototype.show );

可以使用声明变量的形式声明类
const MyClass = class My{
getName(){
    // console.log( this.name );undefined 因为实例没有name属性
    console.log( My.name );// My只能在类内部使用
}
}

let m1 = new MyClass();
m1.getName();
console.log( m1.name );
console.log( My.name );//My只能在类内部使用
console.log( MyClass.name );//结果是 My

类的继承

例子

/*
两个class之间可以通过 extends 关键字来显示继承
*/

//父类
class Animal {
food = '动物吃什么';
constructor(type,age){
    this.type = type;
    this.age = age
}
show(){
    console.log( `${this.type}的寿命是${this.age}岁` );
}
}
//子类
class Dog extends Animal {
    constructor(type,age,food){
        super(type,age);
        this.food  = food;
    }
    msg(){
        console.log( this.food );
        super.show();
    }
    show(){
        console.log( '狗是人类的好朋友' );
    }
}
let dog1 = new Dog('狗',20,'肉狗粮');
dog1.show();
dog1.msg();

在子类的constructor中,有一个super()方法,他在此处表示父类的构造函数,用来新建父类的this对象
子类有显式的constructor()方法,必须在constructor中执行super(),否则会报错。因为子类没有自己的this对象,是继承父类的this对象。

两一个需要注意的地方是,在子类的constructor()中,必须先调用super(),然后再使用this关键字,否则报错。因为子类实例的构建,是基于父类实例的加工,只有先super(),才能得到父类的this对象。

类的存值和取值

/*
在类的内部可以使用get和set关键字,对某个属性设置值和存储值,或者拦截该属性的设置或者存储值的方法
*/
class Run{
    constructor(){
        this._time = '3:40';
    }
    //设置 获取time属性值的方法
    get time(){
        return this._time;
    }
    //设置time属性的方法,参数是val是设置的值
    set time(val){
        console.log( `设置的值是${val}` );
        return this._time=val;
    }

}
let r = new Run();
console.log( r.time );//3:40
r.time = '3:20';
console.log( r.time );
类的静态方法

类可以简单理解为实例的原型,所以在类中定义的方法,都会被实例继承。
如果在一个类中的方法前添加 static 关键字,就代表该方法不会被实例继承,而是直接通过类来调用,那么这个方法就称为静态方法

实例中不能调用静态方法,只有类可以直接调用

子类 可以调用父类的静态方法 ,也可以调用父类的静态属性

static 修饰符,修饰的方法称为静态方法,修饰的属性,称为静态属性
静态属性 和静态方法一致,不能通过实例调用静态属性,只能通过类调用

class Dog {
    //设置静态属性
    static eat = '鱼';
    student = '老虎';
    //创建静态方法
    static show(){
        console.log( '柴门闻犬吠' );
    }
    run(){
        console.log( '竹杖芒鞋轻胜马' );
    }
}
let dog = new Dog();

// dog.show(); 报错
dog.run();

//直接使用类来调用静态方法
Dog.show();

//创建子类
class Cat extends Dog {

}

let cat = new Cat();
cat.run();
Cat.show();
console.log( Cat.eat );
console.log( cat.student );

类的私有属性

//ES6中的私有属性和方法,可以直接使用 # 修饰符,私有属性和方法只能在当前类中使用,不能再类的实例或者子类中使用

	// 不能在子类中使用父类的私有属性和私有方法
	class Person {
	    name='丁不三';
	    //私有属性
	    #msg='武松';
	    //设置私有方法
	    #show(){
	        console.log( this.name );
	    }
	    showMsg(){
	        console.log( '山东'+this.#msg );
	    }
	}
	let p = new Person();
	
	console.log( p.name );
	console.log( p.msg );
	
	p.showMsg();
	// p.show();
	
	// Person.#show();
	
	class Son extends Person {
	    constructor(){
	        super();
	    }
	    info(){
	        //不能在子类中使用父类的私有属性和私有方法
	        // console.log( this.#msg );
	    }
	}
	let s = new Son();
	console.log( s.msg );
	s.showMsg();

模块

如果引入的js文件体积很大,下载和执行时间会很长,因此会造成浏览器阻塞,就是用户会感到浏览器’卡死’,因为在加载js的过程中,浏览器没有任何响应,因此浏览器允许js脚本异步加载,异步加载的方式十给script标签,添加defer 或者 async 属性

使用 defer 或者 async 属性,浏览器会立即引入外部的js,并且不会等到js全部引入才执行,而是引入的同时直接执行js代码

defer 和 async 的qubie
defer:等到整个页面正常渲染结束之后才执行代码。
async:把js代码下载完以后,会终止页面的渲染,立即执行js代码,当js代码执行完毕以后,页面继续渲染
如果多个script标签具有defer属性,会按照顺序一次执行。
如果多个script标签具有defer属性,谁先加载完谁先执行,不按照顺序

代理

Prosy 代理,他可以读取目标对象,进而对目标对象中的函数调用进行拦截。不可以直接操作对象,而是使用代理模式对对象进行操作

	new Proxy(目标对象,{
    get(){
   },
   set(){
   }-});

set和get的3个参数
target:指的是目标对象
prop:当前操作的目标对象
val:设置的新值

//对对象obj设置代理
let p = new Proxy(obj,{
    //get 方法,再获取对象的某一个属性值的时候,触发的函数,此函数中可以在获取值的同时,进行拦截或者其他操作
    get(target,prop){
        return target[prop]+'葬花';
    },
    set(target,prop,val){
        if(val=='孙悟空'){
            target[prop] = val+'孙悟空不能倒拔林黛玉'
        }else{
            target[prop] = '设置成:'+val;
        }
    }
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值