2.22
严格模式
‘use strict’;
严格模式与混杂模式的区别:
- 严格模式必须使变量声明符声明变量
- 严格模式不能使用delete删除变量
- 严格模式中八进制使用0o开头
- 严格模式中this不能指向window
- eval函数有自己独立的作用域
ES5-JSON
JSON的主要作用是传输数据 做数据交互 或者使用JSON做配置文件使用
JSON独立于语言和平台(操作系统) 任何语言和平台都支持JSON的序列化和反序列化
序列化:对象->JSON json.stringify
反序列化:JSON->对象 json.parse
let与const
一、ES6简介
ES6是ECMAScript6的简写
2015年发布ECMA2015,又称ES6。将2015年及以后每年发布的ES,都称为新一代ES,简称ES6。
- ES与js的关系?
ES是JS的规格,js是ES的实现 - ES5与ES6的关系?
ES6是下一代的JavaScript,新一代的JavaScript
ES6相比于ES5的语法更加的简介,严谨
ES6相比于ES5,它并没有修改ES5的语法(全方位兼容ES5),新增知识
新增:
let,const
字符串模板
数组扩展
对象扩展
解构赋值,模式匹配
class/继承
promise
iterator和generator
async,await
模块化(import/export) - ES6的兼容性问题
由于ES6是一个较新的技术,并不是所有的内容都会被浏览器支持(尤其是最新的内容,ES2019、ES2020…),到时候会使用一些工具,将ES6代码重新编译为ES5的代码,再执行。
二、let
能够定义变量的关键字:var function let const class
在ES5中,使用功能var定义变量
在ES6中新增了let关键字来定义变量
let和var的区别
1. let定义的变量没有变量提升,var有
2. let定义的变量属于块级作用域,var定义的变量属于函数作用域(ES5的作用域包括全局和局部,ES6新增块级)
3. let定义的变量不允许被重复定义
4. let定义的变量会出现暂时性死区的情况
5. let定义的变量不会被绑定到顶级对象window中
// 暂时性死区
let username = "admin";
if (true){
console.log(username); //直接报错 不做变量提升
let username = "root";
}
使用let解决for循环问题
//正确添加了点击事件,点击不同li显示对应数值
for (let i = 0; i < lis.length; i++) {
lis[i].onclick = function () {
alert(i);
};
}
使用let解决for循环问题–拆分
//在for循环内部存在一个父子作用域
//系统在每次for循环执行的时候,都会定义一个变量,来保存上一次i的值,把这个进行加1之后,赋值给下一次循环
//第一步:
{
let i = 0;
{
lis[i].onclick = function () {
alert(i);//0
};
}
}
//第二步:
{
let i = 1;
{
lis[i].onclick = function () {
alert(i);
}
}
}
// 第三步:
{
let i = 2;
{
lis[i].onclick = function () {
alert(i);//2
};
}
}
//..
特点:
- 在for循环圆括号内声明的变量,是for语句块作用域的父作用域
- JS引擎内部会记录for循环上一轮的值,每一轮循环 i 都是新的变量,初始化给下一轮循环
三、const
在ES6中新增了const来定义常量(一旦定义,就不能被修改)
- 1.let拥有的特点,const都有
- 2.const定义的变量不能被修改
- 3.const定义的常量,定义同时需要被初始化
常量一般使用大写
解构赋值
在ES6中,允许通过一定的模式,将对象和数组中的内容提取出来,赋值给变量,这个过程称为解构赋值。
一、解构赋值的概念
回顾一下ES5中是如何提取数组的数据
ES6中的解构赋值,核心:模式匹配
- 解构赋值,需要有一个=(赋值符号)
- 解构赋值的=两变的模式是一致(都是对象,或都是数组)
- =的右边是要被解构的值,左边是变量
结构的分类:完全解构、不完全解构(解构的缺省)、解构失败、解构的默认值
二、数组的解构赋值
数组结构的特点:1.数据有序 2. 数组中的元素有索引 3. 数组是一个集合类型
数组的解构:
- 数组的完全解构
let arr=[10,20,30];
//1.完全解构 要解构的数组数据与变量一一对应
let [a, b, c] = arr;
console.log(a, b, c);
- 不完全解构 要解构的数据数量多于变量的个数
//2.不完全解构 let [a,b]=arr;
console.log(a,b);
//不完全解构缺省
let [a, , b] = arr;
console.log(a, b);//a=100 b=5
- 解构失败
//3.解构失败 要解构的数据个数少于变量的个数
let [a,b,c,d]=arr;
console.log(a,b,c,d);//d =undefined
- 解构赋值的默认值(在解构过程中,允许给变量添加默认值)
let [a, b, c = 0, d = 0] = [10, 20, 300];
console.log(d);//默认值为0
console.log(c);//300
默认值生效的前提是:判断变量的值是否严格等于(===)undefined,只有满足时,才去默认值。
//默认值的特殊情况
let [a = 0, b = 0, c = 0] = [undefined, null, undefined];
console.log(a, b, c);// a=0 b=null c=0
// console.log(null==undefined);//true
// console.log(null===undefined);//false
//默认值:判断变量的值是否真等于undefined
三、对象的解构赋值
对象的特点:1.对象是无序的 2.对象是一种hash结构 ,是依靠key去取值的。
对象的解构中,就是使用key来进行匹配
模式:{}
- 完全解构
let obj={
name:'赵帅鸽',
age:21,
addr:'海淀区'
};
//es6 {}模式匹配
//注意:在解构中,name,age,address不是变量
//a,b,c是变量
//1.完全解构
let { name: a, age: b, address: c } = obj;
console.log(a, b, c);
console.log(age);//error age不是变量 a才是变量
- 不完全解构
//2.不完全解构
let {name:a,age:b}=obj;
console.log(a,b);
3)解构失败
let { name: a, no: b } = obj;
console.log(a);
console.log(b);//undefined
4)解构默认值
//4.解构默认值
let { name: a, no: b = '00000' } = obj;
console.log(a);
console.log(b);//默认值
特殊情况:若要解构的对象key与变量名一致,则可以简写
//简写情况
// let { name: name, age: age } = { name: 'lucy', age: 100 };
//可以简写为如下:
let { name, age } = { name: 'lucy', age: 100 };
console.log(name, age);
注意:在简写中,name和age充当了两个角色,第一是:key,第二是:变量名
四、其他类型的解构
- 字符串的解构
let str = 'hello';
let [a] = str;
console.log(a);//h
let { length } = str;//str.length
console.log(length);
- 数值的解构
let a=10;//包装对象 Number
// let b=a.toString();
// console.log(b);//'10'
let {toString}=a;
console.log(toString);
五、解构的使用场景
- 用于数据交换
let a = 5;
let b = 3;
//在不使用第三个变量的前提下,完成a,b的数据交换
// a = a + b;//8
// b = a - b;//5
// a = a - b;//3
// console.log(a, b);
[b, a] = [a, b];
console.log(a, b);
- 解构服务端数据
//解析后台数据
let obj = {
code: 200,
msg: '登陆成功',
data: {
name: 'lucy',
no: '10001'
}
};
//取出
let { code, data } = obj;
console.log(code, data);
let { name, no } = data;//{name: "lucy", no: "10001"}
console.log(name, no);
//取出code和name
let { code, data: { name } } = obj;
console.log(code, name);
- 解构函数的参数
function getSum([a = 0, b = 0, c = 0]) {
let sum = a + b + c;
console.log(sum);
}
// getSum([10, 20, 30]);
// getSum([10, 20]);
// getSum();//报错
getSum([]);
getSum([5]);
当函数的形参较多时,推荐将函数参数封装为对象来进行传递,可以解决参数的顺序问题。再搭配上解构默认值,又可以解决参数的默认值问题
ES6扩展
一、字符串扩展
- 模板字符串,允许通过使用反引号来定义字符串
模板字符串的特性- 支持换行
- 内部支持js表达式,在${}中,可以支持js表达式
//使用es6编辑页面
//将后台数据展示到页面的ul中
var oUl = document.querySelector('ul');
let { data } = obj;//解构
data.forEach(function (item) {
// console.log(item);
oUl.innerHTML += `
<li>
<span class="bookname">${item.name}</span>
<span class="author">${item.autor}</span>
</li>
`;
});
- 新增了一些方法
includes() 判断字符串中是否包含字符 true/false
startsWith() 判断字符串是否以指定字符串开头 true/false
endsWith() 判断字符串是否以指定字符结尾 true/false
padStart() 在头部补全字符串到指定长度
padEnd() 在尾部补全字符串到指定的长度
let num='1';
num=num.padStart(2,'0');//补充字符串到长度为2,使用0来补
console.log(num);//01
二、数组扩展
新增了一些方法
- includes() 判断数组中是否包含指定数据 true/false
- Array.from() 将其他类型转换为数组类型
let obj = {
'0': 100,
'1': 200,
'2': 300,
length: 3
};
// //将上面的对象转换为数组
let arr = Array.from(obj);
console.log(arr);
三、对象扩展
- 对象属性名简写
//若对象的属性名与属性值对应的变量名称一致,则可以简写为如下:
let obj = {
name,
age,
addr
};
console.log(obj);
- 对象属性表达式
ES5中为对象添加属性:
obj.属性名
obj[‘属性名’]
ES6中,新增属性表达式
obj[‘表达式’]
let str = 'no';
let obj = {
name: 'jack',
'age': 20,
// ['a'+'b'+5]:"hello"
[str]: "100"
};
// obj['a' + 'b' + 5] = 1000;
console.log(obj);
示例2:构建城市列表数据
let obj={};
for(let i=0;i<26;i++){
var c=String.fromCharCode(65+i);
obj[c]=[];
}
console.log(obj);
- 对象方法的简写
对象中的方法可以去掉function关键字声明,直接使用函数名(),形式即可:
let obj={
name,
age,
addr,
say(){
console.log(111);
},
walk(){
console.log(222);
}
};
四、函数扩展
- 参数默认
在ES6中,允许给形参添加默认值
//es6中
//形参可以添加默认值
function fn(a = 0, b = 0) {
console.log(a + b);
}
fn(10,20);//30
fn(10);//10
fn();/0
回顾:在ES6中,有哪些默认值?
- 解构默认值 //当解构的数据个数少于变量的个数,解构默认值可以解决解构失败的问题
- 函数的形参默认值 //实参个数少于形参个数时,函数形参默认值起作用
解构默认值+形参 —>解决参数的顺序
示例1:ajax封装时,用对象作为参数,并给解构时传默认值 //当参数传递不全时,仍能正确运行
解构默认值+形参默认值—>解决参数顺序问题,又能解决参数默认值问题
示例1:求和函数 //当不传递参数时(fn()😉,形参默认值生效,当前参数为[];对[]进行解构,解构默认值生效
function fn([a = 0, b = 0] = []) {
console.log(a + b);
}
fn([10, 20]);
fn([10]);
fn([]);//解构默认值生效
fn();//形参默认值生效
示例2:
//解构+形参默认值
function ajax({
method = "GET",
url = "http://localhost:3000",
params = '',
success
} = {}) {
var xhr = new XMLHttpRequest();
if (method == "GET" && params != undefined) {
url = url + "?" + params;
}
xhr.open(method, url);
xhr.onreadystatechange = function () { };
if (method == "POST" && params != undefined) {
xhr.send(params);
} else {
xhr.send();
}
}
ajax();
- 箭头函数
在ES6中,允许通过箭头来定义函数 => //多用于函数的表达式声明中let sum=function fn () { } let sum=fn()=>{}
- 参数的个数
- 若参数的个数是一个,则省略()
- 若无参或有两个以上参数,()不能省略
- 返回值
- 若函数体只有一句代码,且是返回语句,则可以省略{}和return关键字
- 其它情况,return和{}都不能省略
特殊情况:若返回值为对象,则不能省略return和{}(有歧义,会把{}理解为函数体)
let fn = function (a, b) { return { name: a, age: b }; }
- 箭头函数中的this
在普通函数和箭头函数中this的指向不一样。
普通函数中:this指向调用者
箭头函数中:this指向定义时的作用域(当前是谁的作用域,this就指向谁)
普通函数和箭头函数的区别:
- this指向不同
- 箭头函数不能用于构造函数,普通函数可以
- call和apply可以修改普通函数中this的指向,不能修改箭头函数中this的指向
- 箭头函数中没有arguments属性,箭头函数使用rest参数实现arguments的功能
- 箭头函数没有prototype属性,普通函数有
- 箭头函数不会被绑定到顶级对象上
箭头函数不适合的场景: - 构造函数
- 对象的方法 /此时this都指向window
- 事件函数
- 参数的个数
var obj = {
sName: "李四",
age: 20,
say: function () {
console.log(this);//obj
setTimeout(function () {
console.log(this);//window
console.log(this.sName + " 哈哈哈");
}, 1000);
}
};
var obj = {
sName: "李四",
age: 20,
// say: function () {
// console.log(this);//obj
// setTimeout(() => {
// console.log(this);//obj
// console.log(this.sName + " 哈哈哈");//undefined哈哈哈
// }, 1000);
// }
// say: ()=> {
// console.log(this);//window
// setTimeout(() => {
// console.log(this);//window
// console.log(this.sName + " 哈哈哈");
// }, 1000);
// }
};
obj.say();
- rest参数
由于ES6中的箭头函数不能使用arguments属性,rest参数一定程度上类似arguments。
…变量名
rest参数能够接收任意多的数据
rest参数只能是参数列表中的最后一个参数
五、扩展运算符
… 扩展运算符
运算规则:扩展运算符是rest参数的逆运算
rest参数:将离散数据转换为数组(聚合)
扩展运算符:将集合转换为离散数据(打散)
区分:在函数的参数位置的是rest参数,其他都是扩展运算符
//rest参数
function fn(...all){
let sum=0;
for(let i in all){
sum+=i;
}
}
fn(10,20,30);
//扩展运算符
let arr=[10,20,30];
let arr0=[...arr];//先将数据打散,再放入数组中
console.log(arr0);//[10,20,30 ]