模板字符串

1.模板字符串: 只要拼接字符串 都用模板字符串代替+a.整个字符串包裹在一对儿反引号 ` ` 中b.反引号``中支持换行 c.反引号中需要动态生成的内容必须放在${}里d. ${}里: 1). 可以放一切有返回值的合法的变量或js表达式。2). 不能放程序结构(分支和循环)以及没有返回值的js表达式//示例:var price=12.5;var count=5;console.log(`单价:${price.toFixed(2)}, 数量:${count},总计:${(price*count).toFixed(2)}`);

let

旧JS中:var 声明的变量会被声明提前破坏了程序执行顺序,没有块级作用域,导致代码块{}内变量,会影响{}外的程序
说明:代码块 除了函数和对象以为的{},都称为代码块,旧JS中拦不住内部变量影响外部程序
//例子:var t=0;//用于累加每个函数执行耗费的总时间function fn1(){console.log(`执行fn1,耗时0.3s`)t+=0.3}function fn2(){//var t; //if里的var t被提前到这里 //因为fn2中已经有了局部变量t,所以fun2中所有对t的操作,从此与全局t再无关系!console.log(`执行fun2,耗时0.8s`)t+=0.8; //不再加到全局t,而是加到局部t//函数调用后局部变量t释放,所以原本正常的程序,少了0.8s。if(false){var t=new Date();console.log(`当前时间:${t.toLocaleString()}`)}}fn1()fn2()console.log(`共耗时${t}s`)
解决:let代替var声明变量
优点: (1). 用let声明的变量不会被声明提前(2). let让代码块也变成一级作用域——保证块内的变量不会超出块的范围,影响块外的代码。
原理: 其实let会自动添加匿名函数自调,让let的变量变成局部变量
let的特点:(1)相同代码块中只有let的变量受控不会超出块的范围。其它如果有var声明的变量,照样超出块的范围,影响外部(2). 即使在全局let的变量,也不会保存在window中(3). 在相同范围内,不能重复声明一个变量(4). 禁止在let之前提前使用该变量
//示例:var a=10;let b=10;console.log(window.a) //10console.log(window.b) //undefinedconsole.log(b) //10//匿名函数自调(function(){var b=10;console.log(b);//10})()

箭头函数

使用:(1)去掉function ,在()和{}之间加=>(2)如果()只有一个形参变量,可省略()(3)如果{}函数体中只有一句话,可以省略{},如果仅剩这句话还是return 必须去掉return
箭头函数特征:
(1)我们需要回调函数内的this与回调函数外部的this保持一致!但是,几乎所有回调函数中的this都默认值window。var james={   //new Object()不是一个作用域sname:"JAMES",friend:["davis","kuzma","Schroder"," Harrell"],intr:function(){  //intr的函数作用域this.friend.forEach(function(elem){  //回调函数的函数作用域  //this指向lilei.friendconsole.log(`${this.sname}传球给${elem}`)           //this指向window})}}james.intr() //结果undefined 传球给xxx
解决: 只要将回调函数改为箭头函数,就能轻松让回调函数中的this->回调函数外的this
原理: 箭头函数有一个特征: 箭头函数内的this可与外部的this保持一致 仅限于this 至于箭头函数内的其它局部变量,依然只能在箭头函数内部使用(2)所有function都能改成箭头函数吗?不希望内外this保持一致时,就不应该用箭头函数简化 :比如: 对象中的方法,就不应该用箭头函数简化var james={sname:"JAMES",friend:["davis","kuzma","Schroder"," Harrell"],intr:()=>{this.friend.forEach((elem)=>{  //this指向window,undefined.forEach()报错console.log(`${this.sname}传球给${elem}`)})}}james.intr()解决:ES6为了去掉对象中方法的function,提供了一个专门的简写:var james={  intr(){...} }好处:intr()简写不改变this指向
箭头函数与普通函数的差别: (1). 箭头函数中的this与外部的this保持一致。但是普通函数的this与外部的this是无关的(2). 箭头函数不能作为构造函数(3). 箭头函数中不允许使用arguments()

for of

 问题: (1). for循环既可以遍历索引数组,又可以遍历类数组对象,但是不够简化(2). forEach虽然可以简化,但是只能用于遍历索引数组,无法遍历类数组对象。解决:(1)ES6提供了一个for of 循环,统一了for和forEach的优缺点何时:(1)只要遍历数字下标的索引数组和类数组对象,都可以用for of来代替for或者forEach如何:for(var 变量 of 索引数组或类数组对象){//of会依次取出每个元素的值//将当前元素值保存在of前的变量中}for of的局限: (1). 遍历过程中,只能获得元素值,无法获得下标位置(2). 只能从头到尾顺序遍历,无法调整遍历的顺序。(3). 无法调整遍历的步调

参数增强

调用函数时,即使没有传入实参值,形参变量也能有一个默认值使用;
希望即使没有传入实参值,形参变量也能有一个默认值使用时;
如何使用:function 函数名(形参, ..., 形参=默认值){//调用时,带有=默认值的形参,即使没有传入实参值,也有默认值可用//如果调用时用户传入了自定义的实参值,则形参使用传入的自定义实参值——默认值就成了备用!}
//示例:function intrSelf(str="主人很懒,什么也没有写"){console.log(`自我介绍:${str}`)}intrSelf("you can you up");intrSelf();问题: 单靠默认值无法解决多个形参不确定有没有值的情况
//示例:function order(zhushi="奥尔良烤腿堡",xiaochi="土豆泥",yinliao="咖啡"){console.log(`您本次点的餐是: 主食:${zhushi},小吃:${xiaochi},饮料:${yinliao}`)}//第一个每个点 order("香辣鸡腿堡","薯条","可乐");//第二个就点默认套餐order();//第三个只想换套餐里的饮料// order("雪碧");//错误// order(,,"雪碧");//错误// order("","","雪碧");//错误

剩余参数

ES6中,箭头函数中无法使用arguments对象.那么,如果遇到参数个数不确定的情况.
今后只要在ES6中,遇到不确定实参值个数的情况时,我们都要用剩余参数的语法来代替arguments
如何:function 函数名(...数组名){//...表示收集的意思,在函数被调用时,收集所有传入函数的实参值,保存到一个数组中。//数组名就是...后的数组名}
//例子:var add=(...arr)=>{console.log(`arr:${arr}`);var sum=0;for(var n of arr){sum+=n}return sum;}console.log(add(1,2,3));//6console.log(add(1,2,3,4,5));//15优点:a. ...剩余参数语法支持ES6的箭头函数b. ...剩余参数语法获得的是一个纯正的数组,可随意使用数组家的函数c. ...剩余参数语法还可和其它形参配合使用,只获得剩余的参数。不必获得所有实参值。
//示例:function jisuan(ename, ...arr){console.log(`ename:${ename}`);console.log(`arr:${arr}`);console.log(`${ename}的总工资是:${arr.reduce((box,elem)=>box+elem,0)}`)}jisuan("Li Lei",10000,1000,2000);jisuan("Han Meimei",3000,4000,5000,1000,2000);

打散数组

问题: 函数需要多个实参值,但是多个实参值却是放在数组中给的,出现了不一致
解决: a. 不好的解决: applyapply的本职工作是先替换this,再打散数组 如果一个需求与this无关,仅希望打散数组时,使用apply()时,第一个实参值对象写什么就很尴尬 不能不写!但是随便也就行!b. 好的解决: ES6的打散数组操作
如何:调用函数时: 函数名(...数组)
总结:...定义时收集,调用时打散
//示例:console.log(Math.max(2,7,5,1));var arr=[2,7,5,1];console.log(Math.max(arr));// NaN 不支持console.log(Math.max.apply(Math, arr)//不好Math.max(...arr)   //打散)

...常用语法

a.克隆一个对象: var obj2={...obj1} //打散旧对象中每个属性,放入新对象中
b.克隆一个数组: var arr2=[...arr2]//打散旧数组为多个元素值,再放入新数组
c.合并两个数组: var arr3=[...arr1,...arr2];  //先将旧数组arr1和arr2分别打散为多个元素值 //然后再讲所以元素值放入新数组中
d.合并两个对象: var obj3={ ... obj1, ...obj2 } //先将旧对象打散为多个属性,然后将多个属性值放入新对象中保存
//示例:
var lilei={sname:"Li Lei",sage:11}var lilei2={...lilei};console.log(lilei2);console.log(lilei==lilei2);//falsevar arr=[1,2,3];var arr2=[...arr];console.log(arr2);console.log(arr==arr2);//falsevar arr1=[1,2,3];var arr2=[5,6,7];var arr3=[...arr1,4,...arr2,8];console.log(arr3);var obj1={a:0,x:1,y:2};var obj2={a:4,m:5,n:6};var obj3={...obj1,z:3,...obj2,o:7}console.log(obj3);

解构

数组解构:从一个巨大的数组中提取出个别成员单独使用;
如何: [变量1, 变量2, ...]=数组;
原理: a. 先将=左边装扮为一个数组的样子。其中,每个元素位置上都放一个准备接受实际数组元素值的变量b. 执行时: =右边的数组会将对应位置的元素值,自动赋值给=左边对应位置的变量中!
结果: 变量1=数组[0];变量2=数组[1];
示例: 从数组中只解构出月和日var arr=[2020,9,4,15,43,37];//        0   1 2  3  4  5//只想用年、月、日// var [y,m,d]=arr;// //   0 1 2// console.log(y,m,d);//只想用月、日var [ ,m,d]=arr;//   0 1 2console.log(m,d);//9,4
对象解构:从一个巨大的对象中仅提权出个别想要的成员单独使用
如何: {属性名1: 变量1, 属性名2:变量名2 , ... }=对象   //   配对儿 : 接属性值
原理: a. 先将=左边装扮成一个对象的结构。但是=左边写的属性名必须在=右边的对象中有包含才行b. 执行时,=右边的对象,会将相同属性名的属性值赋值给=左边相同属性名的变量
结果: 变量1=对象.属性名1变量2=对象.属性名2
问题: 原对象中的属性名或方法名起的已经很好了 我们其实是没必要改名的
解决: 通常我们从原对象中解构出属性和方法时,都不会轻易修改原属性名和方法名
问题: 被迫要把属性名和变量名,相同的名字写两遍
解决: 其实,ES6中,如果一个属性名和:后的变量名相同 则只需要写一个即可
var { 属性名1, 属性名2, ... }  = 对象一个名字两用既配对又变量名
示例: 使用对象解构从对象中提取出个别属性和方法使用
var user={uname:"dingding",sex:1,email:"dingding@163.cn",login(){console.log(`登录...`)},logout(){console.log(`注销...`)},changePwd(){console.log(`修改密码...`)}}//只想用用户名和注销//      配对  变量名   配对   变量名// var {uname:uname, logout:logout}=user;var { uname, logout } = user;//    配对//    变量console.log(`用户名:${uname}`);logout();
参数解构:
问题: 多个实参值不确定有没有,而且还要求每个实参值与形参对应!
解决: 参数解构
什么是: 以对象解构方式来接收和传递函数的实参值
如何: a. 定义函数:    要把所有形参变量都装扮在一个对象结构中function 函数名({//   配对儿   接值属性名1: 形参1=默认值, 属性名2: 形参2=默认值,... : ...}){}b. 调用函数时,所有实参值必须放在一个对象结构中整体传给函数作为参数函数名({//   配对儿属性名1:实参值1,属性名2:实参值2,... : ...})(5). 结果: 在函数内部a. 形参1 接住了实参值1b. 形参2 接住了实参值2(6). 问题: 多数情况下属性名和形参变量名都是一样的!就要写2遍(7). 解决: 其实,在定义函数时,形参对象结构中,可以只写一个属性名: 但是,一个属性名2用: 既配对,又接收实参值(8). 示例: 定义一个订餐函数,可接收任意个实参值//示例:function order({zhushi="奥尔良烤腿堡",xiaochi="土豆泥",yinliao="咖啡"}){console.log(`您本次点的餐是: 主食:${zhushi},小吃:${xiaochi},饮料:${yinliao}`)}//第一个挨个点: order({zhushi:"香辣鸡腿堡",xiaochi:"薯条",yinliao:"可乐"});//第二个默认:order({})//第三个只要换饮料order({yinliao:"雪碧"})//第四个想换饮料和小吃order({yinliao:"豆浆",xiaochi:"菠萝派"})

class

问题: (1). 箭头函数不能用作构造函数,不能用new来调用(2). 旧js中,明明构造函数和原型对象同属一家人,但是却分开写
解决:class
什么是: 专门集中保存一个类型的构造函数和所有原型对象方法的程序结构
如何: (1). 用class{}包裹以前的构造函数和原型对象方法(2). 构造函数名提升为class名,所有构造函数更名为constructor——构造函数内容保持不变(3). 所有直接包含在class内的方法,默认就保存在原型对象中。不用加"类型名.prototype"前缀 而且"=function"也可省略
本质:底层依然是构造函数、原型对象、继承机制。只不过表面的格式换了
//示例:class student{   //class包裹构造函数和原型对象// 构造函数constructor(sname,sage){  //构造函数名字提升到class名字,所有构造函数改为constructorthis.sname=sname;this.sage=sage;}// 原型对象intr(){  //包含在class内的方法,默认保存在原型对象中console.log(`I'm${this.sname},${this.sage}`)}}var lilei=new student("lilei",11);lilei.intr()问题:多个class之间,拥有部分相同的属性结构和方法定义,但是,我们又不能把相同的属性结构和方法定义写2遍
解决: 两种class间的继承
如何:两种class间的继承: 2大步: (1). 额外创建一个公共的父类型class,集中保存两个子类型class相同部分的属性结构和功能。子类型中就不再需要重复保存这些属性和方法了!问题: 现在的子类型是残缺不全的!(2). 让子类型class继承公共的父类型class: 2步:a. 使用extends让子类型class继承父类型classclass 子类型 extends 父类型{... }说明: extends有点儿像setPrototypeOf()问题: 虽然子类型的子对象可以使用爷爷类型的方法,但是,因为子类型的构造函数缺少必要的语句,所以,子类型的    子对象内部依然缺少属性b. 在子类型构造函数中借用父类型的构造函数来帮子类型为孩子添加必要的属性。 class 子类型 extends 父类型{constructor(){super(实参值,...) //super是extends附赠的关键词,//专门指代父类型的构造函数//所以,调用super就相当于调用父类型构造函数了... ...}}
//示例:class Flyer{   //公共的父类型class ,集中保存两个子类型class向同功能constructor(x,y){this.x=x;this.y=y;}fly(){console.log(`飞到x:${this.x}, y:${this.y}位置`)}}//           继承class Plane extends Flyer{   //extends 让子类型class继承父类型classconstructor(x,y,score){//借用父类型构造函数帮忙给子对象添加必要属性super(x,y);this.score=score;}getScore(){console.log(`击落一架敌机,得${this.score}分`)}}var p=new Plane(10,50,5);p.fly();p.getScore();console.log(p);

promise 异步任务的顺序执行

1.问题:多个异步任务,如何保证必须顺序执行
2.错误:单纯调用三个异步任务函数
3.原因: 异步任务都是在主程序之外执行,主程序中其它代码不会等待异步任务执行完才开始的。而是只要异步任务一开始,后续代码也会立刻执行 与异步任务同时执行
4.旧的解决:回调函数来解决(1). 为前一项异步任务添加一个回调函数参数。用于提前保存下一项要执行的任务。(2). 在前一项异步任务内,最后一句执行的语句之后,自动调用回调函数参数。(3). 调用时,在调用前一项任务时,就通过回调函数的方式,将下一项任务包在一个匿名函数中,提前传给前一项任务的回调函数参数。(4). 结果: a. 当前一项任务执行时,后一项任务仅仅暂时保存在回调函数参数中,暂不执行!b. 只有当前一项任务最后一句话执行完,自动调用回调函数参数时,才会执行回调函数参数提前保存的下一项任务。
5. 问题: 回调地狱: 由于反复使用回调函数的语法,形成的深层的嵌套代码结构//示例:回调函数解决异步任务顺序执行(不好)function james(callback){console.log(`james 起跑..`);setTimeout(()=>{console.log(`james到达终点`)callback()},3000)};function davis(callback){console.log(`davis起跑..`);setTimeout(()=>{console.log(`davis到达终点`)callback()},2000)};function kuzma(callback){console.log(`kuzna起跑..`);setTimeout(()=>{console.log(`kuzna到达终点`);callback()},4000)}//如果想异步函数顺序执行,旧的方法给每个函数加上回调函数,但是这种写法会形成回调地狱james(function(){davis(function(){kuzma()})})
用promise解决异步函数的顺序执行问题:
1.专门保证多个异步任务顺序执行,且不会产生回调地狱问题的新技术
2.何时: 今后只要多个异步任务必须顺序执行时,都首选promise
3.如何:1.将每个异步任务用new Promise包裹,变成一个格子间function 前一项任务(){return new Promise(){function(door){//原来的异步函数代码//异步函数代码结束后:door()}}} 2.调用时:前一项任务().then(后一项任务)
4.原理:1). 当调用前一项任务时:i. 创建一个new Promise格子间对象ii. 自动开始执行new Promise中的异步任务代码iii. 前一项任务将创建好的new Promise格子间对象返回到函数外2). 因为前一项任务返回的是一个new Promise格子间对象,所以可以用.then()继续连接下一项任务。i. .then()中下一项任务一定不要加()。因为()是立刻调用的意思,但是我们不希望下一项任务立刻调用。ii. 当前一项任务内执行完之后,自动调用开门的函数door()时,程序会自动执行.then()中的下一项任务
//示例:function james(){  //前一项任务return new Promise(function(door){   //原来异步任务的代码console.log(`james起跑..`);setTimeout(()=>{console.log('james到达终点..')door()  //原异步任务结束后,传递给下一个要执行的异步任务},2000)})}function davis(){console.log(`davis起跑..`);setTimeout(()=>{console.log('davis到达终点..')door()  //原异步任务结束后,传递给下一个要执行的异步任务},4000)}james().then(davis)
前一项任务可以向下一项任务传递参数: 2步
(1). 前一项任务在使用door()开门时,可以传入一个实参值door(实参值)
(2). 放在then中的下一项任务,必须提前准备好一个形参变量,准备接上一个任务开门时传下来的实参值
//示例:function james(baton){  //前一项任务return new Promise(function(door){   //原来异步任务的代码var baton="接力棒"  //要传递的参数console.log(`james拿着${baton}起跑..`);setTimeout(()=>{console.log('james到达终点..')door(baton)  //原异步任务结束后,传递给下一个要执行的异步任务},4000)})}function davis(baton){  //接入要传递的参数return new Promise(function(door){console.log(`davis拿着${baton}起跑..`);setTimeout(()=>{console.log('davis到达终点..')door(baton)  },2000)})}function kuzma(baton){return new Promise(function(door){console.log(`kuzma拿着${baton}起跑..`);setTimeout(()=>{console.log('kuzmas到达终点..')door()  },1000)})}james().then(davis).then(kuzma)</script>

高级JavaScript #ES6(模板字符串,let,箭头函数,forof,参数增强,解构,class,promise)相关推荐

  1. ES6(ECMASript 相关介绍,ECMASript 6 新特性---let,const关键字,变量的解析赋值,模板字符串,箭头函数,rest参数,spread扩展运算符,Symbol)

    文章目录 1 ECMASript 相关介绍 1.1 es介绍 1.2 为什么要学习 ES6 1.3 ES6 兼容性 2 ECMASript 6 新特性 2.1.let 关键字 2.2. const 关 ...

  2. ES6 语法 之 let、const、模板字符串、箭头函数

    ES6 语法 ES6 语法 简介 let 关键字 模板字符串 const 关键字 js中const,var,let区别 箭头函数 ES6 语法 简介 ES6, 全称 ECMAScript 6.0 ,是 ...

  3. ES6 | let 关键字 + const关键字 + 箭头函数 + rest参数 + 扩展运算符 ... + Symbol + 迭代器 + 生成器 + 变量的解构赋值 + 模板字符串

    目录 ECMASript 相关介绍 ECMASript 6 新特性 let 关键字 const关键字 变量的解构赋值 模板字符串 简化对象写法 箭头函数 => 参数默认值 rest参数 扩展运算 ...

  4. javascript模板字符串(标签函数)

    前面介绍了javascript的模板字符串的基本知识,今天深入学习一下标签函数 模板字符串概述 这里先简单说一下模板字符串的概念 1.模板字符串,从名字上可以得出其实返回的是字符串,普通使用其实就想引 ...

  5. ES6模板字符串【${}配合反单引号一起用】

    转自: https://www.cnblogs.com/shihuc/p/10238511.html 先看看JavaScript中两个字符串的效果,就很容易知道模板字符串是个啥东西,其实一点也不新鲜. ...

  6. ES6之什么是箭头函数?

    箭头函数是匿名函数,ES5匿名函数的语法糖:但又增加了ES5所没有的一些优点,接下来我们一起来看一看箭头: //ES5 var tt = function tt() {return 55 + 99; ...

  7. ES6学习笔记:箭头函数

    lambda函数即匿名函数,在ES6发布之前,我们通常会这样写匿名函数 var selected = allJobs.filter(function (job) {return job.isSelec ...

  8. js es6 模板字符串和使用

    模板字符串描述: 模板字符串使用反引号 (``) 来代替普通字符串中的用双引号和单引号.模板字符串可以包含特定语法(${expression})的占位符.占位符中的表达式和周围的文本会一起传递给一个默 ...

  9. 石川es6课程---4、箭头函数

    石川es6课程---4.箭头函数 一.总结 一句话总结: 相当于函数的简写,类似python lambda 函数,先了解即可 let show1 = function () {console.log( ...

最新文章

  1. GitLab 8.15中引入了自动部署和Web终端
  2. GO语言struct语法
  3. k8s:Service的四种类型和三种代理模式
  4. 阿里云分析型数据库AnalyticDB:使用Logstash插件进行高效数据写入
  5. 一个SAP开发人员的2018年终总结
  6. Windows Embedded CE 6.0开发初体验(五)构建CE平台
  7. oracle 返回表的函数,oracle 返回表函数
  8. oracle display set,Check if the DISPLAY variable is set
  9. 未能加载文件或程序集“Newtonsoft.Json”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)...
  10. atom对比 vscode_Atom、Sublime Text、VSCode 三者比较
  11. 贝莱德文化:领导者必须培养领导者
  12. 离散数学第二版计算机系,《离散数学(第2版)(计算机系列教材)》
  13. 优启通制作系统u盘_优启通 v3.6.2020.0620 VIP版/免费版-好用的U盘启动盘制作工具...
  14. wagtail 实现中英文
  15. android(6.0,11.0)开启wifi热点
  16. 运维工程师社招、校招面试经验汇总
  17. linux unlink函数作用,unlink函数的作用
  18. Psoc Creator入门——EZI2C 通信
  19. Exchange 2013/2016/2019修改附件大小限制
  20. PCL:投影滤波(二)将点云投影至球面

热门文章

  1. (c语言 )输入10个学生5门课的成绩,分别用函数求:每个学生平均分;每门课的平均分;
  2. My Twentieth Page - 用栈实现队列 - By Nicolas
  3. >>数据管理:DAMA简介「考试和续期」
  4. MATLAB实现图像的放大和缩放
  5. 多版本Gradle离线包下载
  6. QT教程:QSortFilterProxyModel代理实现自定义排序、联合过滤
  7. 使用firework进行简单的切图操作
  8. debug idea js,IDEA调试javaScript
  9. 身边现实:帮你揭开几个程序员的真相
  10. asp.net一些面试题(转)