ES6的关键字和解构以及扩展等
2023/7/6大约 6 分钟
let和const
let
- 块级作用域:
- 在ES6之前只有全局作用域和函数作用域,造成内层变量覆盖外层变量,在循环中来计数的i会被泄露成全局的变量
for(var i=0;i<3;i++){ setTimeout(function(){ console.log(i); },1000*i); } ``` 上面在控制台只会打印出3 所以使用let ```js for(let i=0;i<3;i++){ setTimeout(function(){ console.log(i); },1000*i); }
const
const定义的变量是一个常量,常量不允许修改,也会产生一个块级作用域
变量解构
数组解构
如果解构不成功,变量的值就等于undefined。
<script>
// let a=1;
// let b=2;
// let [a,b]=[1,2];
// console.log(b);
let [foo,[[bar],baz]]=[1,[[2],3]];
console.log(bar);
let [,,name]=["h","h","skyme"];
console.log(name);
let [,...jack]=["hello","jacklove","ok"]
console.log(jack);
//解构不成功
let[foo2] =[];
console.log(foo2);
let[bar2,foo3]=[1];
console.log(foo3);
//不完全解构
let[x,y]=[1,2,3];
console.log(x,y);
let[a,[b],d]=[1,[1,2,3],4];
console.log(b);
</script>效果:

对象解构
对象解构不按照顺序:
let object={
type:'object',
name:'object.class'
}
//对象不用按照顺序解构
let{type}=object;
console.log(type);嵌套:
//看似是别名,但是,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
let obj = {
first: 'hello',
last: 'world'
};
let {
first: f,
last: l
} = obj;
let myClass = {
p: [
'hello',
{
type: 'p',
name: {
jack: 'skyme'
}
}
]
};
let {
p,
p: [, {
name: {
jack
}
}]
} = myClass;
console.log(jack);对象的解构赋值可以取到继承的属性:
const obj1 = {};
const obj2 = {
foo: 'obj2'
};
Object.setPrototypeOf(obj1, obj2);
const {
foo
} = obj1;
console.log(foo);字符串解构
const[a,b,...c]="hello";
console.log(c);
let {length : len} = 'hello';
console.log(len);函数参数的解构
function add([x,y]){
return x+y;
}
let x=add([1,2]);
console.log(x);
function move({x, y} = {}) {
return [x, y];
}为变量指定默认值
function move({x = 0, y = 0} = {}) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]为参数指定默认值
function move({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]数组的扩展
- Array.from()
- Array.of()
Array.of(1,2,3);
3. find,findIndex
let arr=[1,23,232,111,3];
let number=arr.find(function(item,index){
return item>1;
})
console.log(number);
let number2=arr.findIndex(function(item,index,arr){
return item>1;
})
console.log(number2);- entries(),keys()和values() ES6 提供三个新的方法——
entries(),keys()和values()——用于遍历数组。它们都返回一个遍历器对象(详见《Iterator》一章),可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。 - includes()
- 扩展运算符...
- 展开数组
function count(a, b) { return a + b; } count(...[1, 2]);
- 展开数组
对象的扩展
- 对象的简写,当属性与属性值相同的时候,可以省略
- 方法可以直接简写
let name ="skyme";
let person={
name,
sayName(){
console.log(this.name);
}
}
person.sayName();- 属性值是变量
- 对象解构
let name ="skyme";
let key="age";
let person={
[key]:18,
sayName(){
console.log(this.name);
}
}
let cp=Object.assign(person);
console.log(person.age)
//循环
for(let keys in person){
console.log(keys);
}
for(let keys of Object.keys(person)){
console.log("key:"+keys);
}
//值
for(let values of Object.values(person)){
console.log(values);
}
let p1={...person};//浅拷贝
let p2={like:"girl",...person};//合并
let {like,...p}=p2;函数的扩展
- 函数参数默认值
function(x=1,b=2){
//相当于给x,b这两个函数参数默认值
}- reset参数,获取调用函数时,多余的参数与扩展预算
function(...arr){
for(let i=0;i<arr.length;i++){
}
}- 箭头函数
setTimeout(()=>{
})<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>函数的扩展</title>
</head>
<body>
</body>
<script>
function myFc(a=1,b=2){
return a+b;
}
console.log(myFc(2,2));
function c1(a,b,love){
let {c,d}=love;
return c;
}
console.log(c1(1,2,{
c:"hello",
d:'jack'
}));
let arr=['hello','skyme']
</script>
</html>Promise异步编程
- 首先了解什么是JavaScript的异步编程:
通俗来说,异步就是从主线程发射一个子线程来完成任务
- 什么时候用异步编程: 在前端编程中(甚至后端有时也是这样),我们在处理一些简短、快速的操作时,例如计算 1 + 1 的结果,往往在主线程中就可以完成。主线程作为一个线程,不能够同时接受多方面的请求。所以,当一个事件没有结束时,界面将无法处理其他请求。 现在有一个按钮,如果我们设置它的 onclick 事件为一个死循环,那么当这个按钮按下,整个网页将失去响应。 为了避免这种情况的发生,我们常常用子线程来完成一些可能消耗时间足够长以至于被用户察觉的事情,比如读取一个大文件或者发出一个网络请求。因为子线程独立于主线程,所以即使出现阻塞也不会影响主线程的运行。但是子线程有一个局限:一旦发射了以后就会与主线程失去同步,我们无法确定它的结束,如果结束之后需要处理一些事情,比如处理来自服务器的信息,我们是无法将它合并到主线程中去的。 为了解决这个问题,JavaScript 中的异步操作函数往往通过回调函数来实现异步任务的结果处理。
- 回调函数:
案列:
const promise = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
if (Math.random() < 0.5) {
resolve('success');
} else {
reject('error');
}
}, 1000);
});
promise.then(result => {
console.log(result);
}).catch(error => {//失败状态
console.log(error);
});Promise类有.then() .catch() .finally()三个方法
new Promise((resolve,reject)=>{
console.log(1111);
resolve(2222);
}).then((value)=>{
console.log(value);
return 3333;
}).then((value)=>{
console.log(value);
})
- 为什么要使用promise 先了解下回调函数
function c1(id,callback){ let userId; setTimeout(()=>{ userId=id; },1000) callback(id); } function c2(id,callback){ let a=id+'skyme'; setTimeout(()=>{ console.log(a) callback(a); },1000) } c1('1',function(id){ console.log(id); c2(id,function(name){ console.log('c2'+name) }) }) ``` 这样进行操作会十分繁琐,如果使用Promise的话
function c1(id){
return new Promise(function(resolve, reject){
setTimeout(()=>{
console.log(id);
resolve('skyme');
},1000)
})
}
function c2(name){
console.log(name);
}
function c3(url){
console.log(url);
}
c1('1').then(function(name){
return c1(name);
}).then(function(url){
console.log('url'+url);
})function c1(id){
return new Promise(function(resolve, reject){
setTimeout(()=>{
console.log(id);
resolve('skyme');
},1000)
})
}
function c2(name){
return new Promise(function(resolve,reject){
console.log('参数:'+name+'这是promise');
resolve('name:'+name);
})
}
c1('1').then(function(name){
return c2(name);
}).then(function(c2){
console.log(c2+'执行结束');
}
)其实我们应该用到resolve,这个函数在异步操作成功后才会反回参数并传递
数组的迭代方法
遍历的一般情况用 for in 和for of
es6提供了一个forEach进行循环
第一个参数为value,第二个参数为索引,第三个参数为数组
let phone = ['小米','三星','苹果','一加','乐视','OPPO','VIVO','魅族','联想'];
phone.forEach((item,index,arr)=>{
console.log(item);
})map和fillter方法都是要返回一个新数组,原数组不会变动
let newPhone= phone.map((x)=>{
console.log(x);
return x+'手机';
})
console.log(phone,newPhone);
let f= phone.filter((item,index,arr)=>{
console.log('fillter:'+item);
return item=='小米';
})
console.log('f:'+f);Module
主要就是export和import的语法规范
