ES6 语法讲解
ECMAScript是JavaScript的标准(语法规范),javascript用于遵循这个规范。
- ES6并不是兼容所有浏览器,需要使用
Babel
转为ES5语法(ES5语法所有浏览器都兼容)。- Visual Studio Code下载插件:Bracket pair Colorizer(颜色高亮)、JavaScript(ES6)code(es6语法提示)、live server(vscode保存代码后,页面立即刷新,不需要手动刷新页面)
注:
live server使用:
vscode编辑器页面中右击,选择 “Open with live server”,即可开启保存后就刷新页面的效果,在vscode编辑器最底部有“port:5500”,点击后即可关闭此功能。
1、数组方法
迭代器函数:
(1)、forEach
应用场景:
//forEach使用姿势一:
var numbers = [1, 2, 3, 4, 5],
sum = 0;
numbers.forEach(function(item) {
sum += item;
});
console.log(sum); //结果:15
//forEach使用姿势二:
var numbers = [1, 2, 3, 4, 5],
sum = 0;
function adder(item) {
sum += item;
}
//直接调用adder函数,注意不加括号
numbers.forEach(adder);
console.log(sum); //结果:15
注意:map和forEach区别是:map有返回值,而forEach没有返回值。
(2)、map
注:map需要返回值,如果不给return,默认返回undefined,map返回的是一个新数组。
应用场景1:假定有一个数值数组A,将A数组的数值以双倍的形式放到B数组。
var numbers = [1, 2, 3];
var newNumbers1 = numbers.map(function(item) {
return item * 2;
});
console.log(newNumbers1); // 结果:[2,4,6]
应用场景2:假定有一个对象数组A,将A数组中对象某个属性的值存储在B数组中。
var cars = [
{
model: "mini",
price: 200
},
{
model: "nio",
price: 300
}
];
var prices = cars.map(function(item) {
return item.price;
});
console.log(prices); //结果:[200, 300]
(3)、filter
应用场景1:假定有一个对象数组A,获取数组中指定类型的对象放到B数组中。
var products = [
{
name: "cucumber",
type: "vegetable"
},
{
name: "apple",
type: "fruit"
},
{
name: "orange",
type: "fruit"
}
];
var filters = products.filter(function(item) {
return item.type == "fruit";
});
console.log(filters);
//结果:[{name: "apple", type: "fruit"},{name: "orange", type: "fruit"}]
应用场景2:假定有一个对象数组A,过滤掉不满足一下条件的对象,条件:水果 ,价格小于10,数量大于0。
var products = [
{
name: "cucumber",
type: "vegetable",
quantity: 10,
price: 5
},
{
name: "apple",
type: "fruit",
quantity: 0,
price: 5
},
{
name: "orange",
type: "fruit",
quantity: 1,
price: 2
}
];
var filters = products.filter(function(item) {
//使用&符号将条件链接起来
return item.type === "fruit" && item.quantity > 0 && item.price < 10;
});
console.log(filters);
//结果:[{name: "orange", type: "fruit", quantity: 1, price: 2}]
应用场景3:假定有对象A和数组B,根据A中id值,过滤掉B中不符合的数据。
var post = { id: 1, title: "A" };
var comments = [
{ postId: 3, content: "CCC" },
{ postId: 2, content: "BBB" },
{ postId: 1, content: "AAA" }
];
function commentsPost(post, comments) {
return comments.filter(function(item) {
return item.postId == post.id;
});
}
console.log(commentsPost(post, comments));
//结果:[{postId: 1, content: "AAA"}],返回的是数组
注意:filter和find区别:filter返回的是数组,find返回的是对象。
(4)、 find
应用场景1:假定有一个对象数组A,找到符合条件的对象
var users = [
{ name: "jack", age: 12 },
{ name: "alex", age: 15 },
{ name: "eva", age: 20 }
];
var user = users.find(function(item) {
return (item.name = "eva");
});
console.log(user);
//结果:{ name: "eva", age: 20 }
注:find()找到第一个元素后就不会在遍历其后面的元素,所以如果数组中有两个相同的元素,他只会找到第一个,第二个将不会再遍历了。
应用场景2:假定有一个对象数组A,根据指定对象的条件找到数组中符合条件的对象。
var post = { id: 1, title: "AAA" };
var comments = [
{ postId: 3, content: "CCC" },
{ postId: 2, content: "BBB" },
{ postId: 1, content: "AAA" }
];
function commentsPost(post, comments) {
return comments.find(function(item) {
return item.postId == post.id;
});
}
console.log(commentsPost(post, comments));
//结果:{postId: 1, content: "AAA"},返回的是对象
(5)、every
总结:一假即假 ,而且只要有一个元素是假,其后面的元素将不再遍历。
(6)、some
总结:一真即真
使用场景:假定有几台电脑,判断其操作系统是否都大于16
var computers = [
{ name: "mac", ram: 32 },
{ name: "mac", ram: 8 },
{ name: "IBM", ram: 16 },
{ name: "IBM", ram: 64 }
];
var everyComputerCan;
var someComputerCan;
//判断每一个元素的ram是否都大于16
var everyBoolan = computers.every(function(item) {
return item.ram > 16;
});
//判断元素的ram是否都大于16
var someBoolean = computers.some(function(item) {
return item.ram > 16;
});
console.log(everyBoolan); //结果:false
console.log(someBoolean);//结果: true
(7)、reduce
应用场景1:计算数组中所有值总和
var numbers = [1, 2, 3];
var sumVal = numbers.reduce(function(sum, number) {
return sum + number;
//0是sum的初始化值
}, 0);
console.log(sumVal);
应用场景2:将对象数组中对象的某个属性抽离到另外一个数组中
var colors = [
{ color: "red" },
{ color: "green" },
{ color: "black" }
];
var colorsNew = colors.reduce(function(colorArr, colors) {
colorArr.push(colors.color);
return colorArr;
}, []);
console.log(colorsNew);
//结果:["red", "green", "black"]
应用场景3:判断字符串中括号是否对称
function balanceParents(string) {
return !string.split("").reduce(function(previous, char) {
if (char == "(") {
return ++previous;
}
if (char == ")") {
return --previous;
}
return previous;
}, 0);
}
console.log(balanceParents("(())aaadsd))"));//结果:false
2、新语法
(1)、 const
const 定义的常量后不能更改其值,但是数组是可以创建后,添加元素的。
const arr = [];
arr[0] = 1;//不会报错
console.log(arr);
const str = "abc";
str = "ddd";//报错:Assignment to constant variable.
(2)、模板字符串
定义:模板字符串是指在js语句中使用``符号包含的字符串。
let age = 10;
function makeUppercase(item) {
return item.toUpperCase();
}
//模板字符串中语法:
//在模板字符串中使用${方法名()}调用某得方法
//在模板字符串中使用${}获取变量的值
var template = `<h1>内容</h1>
<spn>${makeUppercase("hello")}</spn>
<p>${age}</p>`;
document.getElementById("name").innerHTML = template;
页面结果显示:
**内容**
HELLO
10
(3)、箭头函数
const team = {
merbers: ["heny", "jack"],
teamName: "A组",
//箭头函数(ES6语法)
teamSummary: function() {
return this.merbers.map(item => {
//this指向team对象
return `${item}隶属于${this.teamName}小组`;
});
},
//self保存this(ES5语法)
teamSummary1: function() {
let self = this;
return this.merbers.map(function(item) {
return `${item}隶属于${self.teamName}小组`;
});
},
//bind绑定this(ES5语法)
teamSummary2: function() {
return this.merbers.map(
function(item) {
return `${item}隶属于${this.teamName}小组`;
}.bind(this)
);
}
};
console.log(team.teamSummary());
console.log(team.teamSummary1());
console.log(team.teamSummary2());
(4)、 增强对象字面量
目的:减少不必要的代码,比如我们使用vue开发时:
new Vue({
el: "#app",
//此处的router就是一种简写形式(即增强对象字面量),其完整写法为:"router:router"
router,
components: { App },
template: "<App/>"
});
同理,对于jquery中的ajax请求:
$.ajax({
//此处的url和data就是简写形式(即增强对象字面量),完整的为"url:url,data:data"
url,
data,
methods:"POST"
});
(5)、扩展运算符
应用场景1:将单独的数值组成数组返回
//使用"..."(扩展运算符)自动将传入的参数组成数组:numbers
function addNumber(...numbers) {
return numbers.reduce((sum, item) => {
return sum + item;
}, 0);
}
console.log(addNumber(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
//结果:55
应用场景2:组合多个数组
var defaultNum = [1, 2, 3, 4, 5];
var myNum = [10, 20];
var yourNum = [9, 8, 7];
console.log([11, 22, 33, ...defaultNum, ...myNum, ...yourNum]);
//结果: [11, 22, 33, 1, 2, 3, 4, 5, 10, 20, 9, 8, 7]
(6)、 解构
应用场景1:对象属性解构
var obj = {
name: "Zhangfei",
age: 26
};
//注意:结构的变量的名字要和对象中的名字保持一致,找不到的将会返回undefined
const { name, age, data } = obj;
console.log(name, age, data);
//结果:Zhangfei 26 undefined
应用场景2:函数参数解构
var obj = {
name: "zhangsan",
age: 12
};
function myObj({ name, age }) {
return `${name},年龄:${age}岁`;
}
console.log(myObj(obj));
//结果:zhangsan,年龄:12岁
应用场景3:数组元素的解构
const names = ["hery", "bucky", "emily"];
const [name1, name2, name3] = names;
console.log(name1, name2, name3);
//结果:demo.js:3 hery bucky emily
应用场景4:数组长度的解构
const names = ["hery", "bucky", "emily"];
//使用{}解析数组得到数组长度
const { length } = names;
console.log(length);
应用场景5:结构和展开运算符搭配使用
const names = ["herry", "emliy", "buky"];
const [name1, name2, ...rest] = names;
console.log(name1); //herry
console.log(name2); //emliy
console.log(rest); //['buky']
应用场景6:将数组转为对象
const points = [[1, 2], [3, 4], [5, 6]];
var newPoints = points.map(function(item) {
const [x, y] = item;
return { x, y };
});
console.log(newPoints);
//结果:[{x: 1, y: 2},{x: 3, y: 4},{x: 5, y: 6}]
3、新语法
(1)、 面向对象class(万事皆对象)
class Car {
constructor(options) {
this.title = options.title;
}
drive() {
return "vromm";
}
}
//这里需要继承Car类,拿到构造函数中的title属性
class Toyota extends Car {
constructor(options) {
//使用super继承父类的构造函数中的属性,这样toyota.title才不会是undefined
super(options);
this.color = options.color;
}
}
const toyota = new Toyota({ color: "red", title: "MINI" });
console.log(toyota.title); //MINI
(2)、 generator生成器(可以返回多次的函数)
//斐波那契数列
//生成器函数是:在function后面加上*的函数
function* fib(max) {
var a = 0,
b = 1,
n = 0;
while (n < max) {
yield a;//yield关键字
[a, b] = [b, a + b];
n++;
}
return;
}
for (var x of fib(5)) {
console.log(x);
}
//结果:0 1 1 2 3
(3)、 数据结构:map (与上面所讲的数组的map方法不是一回事)
注:与对象不同的是,键和值可以使任意类型的。
应用场景1: 创建map数据结构
const map1 = new Map();
//设置key键
const key1 = "name",
key2 = {},
key3 = function() {};
//设置value
map1.set(key1, "key1‘s value");
map1.set(key2, "key2’s value");
map1.set(key3, "key3‘s value");
console.log(map1.get("name")); //key1‘s value
console.log(map1.get(key2)); //key2’s value
console.log(map1.get(key3)); //key3‘s value
应用场景2:获取map数据结构的长度
console.log(map1.size); //3
应用场景3:遍历map数据结构的key和value
for(var [key,value] of map1){
console.log(`${key} = ${value}`);
}
//结果:name = key1‘s value
[object Object] = key2’s value
function () {} = key3‘s value
for (let item of map1.keys()) {
console.log(item);
}
//结果:name {} ƒ () {}
for (let item of map1.values()) {
console.log(item);
}
//结果:key1’s value key2’s value key3‘s value
应用场景4:将map数据结构的key和value转为数组
const keyArr = Array.from(map1.keys());
console.log(keyArr);
//结果:["name", {…}, ƒ]
const valueArr = Array.from(map1.values());
console.log(valueArr);
//结果:["key1‘s value", "key2’s value", "key3‘s value"]
(4)、 数据结构:set
set即集合:可以存储任何类型数据,并且是唯一的。
应用场景1:创建set
var set = new Set();
set.add(100);
set.add("asdf");
set.add({ name: "herry" });
set.add("fn");
set.add(100);
console.log(set);
//结果:{100, "asdf", {…}, "fn"}
应用场景2:set长度计算
console.log(set.size);
//结果: 4
应用场景3:判断set中是否包含某项
console.log(set.has(100));
console.log(set.has({ name: "herry" }));
//结果:true
false(因为对象在内存中存储的是地址,而不是值,所以是false)
应用场景4:删除set中某元素
set.delete("fn");
console.log(set);
//结果:{100, "asdf", {…}}
应用场景5:遍历set
for (let item of set) {
console.log(item);
}
//结果:100 "asdf" {…}
应用场景6:set转为数组
const arr = Array.from(set);
console.log(arr);
//结果:[100, "asdf", {…}]
4、数据请求(异步)
(1)、 promise
A[Promise] --> B(unresolved)
A[Promise] --> c(resolved)
A[Promise] --> d(rejected)
c --> e[then]
d --> f[catch]
应用场景1:
let promise = new Promise((resolve, reject) => {
resolve();
// reject();
});
promise
.then(() => {
console.log("no problem");
}) //resolve后走then()方法
.then(() => {
console.log("可以无限调用then");
.catch(() => {
console.log("uh oh,出问题啦");
}); //reject后走catch()方法
(2) fetch
fetch方法定义:
①、option(参数选项):
- method:get | post 等方法
- headers:任何你想加到请求中的头,可以是对象字面量的方式也可以是通过 Headers
- body:发送给服务器的信息, 可以是JSON, ufferSource, FormData, URLSearchParams, 或 USVString。注意get和HEAD请求没有body
- mode:请求模式, 可选值为 cors, no-cors, same-origin, 或 navigate,cors-with-forced-preflight。默认值应该为 cors。但在Chrome中,Chrome 47 之前的版本默认值为 no-cors ,自Chrome 47起,默认值为same-origin。--MDN Request
- credentials:在请求中是否需要凭据。在请求数据中根据是否需要携带Cookie 来设置其值,可选值为omit(在请求中不懈怠认证凭据(Cookie)), same-origin(在同原站点下包含凭据), 或 include(对所有网站包含认证凭据)
- cache:如何处理缓存,可取值有 default | no-store | no-cache | reload | force-cache | only-if-cached
- redirect:对重定向的处理,可取值 follow, error, redirect
- referrer:一个指定了no-referrer, client, 或一个 URL的 USVString 。默认值是client.
- integrity: 包括请求的 subresource integrity 值 (e.g., sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=).
②、mode 参数便于CORS,设置不同的值可以使在不同的请求方式下,使得请求有效。
- cors:在同域和带有CORS响应头的跨域下可以请求成功
- no-cors:常用于在跨域不带CORS场景下,此时请求发出并且会有响应,但是此时type为“opaque”, status为0 ,js获取不到返回数据。
- same-origin:在同域下请求
- cors-with-forced-preflight:在请求前进行preflight 检查
应用场景1:fetch实例
let url = "http://jsonplaceholder.typicode.com/posts";
fetch(url)
.then(response => response.json()) //fetch方法中先获取response.json()
.then(data => console.log(data))
.catch(error => console.log(error));
//结果:返回的是接口详细数据
应用场景2:fetch的三种请求数据方式
document.getElementById("button1").addEventListener("click", getText);
document.getElementById("button2").addEventListener("click", getJson);
document.getElementById("button3").addEventListener("click", getInternet);
//获取本地文本数据
function getText() {
fetch("test.txt")
.then(res => res.text())
.then(data => {
document.getElementById("output").innerHTML = data;
})
.catch(error => {
console.log(error);
});
}
//获取本地json数据
function getJson() {
fetch("data.json")
.then(res => res.json())
.then(data => {
console.log(data);
var str = "";
data.forEach(function(item) {
str += `<h2>${item.title}</h2><h3>${item.body}</h3>`;
});
document.getElementById("output").innerHTML = str;
})
.catch(error => {
console.log(error);
});
}
//获取接口数据
function getInternet() {
fetch("http://jsonplaceholder.typicode.com/users")
.then(res => res.json())
.then(data => {
console.log(data);
var str = "";
data.forEach(function(item) {
str += `<h2>${item.id}</h2><h3>${item.name}</h3>`;
});
document.getElementById("output").innerHTML = str;
})
.catch(error => {
console.log(error);
});
}
//data.json数据
[
{
"title": "es6",
"body": "I am es6"
},
{
"title": "es7",
"body": "I am es7"
},
{
"title": "es8",
"body": "I am es8"
}
]
//test.txt数据
这是本地文本数据测试的!!!
应用场景3:封装fetch(使用ES6语法promise,对照下面ES7语法封装)
//首先封装fetch 方法
class EasyHttp {
//get方法
get(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then(rsp => rsp.json())
.then(data => resolve(data))
.catch(error => reject(error));
});
}
//post请求
post(url, data) {
return new Promise((resolve, reject) => {
fetch(url, {
method: "POST",
headers: {
"Content-type": "application/json"
},
body: JSON.stringify(data)
})
.then(res => res.json())
.then(data => resolve(data))
.catch(error => reject(error));
});
}
//put请求
put(url, data) {
return new Promise((resolve, reject) => {
fetch(url, {
method: "PUT",
headers: {
"Content-type": "application/json"
},
body: JSON.stringify(data)
})
.then(res => res.json())
.then(data => resolve(data))
.catch(error => reject(error));
});
}
//delete请求
delete(url) {
return new Promise((resolve, reject) => {
fetch(url, {
method: "DELETE",
headers: { "Content-type": "application/json" }
})
.then(rsp => rsp.json())
.then(data => resolve("数据删除成功!"))
.catch(error => reject(error));
});
}
}
//main.js数据中调用封装好的fetch方法
const http = new EasyHttp();
//get请求(获取数据)
http
.get("http://jsonplaceholder.typicode.com/users")
.then(data => {
console.log(data);
})
.catch(error => {
console.log(error);
});
//post请求数据(增加数据)
const data = {
name: "Herry",
username: "恒瑞"
};
http
.post("http://jsonplaceholder.typicode.com/users", data)
.then(data => console.log(data))
.catch(error => {
console.log(error);
});
//put请求(更新数据)
const data = {
name: "Herry",
username: "恒瑞"
};
http
.put("http://jsonplaceholder.typicode.com/users/2", data)
.then(data => console.log(data))
.catch(error => {
console.log(error);
});
//delete请求(删除数据)
http
.delete("http://jsonplaceholder.typicode.com/users/2")
.then(data => console.log(data))
.catch(error => {
console.log(error);
});
5、es7方法
(1)、 async 和 await
应用场景1:async 和 await基本使用
//使用async定义函数,返回的是一个promise对象
async function myFun() {
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("Hello"), 1000);
});
const error = false;
if (!error) {
//这里await等待promise返回结果
const rsp = await promise;
return rsp;
} else {
await Promise.reject(new Error("error:报错了!"));
}
}
myFun()
.then(data => {
console.log(data);
})
.catch(error => {
console.log(error);
});
//输出结果:Hello
应用场景2:async 和 await调用接口
async function getUsers() {
//await等待接口调用成功
const response = await fetch("http://jsonplaceholder.typicode.com/users");
//await等待数据解析成功
const rsp = await response.json();
return rsp;
}
getUsers()
.then(data => console.log(data))
.catch(error => console.log(error));
//返回结果:users数据信息
应用场景3:ES7语法使用async 和 await重新封装fetch(对照上面的promise封装fetch)
//首先封装fetch方法:
class EasyHttp {
//get方法
async get(url) {
const response = await fetch(url);
const rspData = await response.json();
return rspData;
}
//post请求
async post(url, data) {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-type": "application/json"
},
body: JSON.stringify(data)
});
const rspData = await response.json();
return rspData;
}
//put请求
async put(url, data) {
const response = await fetch(url, {
method: "PUT",
headers: {
"Content-type": "application/json"
},
body: JSON.stringify(data)
});
const rspData = await response.json();
return rspData;
}
//delete请求
async delete(url) {
const response = await fetch(url, {
method: "DELETE",
headers: { "Content-type": "application/json" }
});
const rspData = await response.json();
return rspData;
}
}
//main.js数据中调用封装好的fetch方法
const http = new EasyHttp();
//get请求(获取数据)
http
.get("http://jsonplaceholder.typicode.com/users")
.then(data => {
console.log(data);
})
.catch(error => {
console.log(error);
});
//post请求数据(增加数据)
const data = {
name: "Herry",
username: "恒瑞"
};
http
.post("http://jsonplaceholder.typicode.com/users", data)
.then(data => console.log(data))
.catch(error => {
console.log(error);
});
//put请求(更新数据)
const data = {
name: "Herry",
username: "恒瑞"
};
http
.put("http://jsonplaceholder.typicode.com/users/2", data)
.then(data => console.log(data))
.catch(error => {
console.log(error);
});
//delete请求(删除数据)
http
.delete("http://jsonplaceholder.typicode.com/users/2")
.then(data => console.log(data))
.catch(error => {
console.log(error);
});
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。