0
点赞
收藏
分享

微信扫一扫

ES6技术

young_d807 2022-02-09 阅读 31


ES6技术

一.ES6基础和语法

1.JavaScript和ECMAScript的关联

JavaScript之前是LiveScript,具体的资料,大家自己查一下百度。网景公司的语言,这个公司为了把自己的公司语言,走出美国,迈向世界。把自己的语言提交给了ECMA。

JavaScript:Dom、Bom、核心ECMAScript;

ECMA: Ecma国际(Ecma International)是一家国际性会员制度的信息和电信标准组织。原名为欧洲计算机制造商协会ECMA(European Computer Manufacturers Association)

ECMAScript: ECMAScript 是标准化组织 ECMA(Ecma International - European association for standardizing information and communication systems)发布的脚本语言规范

ECMA第39号技术委员会 (TC39): 负责制定和审核ECMA-262标准,成员由业内的大公司派出的工程师组成,目前共25个人。该委员会定期开会,所有的邮件讨论和会议记录,都是公开的。

2.ES6的历史

ECMAScript历史

1996年提交给了ECMA,ECMA效率非常高,次年开始着手指定标准。

​ 1997年----发布1.0版本

​ 1998年6月----发布2.0版本

​ 1999年12月----发布3.0版本

​ 2007年10月----发布4.0版本草案,过于激动,超前。

​ 2008年7月----中止4.0版本的开发,发布3.1版本,不久后改名为ECMAScript5.0

​ 2009年12月----发布5.0

​ 2011年6月----发布5.1

​ 2013年12月----发布6.0草案

​ 2015年6月----正式通过6.0,也就是说这时候是ES6的开始。

大家在网上看到ES7、ES8、ES9,说自己要不要学这些?

ECMA:组织6月份的时候,公布了ES6.0版本,后来就指定每年6月份发布一个版本。

ES6.0 ----》2015

ES6.1 —》2016

ES 6.2 —》2017

ES6–》发布的年份,也就是2015年,类似于微软的C#,VS2019,ES2015,ES2016,ES2017,所以说呢?

ES6泛指ES6之后的版本,再往后,ESNEXT。

ECMAScript官方资料:

​​https://github.com/tc39/​​

​​https://github.com/tc39/ecma262​​

3.兼容性

​​https://www.caniuse.com/​​

查询一下ES5 ES6的浏览器的支持,WEB开发。

http://kangax.github.io/compat-table/es6/ :这个也可以

ES5浏览器的支持:

ES6技术_jsES6浏览器支持:

ES6技术_JavaScript_02ES6技术_ES2021_03

ES6的浏览器支持:

IE10版本以上

FireFox、Chrome支持较好

移动端:IOS支持较好

后面课程有关支持较好:NODEJS

问题,就是之前我们开发的程序是ES5版本的?现在是ES6版本的,客户还要用之前的版本如何办?向前兼容的问题。

ES6和ES5的转换两种方法:

1.在线转换:影响效率

2.提前编译(推荐)

4.开发工具

本教程开发工具使用的是WebStrom,和后面的课程关联起来,用的开发工具尽量一致。

第一步:设置

ES6技术_最新js_04第二步,选中JavaScript版本为ECMAScript

ES6技术_ES2021_05

5. let关键字和const关键字

ES6目标,使JavaScript语言可以编写复杂的大型应用程序、更加面向对象、效率更高、成为企业级开发语言。

JAVAScript存在的问题,本节课一讲,就会发现JS有N多问题?为什么要用ES6。

let关键字实际上就替换了var关键字,更为严谨;

5.1.变量重复问题

<script>
//1.变量重复声明问题;实际上这种使用变量的方式对不???
//我们已经学习过java,这样定义的时候。
/*
对比一下;
var a=2;
var a=4;
*/
let a=2;
let a=4;
//使用console控制台命令输出
console.log(a);
</script>

ES6技术_ES6_06也就是说,let更为严谨。

5.2.变量提升问题

ES5 提升有变量提升和函数提升。

原则:

1、所有申明都会被提升到作用域的最顶上;

2、同一个变量申明只进行一次,并且因此其他申明都会被忽略;

3、函数声明的优先级优于变量申明,且函数声明会连带定义一起被提升。

原理: 在于JS引擎的工作方式

1.先解析代码,获取所有被声明的变量;

2.运行

总体来说,分为预处理和执行两个阶段。

//先输出一个b,然后再声明一个变量,并赋值;这种在java里面会报错,这里没有错误???
//就是一个变量提升到前面了。
//2.变量提升问题
console.log(b);
var b=2;

ES6技术_js_07修改var为let之后报错:

ES6技术_最新js_08同理,js里面,function()也可以看成变量。

代码看一下:

test1();
function test1() {
console.log('执行test01...')
}
//更改一下,将一个变量来接受一下,函数function
// let关键字,就有效的防止了变量提升。

ES6技术_ES6_09

5.3 块级作用域

js作用域:

​ 全局

​ 函数

var aa=88;
function fn() {
// console.log(aa);
// var aa=99;
//除了函数提升,还有就是函数的作用域先于外部作用域。
var aa;
console.log(aa);
aa=99;
}
fn();

ES6技术_ES6_10```

//2.全局作用域

for(var i=1;i<10;i++){

}

console.log(i);

//这个时候,i值在外部还可以继续访问for循环的局部变量,这个java里面,绝对不允许的。

for(i;i<14;i++){

}

console.log(i);

//上面for循环内部变量,影响了后面for循环的变量的值,污染全局变量的问题。

块级作用域:

{}:代码块

if(条件){}

for(){代码块}

while(){代码块}

在ES6里面,我们的代码块,就是{ }包含起来的。

// if(true){

// let a=9; //a:作用域,就是{开始,到}结束。

// }

// console.log(a); //这个就访问不到,避免了外部访问内部的值;

for(let i=1;i<10;i++){

}

console.log(i);

//总结:let替换了var,作用域:块级

总结:使用let关键字替换了var,作用域是块级的,外部作用域无法获取到内部作用域,非常安全。

ES6块级作用域的使用案例:

块级作用域的案例使用 JAVA 大数据 AR 人工智能 ```

再次提下闭包:

闭包是指有权访问另外一个函数作用域中的变量的函数。

闭包作用:

1.可以在函数的外部访问到函数内部的局部变量。

2.让这些变量始终保存在内存中,不会随着函数的结束而自动销毁。

使用let关键字来处理问题:

<script>
//来获取他们的序号;
//首先是得到他们的数组;
window.onload=function () {
var ckboxs=document.getElementsByTagName("input");
for(let i=0;i<ckboxs.length;i++){
//1.使用闭包
// (function (i) {
// //2.原来的代码拷贝过来。
// })(i);
ckboxs[i].onclick=function () {
alert("let:"+i);
}
}
}
</script>

5.4 常量

// var PI=3.1415926; var PI;PI=值;
// PI=4;
//同样这种代码的使用,在强语言语言(java)也是不允许;哪里有常量一直被修改呢???
const PI=3.1415926;
// PI=4;
console.log(PI);
//1.就是const声明常量的时候,需要赋值;
//2.就是const常量赋值之后,不能再次赋值;
//在es5之前,直接使用大写字母表示常量,但是可以修改,ES6直接增加了const关键字。

6 解构赋值

什么是解构?

正统解释:按照一定模式,从数组和对象中提取值,然后对变量进行赋值。

直白理解:模式匹配,映射关系,只要等式放的两边模式一样,一一对应,左边的变量就会被赋予对应的值。直白理解,拆解数据结构。

//之前变量的赋值;
// let a1=6;
// let a2=4;
// let a3=2;
// console.log(a1,a2,a3);

//let arr=[6,4,2];
//console.log("数组:"+arr[0],arr[1],arr[2]);

// let [a1,a2,a3]=[6,4,2]; //观察,左右都是数组,个数一致;
// console.log("解构赋值:"+a1,a2,a3);

// let [a1,[a2,a3]]=[6,[4,2]];
// console.log("解构赋值"+a1,a2,a3);
let [a1,a2,a3="默认值"]=[6,4,null];
console.log(a1,a2,a3);
//问题是啥呢?一个一个赋值,太慢!!!
//1.左右结构一致,左边是变量,右边是值。左边变量个数>右边值,最后一个不显示,显示一个undefined,a3,显示是null,证明null是一个对象。
let [a,b];
[a,b]=[22,33];
console.log(a,b);

ES6技术_js_11

let {a,b}={"张三","李四"};
console.log(a,b); //右边不是东西!!!

ES6技术_JavaScript_12注意事项:

​ 1.左右结构必须一致;

​ 2.右边必须有内容;

​ 3.声明和赋值不能分开;

7.字符串和模板

7.1 扩充的方法


  • 遍历器接口,for…of循环遍历
  • includes()、startsWith()、endsWith()
  • repeat(n)
  • padStart()、padEnd()

案例1:

// let str="杩欐槸涓张晨光老师乱码格式2";
//第2个例子:for of可以识别oX0ffff之上的字符
let str=String.fromCodePoint(0x20BB7); //上土 下口

// for(let i=0;i<str.length;i++){
// console.log(str[i]);
// }
//for of循环,类似于java的迭代器遍历
for(let s of str){
console.log(s);
}
//之前的for循环会认为大于0Xffff的字符包含2个字符,所以出现乱码,而for of循环会识别大于0XFFFF的字符.

案例2:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
// let str="My View is Chrome";
// console.log(str.indexOf('Chrome')); //确定一个字符串在另外一个字符串中的第一次出现的位置.
/*
* navigator为Window对象的一个属性,指向了一个包含浏览器相关信息的对象。navigatot中包含了一些常用到的属性,如
navigator.appVersion 浏览器的版本号
navigator.appName 浏览器的名称
navigator.language 浏览器使用的语言
navigator.platform 浏览器使用的平台
navigator.userAgent 浏览器的user-agent信息
其中userAgent 属性是一个只读的字符串,声明了浏览器用于 HTTP 请求的用户代理头的值。
* */
//输出浏览器用户代理头信息里面的是否包括Chrome
// console.log(navigator.userAgent.includes('Chrome'));
console.log(navigator.userAgent);
if(navigator.userAgent.includes('Chrome'))
alert('当前浏览器是谷歌浏览器');
else if(navigator.userAgent.includes('Firefox'))
alert('当前浏览器是火狐浏览器')
else
alert('当前浏览器是其他浏览器');
</script>
</head>
<body>
</body>
</html>

案例3:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
//开头starsWith
//前端开发的时候,有http协议,也有https协议;
// let url="https://www.taobao.com/";
// if(url.startsWith("https"))
// console.log('您的网站采用的是https协议,更为安全');
// else if(url.startsWith('http'))
// console.log('您的网站采用的是http协议');
// else
// console.log('您的网站采用的是其他协议');
//结尾的判断,用途,用于前端上传图片等文件的判断;
let file='xxx.jpg';
if(file.endsWith('jpg')||file.endsWith('png'))
alert('您可以上传图片')
else
alert('您不可以上传不符合条件的文件');
</script>
</head>
<body>

</body>
</html>

案例4:

<script>
//应用场景:后端一个程序员传过来一个数字n,让我们重复当前的某个字符n次'
//有时候要写个循环,当前字符串 加了很多次.
//负数会报错
//字符串如果可以转换,也可以用;
//小数会自动取整
let str="呆瓜";
console.log(str.repeat(3));
</script>

案例5:

//padStart padEnd; pad:空格字符串补全的功能;
let str='张老师';
console.log(str.padStart(4,'O')); //padStart(数字>=字符串长度,补全的字符)
console.log(str.padEnd(5,'1'));
//第二个参数我们不要,则自动补全空格。
console.log(str.padStart(4)); //padStart(数字>=字符串长度,补全的字符)
console.log(str.padEnd(5).length);

7.2 模板字符串


  • 反引号
  • 嵌入变量写法
  • 运算操作
  • 调用函数
  • 用途

ES6增加一个新的技术,模板字符串。格式使用反引号出来的字符串,就是1前面~下面的这个符号`。

js里面,我们写一个字符串 let str=’’+变量+’

’,然后使用${变量}引用前面定义的变量,el表达式。

还可以做运算操作;

模板字符串一:

<script>
let name='张晨光';
let level=10;
// let str='教师名:'+name+',级别:'+level;
// console.log(str);
let str=`教师名:${name},级别:${level}`;
console.log(str);
//ES6,增加了占位符的字符串方式,非常牛.
//***************************可以运算,非常牛牛
let num1=11;
let num2=22;
let result=`${num1}+${num2*3}=${num1+num2*3}`;
console.log(result);
//************************可以调用函数;
function getNmae() {
return "张晨光";
}
let myname=`通过函数得到的名字:${getNmae()}`;
console.log(myname);
</script>

作用:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板字符串案例</title>
<script>
//没有数据库,整一个json数据来模拟一下
let db=[
{title:'英国脱欧',clicks:220,author:'叶晓'},
{title:'老张说IT',clicks:220,author:'张晨光'},
{title:'金融圈的哪些事儿',clicks:220,author:'郑阳'},
{title:'我的软件生涯',clicks:220,author:'马云'}
];
//加载事件;
window.onload=function () {
for(let i=0;i<db.length;i++){
//要实现动态的把数据,增加到ul里面;
//let ul=document.getElementById("news");
let ul=document.querySelector("#news");
let li=document.createElement("li"); //创建一个li节点
//li.innerHTML=' <span>'+db[i].title+'</span>\n' +
' <span>单击数:'+db[i].clicks+'11</span>\n' +
' <span>作者:'+db[i].author+'</span>';
li.innerHTML=` <span>${db[i].title}</span><span>单击数:${db[i].clicks}</span>
<span>作者:${db[i].author}</span>`;
//这个节点有了之后,增加到ul
ul.appendChild(li);
}
}
</script>
</head>
<body>
<!--news网站-->
<ul id="news">
<!-- <li>
<span>新闻信息,英国脱欧</span>
<span>单击数:11</span>
<span>作者:叶晓</span>
</li>
<li>
<span>新闻信息,英国脱欧</span>
<span>单击数:11</span>
<span>作者:叶晓</span>
</li>
<li>
<span>新闻信息,英国脱欧</span>
<span>单击数:11</span>
<span>作者:叶晓</span>
</li>-->
</ul>
</body>
</html>

二.函数和数组

2.1 函数的默认值

函数在ES5的写法

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>函数的默认值</title>
<script>
function getInfo(name,age) {
name=name||'张晨光';
age=age||18;
console.log(name,age);
}
//出现问题了,什么问题呢???
//我们实际的赋值是''空字符串,但是出来的是默认值。
getInfo('',28);
</script>
</head>
<body>

</body>
</html>

ES6改进ES6默认值好处:

1.阅读代码更清晰,知道哪个参数是可以省略;

2.有利于代码优化,将来去掉参数更方便。

2.2 rest运算符和参数

…运算符,JAVA Object…params,Object[]params,…运算符实际上就是将数组转化为逗号分隔的序列。

<script>
let arr=[2,4,6,8,10];
//let arr2=arr;
let arr2=[...arr];
//改变arr2的某一个值;
//场景:想让arr2只是arr的一个拷贝,arr2的改变,不影响原来的数组,写循环.
arr2[0]=90;
console.log("arr:"+arr);
console.log("arr2:"+arr2);
</script>

rest参数,放在函数里面

<script>
//参数 ...代表不确定的值
function sortList(...arr) {
//针对5个参数,写判断,写循环;
return arr.sort(); //sort() 只针对ASCII进行排序;
//下去再写一个函数,放sort即可。
}

//排序,看一下传递参数;5;下一次传递6;下第一次3;
console.log(sortList(2,1,8,9,4));
</script>
<script>
//函数;...参数用起来很方便;
//...运算符只能是最后一个参数
function sum(...nums) {
let sum=0; //定义一个和的变量;
for(var n of nums)
sum+=n;

return sum;
}

//求和
console.log("和",sum(2,1,3,10,20));
</script>

小结:函数名(…变量)用于获取函数的多余参数,搭配的变量是一个数组,数量不确定,只能用于最后一个参数。

2.3 箭头函数

ES6新增了=>函数。

<script>
//加载事件,做个弹出提示信息
/* window.οnlοad=function () {
alert('您已经进入本系统了!');
}*/
//改造成ES6的箭头函数,怎么写呢?
window.onload=()=>{
alert("欢迎使用箭头函数,进入张晨光老师的课程!!!");
};
//在ES6里面,=>,省略了之前的function-- ()=>
</script>
<script>
//定义一个变量,来接受一下,函数,函数有返回值;
//定义一个变量,在ES6使用let
/*let info=function (num) {
return num*4;
}*/
/*let info=(num)=>{
return num*6;
};*/
let info=num=>num*7;
//调用一下这个函数;如果有参数num,则写成(参数num)=>或num=>
//如果只有一条返回语句,则可以省略{},return。
console.log(info(6));
</script>
//调用一下这个函数;如果有参数num,则写成(参数num)=>或num=>
//有参数a,b,写(a,b)=>,a,b=>报错
//如果只有一条返回语句,则可以省略{},return。
//有多条的时候,格式=>{}
//规范性的格式:(参数1,参数n)=>{}
<script>
// let info=function (a,b) {
// console.log(a+"...");
// console.log(b+"....");
// return a+b;
// }
let info=(a,b)=>{
console.log(a+"...");
console.log(b+"....");
return a+b;
}
console.log(info(33,4));
//调用一下这个函数;如果有参数num,则写成(参数num)=>或num=>
//有参数a,b,写(a,b)=>,a,b=>报错
//如果只有一条返回语句,则可以省略{},return。
//有多条的时候,格式=>{}
//规范性的格式:(参数1,参数n)=>{}
</script>
<script>
//var id=1; //var:定义了一个全局的变量,this.id-->var这个地方的全局id;
//在json的使用;
let json={
id:2,
info:function () {
//延迟时间响应,大家想下setInterval()/setTimeout()
setTimeout(()=>{
alert(this.id);
},3000);
//切记需要注意中英文的格式,.
}
}
//调用以下;
json.info();
//注意点:1.=>函数体内的this对象指的就是定义时所在的对象,不是使用时所在的对象。
//定义的时候let json对象,使用的是script的全局的对象;
</script>
<script>
//注意事项二,arguments:参数;这个参数是js系统自带的,像this也是浏览器自动传递过去给
//调用者;可以实现js的重载功能。
// function fn() {
// console.log(arguments); //有这个参数
// }
// let fn=()=>{
// console.log(arguments);
// };
let fn=(...args)=>{
console.log(args);
};
//调用一下;
fn("zhangsan","lisi","wangwu");
//ES6箭头函数注意:不可以使用arguments对象,该对象在函数体内不存在的。如果要用,用rest参数传递;
</script>
<script>
//之前学习过构造函数,功能对类的属性进行初始化操作;
// function Person() {
// this.name="zhangchen";
// }
let Person=()=>{
this.name="zhangchenguang";
};
let p=new Person();
alert(p.name);
//注意三:不可以当作构造函数来使用,不能使用new命令,狗则会抛出错误。TypeError: Person is not a constructor
</script>

三.类

编程语言语言,都有关于类的定义和使用,java,C#,C++。使用class的关键字,js之前的版本,没有用。保留字,ES6启用了该关键字。

6.1 传统方法

通过构造函数定义,并生成对象。

//定义传统的类,js之前的写法
function Person(name,salary) {
this.name=name;
this.salary=salary;
}
//定义它的方法
Person.prototype.toString=function () {
return this.name+","+this.salary;
}
//如何来获取
let p1=new Person('张晨光',90000);
console.log(p1.toString());
//这时候,用的是function来定义一个类。

和传统面向对象语言,写法差别很大,很难受。

接下来,看看ES6是如何写的呢?

6.2 ES6类的定义:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
//使用ES6来定义类,启用了之前的保留字class
class Person{
//构造方法
constructor(name,salary){
this.name=name;
this.salary=salary;
}
//其他方法
toString(){
return `${this.name},${this.salary}`;
}
}
//使用该类
let p2=new Person('张晨光老师',100000);
console.log(p2.toString());
//这种方式,看起来就是面向对象,ES6更加面向对象;
console.log(typeof(Person)); //输出的是一个function
//证明ES6,class对应了之前的function
let result=(Person===Person.prototype.constructor);
console.log(result);
//证明类本身指向了构造方法.
</script>
</head>
<body>

</body>
</html>

6.3 静态方法

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
//class Person{}
const Person=class{
constructor(name,salary){
this.name=name;
this.salary=salary;
}
//自定义方法
showName(){
return `姓名:${this.name}`;
}
showSalary(){
return `工资:${this.salary}`;
}
//静态方法
static isFee(salary){
if(salary<5000)
return '不用交税';
}
} //类定义的结束

//调用之
let p3=new Person('张晨光',4500);
console.log(p3.showName());
console.log(p3.showSalary());

//调用类的静态方法;类名.静态方法
console.log(Person.isFee(4500));
</script>
</head>
<body>

</body>
</html>

使用静态方法的时候,语法

static 方法名(参数){}

调用的时候:类名.方法名()

6.4 继承

基本语法

子类 extends 父类,在之前ES5通过修改构造函数模式实现。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
//人的定义
class Person{
//构造方法的定义
constructor(name,salary){
this.name=name;
this.salary=salary;
}
//自定义方法
showName(){
return `姓名:${this.name}`;
}
showSalary(){
return `工资:${this.salary}`;
}
}
//定义一个子类
class YellowPerson extends Person{
//子类如果没有定义construtor,则该方法会默认添加上去,即任何子类都有constructor()
//constructor(...args){ super(...args) }
//这时候,子类需要针对父类进行加工处理
constructor(name,salary,skin){
super(name,salary);//super()使用,在子类构造方法最前面;
this.skin=skin; //
}
//子类增加一个自己的方法;
showInfo(){
//通过super.方法,来调用父类的方法
return super.showName()+","+super.showSalary()+",肤色:"+this.skin;
}
}
//调用之;
let yp=new YellowPerson('张晨光',8888,'青铜色');
//测试实例;
//console.log(yp instanceof YellowPerson); //yp是不是子类的实例
//console.log(yp instanceof Person); //yp是不是父类的实例
console.log(yp.showInfo());
</script>
</head>
<body>

</body>
</html>

总结:

1.ES6类定义的语法,使用class 类名{

//构造方法

//自定义方法

}

2.ES6 静态方法的定义和使用

3.ES6 子类继承父类的语法和使用



举报

相关推荐

0 条评论