ES6新特性(学起来)
let&const
var
声明的变量往往会越域
但let
声明的变量有严格的局部作用域。
<script>
{
var a = 1;
let b = 1;
}
console.log(a); //1
console.log(b); //Uncaught ReferenceError: b is not defined
</script>
var
可以声明多次
let
只能申明一次
<script>
var a = 1;
let b = 2;
var a = 3;
let b = 4;
console.log(a); //3
console.log(b); //Uncaught SyntaxError: Identifier 'b' has already been declared
</script>
var
会提升变量
let
不存在变量提升
<script>
console.log(a); //undefined
console.log(b); //Uncaught ReferenceError: Cannot access 'b' before initialization
var a = 1;
let b = 2;
</script>
const
声明常量(只读变量)
声明之后不允许改变。
一旦声明必须初始化,否则报错。
代码语言:javascript复制 <script>
const a = 1;
a = 2;
console.log(a); //Uncaught TypeError: Assignment to constant variable.
</script>
解构表达式
数组解构
代码语言:javascript复制 <script>
//之前的赋值写法
let arr = ["hello","world","ES6"];
let a = arr[0];
let b = arr[1];
let c = arr[2];
console.log(a,b,c); //hello world ES6
//ES6之后
let [d,e,f] = arr;
console.log(d,e,f); //hello world ES6
</script>
对象解构
代码语言:javascript复制 <script>
/**
* 以前的写法,太过麻烦
* 需要一个个赋值
**/
const person = {
name: "java",
age: 18,
friend: ["python,go,php"]
}
// const name = person.name;
// const age = person.age;
// const friend = person.friend;
// console.log(name, age, friend); //java 18 ["python,go,php"]
/**
* 现在可以这样写,注意,对象解构是{}
**/
const {name,age,friend} = person;
console.log(name,age,friend); //java 18 ["python,go,php"]
</script>
当然你如果不想变量继续叫name,age,friend
也可以这样赋值
代码语言:javascript复制 const {name:a,age:b,friend:c} = person;
console.log(a,b,c); //java 18 ["python,go,php"]
字符串扩展
新增API
ES6为字符串扩展了几个新的API:
includes()
:返回布尔值,表示是否找到了参数字符串。startsWith()
:返回布尔值,表示参数字符串是否在原字符串的头部。endsWith()
: 返回布尔值,表示参数字符串是否在原字符串的尾部。
<script>
let a = "hello,world";
console.log(a.startsWith("hello")); //true
console.log(a.endsWith("world")); //true
console.log(a.includes("w")); //true
console.log(a.includes(",")); //true
</script>
字符串模板
除此之外还有一个字符串模板,相当于加强版的字符串。用反引号``(之前我们字符串一直使用的是""),可以用来定义多行字符串,还可以在字符串中加入变量和表达式。
代码语言:javascript复制 console.log(`
let a = "hello,world";
console.log(a.startsWith("hello")); //true
console.log(a.endsWith("world")); //true
console.log(a.includes("w")); //true
console.log(a.includes(",")); //true
`);
let name = "Jam";
let age = 18;
function hello(){
return "你好";
}
let info = `我是${name},年龄${age 1},${hello()}`;
console.log(info);
函数优化
函数参数默认值
现在可以直接给一个默认值了
代码语言:javascript复制 function add(a,b){
b = 1;
return a b;
}
console.log(add(10));
不定参数
用来表示不确定参数的个数,必须有且只有一个不定参数。
代码语言:javascript复制 function fun(...values){
console.log(values); //本质就是转化为数组
console.log(values.length); //5
}
fun(4,5,6,7,8);
箭头函数
代码语言:javascript复制 // 一个a b的函数
var sum1 = (a, b) => a b;
var sum2 = (a, b) => {
c = a b;
return c 100;
}
console.log(sum1(1, 2));
console.log(sum2(1, 2));
const person = {
name: "java",
age: 18,
friend: ["python,go,php"]
}
var hello = (person) => person.name;
console.log(hello(person));
对象优化
新增API
代码语言:javascript复制 <script>
const person = {
name: "java",
age: 18,
friend: ["python,go,php"]
}
//将所有的属性名组成一个数组
console.log(Object.keys(person));
//将所有的属性值组成一个数组
console.log(Object.values(person));
//将属性名和值分别取出来组成一个数组
console.log(Object.entries(person));
const target = {
a: 1
};
const source1 = {
b: 2
};
const source2 = {
c: 3
};
//将source1和source2合并到target
Object.assign(target,source1,source2);
console.log(target);
</script>
声明对象简写
代码语言:javascript复制 let person = {
name: "Nginx",
//以前
play: function (things) {
console.log(this.name ": playing:" things);
},
//ES6写法(两种)
//箭头函数,拿不到this
play2: things => console.log(person.name ": playing:" things),
//另一种写法
play3(things){
console.log(this.name ": playing:" things);
}
};
person.play("basketball")
person.play2("game");
person.play3("soccer")
map方法
接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。
代码语言:javascript复制 let arr = ["1", "10", "15", "99"];
arr = arr.map(item => item "java");
console.log(arr); //["1java", "10java", "15java", "99java"]
Promise
在JavaScript的世界中,所有代码都是单线程执行的。由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现。一旦有一连串的ajax请求a,b,c,d...后面的请求依赖前面的请求结果,就需要层层嵌套。这种缩进和层层嵌套的方式,非常容易造成上下文代码混乱,我们不得不非常小心翼翼处理内层函数与外层函数的数据,一旦内层函数使用了上层函数的变量,这种混乱程度就会加剧,这种层叠上下文"的层层嵌套方式,着实增加了神经的紧张程度。
案例:用户登录,并展示该用户的各科成绩。在页面发送两次请求:
1.查询用户,查询成功说明可以登录
2.查询用户成功,查询科目
3.根据科目的查询结果,获取去成绩
实现:
首先我们需要根据需求需要先去创建3个json数据
user.json
代码语言:javascript复制{
"id": 1,
"name": "zhangsan",
"password": "123456"
}
user_course_1.json
代码语言:javascript复制{
"id": 10,
"name": "chinese"
}
course_score_10.json
代码语言:javascript复制{
"id": 100,
"score": 90
}
用过去的方法来实现这个需求
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<script>
// 1、查出当前用户信息
// 2、按照当前用户的id查出他的课程
// 3、按照当前课程id查出分数
$.ajax({
url: "user.json",
success(data) {
console.log("查询用户:", data);
$.ajax({
url: `user_course_${data.id}.json`,
success(data) {
console.log("查询到课程:", data);
$.ajax({
url: `course_score_${data.id}.json`,
success(data) {
console.log("查询到分数:", data);
},
error(error) {
console.log("出现异常了:" error);
}
});
},
error(error) {
console.log("出现异常了:" error);
}
});
},
error(error) {
console.log("出现异常了:" error);
}
});
</script>
</body>
</html>
使用Promise封装,虽然代码比之前更多了,但是逻辑上是比较清晰可取的。
代码语言:javascript复制 //promise封装异步操作
let p = new Promise((success, error) => {
$.ajax({
url: "user.json",
success: function (data) {
console.log("查询用户:", data);
//表示成功后进行执行下一个方法,即后面的p.then
success(data);
},
error: function (err) {
console.log("出现异常了:" error);
error(err);
}
});
});
p.then((obj) => {
//继续用promise包装,因为后面还有第3个需求
return new Promise((success, error) => {
$.ajax({
url: `user_course_${obj.id}.json`,
success: function (data) {
console.log("查询到课程:", data);
success(data);
},
error: function (err) {
console.log("出现异常了:" error);
error(err);
}
})
})
}).then((obj) => {
$.ajax({
url: `course_score_${obj.id}.json`,
success(data) {
console.log("查询到分数:", data);
},
error(error) {
console.log("出现异常了:" error);
}
});
}).catch((err => {
console.log(err);
}))
当然,上面的代码量多,而且实际开发我们也不会这么做。
下面我们去把他封装成函数。
代码语言:javascript复制 function get(url) {
return new Promise((success, error) => {
$.ajax({
url: url,
success: function (data) {
success(data);
},
error: function (err) {
error(err);
}
})
});
}
get("user.json")
.then((data) => {
console.log("查询用户:", data);
return get(`user_course_${data.id}.json`);
})
.then((data) => {
console.log("查询到课程:", data);
return get(`course_score_${data.id}.json`)
})
.then((data) => {
console.log("查询到分数:", data);
})
.catch((err)=>{
console.log("出现异常了:" , error);
})
模块化
模块化就是把代码进行拆分,方便重复利用。类似java中的导包:要使用一个包,必须先导包。而JS中没有包的概念,换来的是模块
模块功能主要由两个命令构成: export
和import
。
export
:命令用于规定模块的对外接口。
import
:命令用于导入其他模块提供的功能。
举个例子:
导出一个函数和一个变量->hello.js
代码语言:javascript复制const util = {
sum(a,b){
return a b;
}
};
var name = "java";
//导出util对象
export {util};
//导出name对象
export {name};
导出来使用,main.js
代码语言:javascript复制import {name,util} from "./hello.js";
console.log(name);
util(1,2);