关闭

ES6基础语法

IT985 1年前 ⋅ 268 阅读

变量

旧:var变量声明

缺点:1、可以重复声明同一个变量后面定义的会覆盖前面的变量

2、没有块级作用域,在ES5中只有函数作用域,没有普通的块级作用域

3、不能限制,对于一些常用不修改的常量无法定义,后期维护时一不小心就容易修改

新:let变量声明和const常量声明

1、禁止重复声明同一个变量

2、控制修改,通过const声明的常量无法进行二次修改

3、支持块级作用域,let在块级作用域中声明的变量,会绑定这个区域,不再受外部的影响(不会受全局变量的影响),也就是在全局let了一个num变量,在一个块级作用域中又let了一个num变量,这时候这个块级作用域只能访问到内部这个num变量,并且在这个内部变量没有声明的时候依旧访问不到这个变量,会直接报错

4、for循环的小括号中let声明的变量是在循环的父级作用域中,循环体内部的变量是一个单独的子作用域

5、let定义的变量不纯在声明提升,必须先声明变量才能获取值,在声明变量前无法访问到这个变量被称为“暂时性死区”

解构赋值

一次性可以定义多个变量,但两边需要一样,并且得是一个正经的格式,不管是json还是数组,必须是正经的格式

let {a,b,c} = {a:12,b:5,c:20};

let [a,b,c] = [12,5,20];

作用域

旧:ES5函数作用域

ES5中只有一种函数作用域,也就是在函数中的就是局部变量,函数外的都是全局变量

新:ES6块级作用域

ES6中不仅支持函数作用域,而且还新增了块级作用域,只要在满足花括号的情况内部都算块级作用域,而且块级作用域内部的局部变量外部无法访问,也不会造成全局变量的污染,而且只有ES6新增的let和const支持,var不支持块级作用域

函数

箭头函数

普通函数:function (参数){};

箭头函数:(参数)=>{};

箭头函数中如果只有一个参数,那()可以省略,如果箭头函数中只有一条return执行语句那么{}也可以省略

修复this指向

ES5中的this指向会随着不同的赋值或调用,this的指向也会不同,但是在ES6中的箭头函数修复了这一点,ES6中的箭头函数的this指向是绑定在当前的环境下,定义在全局中的指向就是window

剩余参数(arr...)

function fn (a,b,arr...){};

里面的arr...就是将传入的多余的参数收集起来,但js规定必须是放在函数形参的最后一位

数组展开(...arr)

console.log(...arr)

这就是将一个数组里面的所有参数全部打印出来

系统对象

Array

map(映射)

调用方法,操作数组,数组有几个元素就返回多少个值,map方法中需要传入一个回调函数作为参数,回调函数也有两个参数,第一个参数就是数组中的元素,第二个参数就是元素的索引值,回调函数内部对数组进行操作

arr.map(function(item,index){});

reduce (减少)

是一个多对一的方法,不管调用这个方法的数组是多长,当时候都只返回一个数据,多数用来求平均数求和,参数一是tmp,就是在求和的过程中的一个加一个的中间数,参数二就是当前的操作元素,参数三还是索引值,最终返回的是一个值

arr.reduce((tmp,item,index)=>{})

forEach (遍历)

循环遍历数组和map差不多,也是回调函数作为方法的参数,回调函数有两个参数,一个是遍历的当前元素一个是索引值

arr.forEach((item,index)=>{});

filter (过滤)

对数组进行一个筛选,也是一个回调函数作为参数,回调函数中带两个参数,一个当前元素,一个索引,通过回调函数操作完返回的是true还是false来选择保留或者移去这个元素,最终还是返回一个数组

arr.filter((item,index)=>{筛选后return true或false})

String

字符串模板

使用反单引号包裹字符串,字符串中的变量用${}包裹,变量会被自动解析

startsWith()

以什么字符串开头

endsWith()

以什么字符串结尾

JSON

标准写法

{"key":"aaa","key2":1}

键必须带引号,值如果是字符串也需要带引号,如果是数值的话就不需要了

JSON.stringify(json对象)

因为js中的json对象书写时并不是特别规范也可以使用,但是如果传输数据别的可能无法识别,所以这个方法可以将不怎么规范的json格式的json对象转换成标准的json格式的字符串,括号中的参数就是要转换的json对象。

JSON.parse(str)

将请求到的json格式的字符串转换成js可调用的json对象格式。

异步处理

异步和同步的概念

异步就是多个操作可以同时进行,互不干扰

同步就是操作哦了【-一个来进行

promise数据请求

语法:let pom = new Promise(function(resolve,reject){ajax请求,success回调函数就是请求成功,然后调用resolve,error回调函数就是请求失败了,然后调用reject});

以上是promise数据请求的基本语法,promise就是一个对数据请求的封装,以new的方式进行创建,传入一个函数作为参数,函数又会带有两个回调函数作为参数(resolve,reject),在函数内部进行ajax请求,ajax请求有两个回调函数,success和error,success是数据请求成功然后回调,参数是请求到的数据,在这个回调函数中调用传入的resolve回调函数,error就是ajax请求失败调用的回调函数,参数是一个错误对象,在error回调函数中调用传入的reject回调函数,这样promise对象就创建好了,然后使用pom.then(function(成功的数据),reject(失败对象))方法调用promise对象,将promise对象中使用的resolve和reject回到函数传入执行操作。

.then()

.then方法是promise对象的原型方法,是在数据请求完成后的操作,需要传入两个匿名函数作为参数和promise对象的resolve和reject对应,一个代表数据请求成功做出相应的操作,第二个代表数据请求错误。

Promise.all();

使用jqueryAjax请求是有返回值的,返回的就是一个promise对象,所以可以使用Promise.all(数组),这个方法的参数是一个数组,数组的元素就是一个个的JqueryAjax请求,然后在这个方法后面可以继续跟.then方法,同上面一样是两个匿名函数,只不过这次的两个匿名函数的参数不同,第一个变成了数组,数组中的元素就是一个个Ajax请求到的数据,第二个还是一个错误对象。请求到的数据顺序不会乱。虽然写的格式是同步但是异步请求的

缺点

1、在all方法中的多个数据请求是异步的,但是有不足的就是其中如果有一个数据出错请求不到,那么就会直接跳转到reject这个请求错误的匿名函数中,所有的数据都无法渲染。

2、all中的多个请求时间是等最后一个请求的完成才一块按照请求的顺序返回数据,所以时间等的是最后一个。

async/await

语法
async function XX(){
let data = await $.ajax(url:xx,dataType:xx);
let data2 = await $.ajax(url:xx,dataType:xx);
}

这是async和await配合promise异步请求数据,通过async声明的函数内部依旧可以书写普通的代码,处理依旧一样,只有在碰见await的时候才是异步处理,但是await后面必须是跟着promise对象,可以直接写jq的ajax请求,他返回的就是一个promise对象,虽然书写的是同步的代码,但是他自己会将代码格式化,转换成异步处理的代码。

ES6兼容

在IE和低版本的浏览器中是不识别ES6的代码的,可以通过babel进行编译

在线编译

通过去babel官网babeljs.io下载他的browser.min.js文件,然后将文件引入页面,将需要编译的js文件或代码的script添加type=“text/babel”属性,这样在网站是会在浏览器进行编译,消耗资源,不推荐

预编译

通过node进行线下编译,编译好在连入页面。

步骤:

1、安装node,在命令行中首先进入自己的项目的文件目录,

2、然后输入命令 npm init -y,生成一个node.js的工程文件,

3、然后输入命令安装3个babel模块

core核心模块,cli命令行工具,env预设,帮助设置一些东西

npm i @babel/core @babel/cli @babel/preset-env -D

4、在生成的nodejs工程文件中的scripts里面写入以下代码运行脚本时使用

"build":babel 源js目录 -d 编译后的js目录;

5、声明preset预设,在项目的目录下新建一个.babelrc文件这是一个固定的文件名,然后在内部写入下面的代码,意思就是编译的设置按照之前安装的这个模块走

{"presets":["@babel/preset-env"]}

6、编译js文件脚本运行,在命令行中输入npm run build

面向对象和闭包

面对象

语言的发展:机器语言 =》汇编 =》低级语言(面向过程)=》高级语言(面向对象)=》模块 =》框架 =》API接口

面向对象的特性

1、封装性

不需要关心内部是怎么获取的

2、继承性

不用每次都从0开始写,去使用前人写过验证过的代码,在这个基础上添加另外的功能

3、多态性

在js中体现的不太明显

ES5面向对象

function person(name,age){
this.name = name;
this.age = age;
}
preson.prototype.show = function (){
alert(this.name);
}
var per = new person("name",age);
per.show();

以上就是ES5中的面向对象,没有明确的声明这个类,而是使用一个构造函数作为类来使用,并且这个对象的方法需要使用prototype原型在外面来定义,而不是在内部写,且在使用的时候在用new出来这个对象。

继承
第一种:
function worker(name,age,job){
person.call(this,name,age);
this.job = job;
}
worker.prototype = new person();
worker.prototype.constructor = worker;
var w = new worker(name,age,job);

这是通过调用call方法改变this指向来实现的继承,但是会导致函数中的constructor构造器的混乱,所以需要将构造器的指向再指向一次。

第二种:
在创建完第一个构造函数后,使用window.属性 = 构造函数名;将构造函数赋值给window,这样在其他的构造函数中可以直接用this.属性 = 函数名();来进行继承,但是这样只能继承定义在prototype中的属性和方法,在构造函数内部定义的无法继承。

ES6面向对象

class person{
constructor(name,age){
this.name = name;
this.age = age;
}
show(){
alert(this.name);
}
}
let per = new person(name,age);
per.show();

ES6中修复了原来的没有明确声明类的概念,直接用class声明类,constructor就是构造器,直接明确分类出来,将属性放在构造器内,方法放在类的内部就好,创建对象和调用方法和之前一样,都是直接new和调用,但是比之前的直接用函数来代替要清晰很多。

继承
class worker extends person{
constructor(name,age,job){
super(name,age);
this.job = job;
}
showjob(){
alert(this.job);
}
}
let w = new worker(name,age,job);
w.show();
w.showjob();

ES6中的继承是直接通过extends要继承的类。然后还是自己的构造器,只需要使用super将继承的类需要使用的值传进去,然后自己定义自己的属性,在extends的时候就直接继承了这个类的方法,所以不需要做多余的操作,直接定义自己的方法,和使用就行了。

总结

ES6中添加的几个关键字

class 声明类

constructor 声明构造器

extends 继承

super 父类

ES6模块化

JS模块系统

没有模块 > CMD公共模块声明(同步) > AMD模块异步加载 > ES6语言提供的模块化支持

目前ES6的模块化浏览器还不支持,但是可以通过webpack进行编译

使用

每一个js文件就是一个模块,模块内部向外提供东西

步骤:
1、先将一个个js文件写好,作为模块需要将要提供的变量或者方法通过export去输出出来
2、然后在要引用其他模块的js文件写入
import * as 模块名 from '文件路径';
3、使用模块的变量或方法是 模块名.XXX
export写法
export let a = XX;      //导出变量
export const a = XX; //导出常量
export {xxx,xxx,xxx}; //导出对象格式
export function xxx(){}; //导出函数
export class xxx{}; //导出类
export default 'xxx'; //导出默认的成员就是一个成员存在
export * form '另一个模块'; //将另一个模块导入进来然后在导出
export {xx,x,xx} form '另一个模块';
export {default} form '另一个模块';
import写法
import * as 模块名 from "./文件路径";          //导出的数据全部引入
import {xxx,xxx,xxx,...}from "./文件路径"; //挑着引入需要的数据
import xxx from "./文件路径" //引入默认的成员default,顺便取了个名字
import "1.jpg"; //只引入文件不使用
import "1.css";
import ("./文件路径").then(请求成功匿名函数,请求失败匿名函数)

最后的import请求是一个函数,是异步请求,用来请求页面不怎么重要的文件,而且返回值是一个promise对象,所以使用then进行回调


全部评论: 0

    我有话说: