一、let命令和const命令
1.let命令:用于声明变量,与var类似,不同的是:
- let声明的变量只在代码块中有效;
- let不存在“变量提升”,即变量一定要在声明后使用
- 在一个代码区域里,不能重复声明同一个变量
{
let a=0;
console.log(a);
}
console.log(a); //报错 let只在代码块中作用
由于 let声明的变量在一个代码块中有效,可以用于代替ES5中的相关闭包问题,比较简便;例如:ES5中在循环内部的事件中输出每次循环的次数
for(var i=0;i<10;i++){
(function(a){
setTimeout(function(){
console.log(a);
})
})(i);
}
ES6用let命令可简化操作:
for(let i=0;i<10;i++){
setTimeout(function(){
console.log(i);//输出10个10
})
}
2.const:声明一个只读常量,即一旦声明,其值就不能改变
const a=3.14;
console.log(a++); //报错 const定义只读变量,不可改
二、变量的解构赋值
1.数组的解构赋值:只要等号两边的模式相等,即可按照顺序依次进行赋值
{
let [a,b,c]=[1,2,3,4,5,6];
console.log(a,b,c); //1 2 3
let [d,[[f],g]]=[1,[[2],3]];
console.log(d, f, g); //1 2 3
let [name,age,grade]=["张三",13,7];
console.log(name,age,grade); //张三 13 7
}
注:
- 解构赋值允许设置默认值,即等号左边数组中的变量可以直接进行赋值,例如:
let [a=10,b]=[,2];
console.log(a, b); //10 2
- 如果等号的右边不是数组形式,则赋值会报错;例如:
let [a]=1;
console.log(a); //报错
2.对象的解构赋值
- 已有对象的解构赋值
// console 对象
let {log}=console;
log(1); //输出1
//Math 对象
let {random,floor,round}=Math;
console.log(random()); //0-1随机数
console.log(round(3.45)); //3
- 自定义对象的解构赋值
//自定义对象
let {name,age}={name:"张三",age:20};
console.log(name, age);
注:对提前声明过的对象赋值
let x; //声明x
// {x}={x:3}; //报错
> js会将{x}理解成一个代码块,从而发生语法错误。
> 只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。
//改为:
({x}={x:3}); //x 3
console.log(x);
3. 字符串的解构赋值
let [a,b,c,d,e,f,g]="related";
console.log(a, b, c, d, e, f, g); //r e l a t e d
注:length属性的应用
let {length:len}="related";
console.log(len); //7
三、扩展符 "…"的应用
- 数组中,扩展运算符必须放在最后一个元素上
let [a,b,...c]=[1,2,3,4,5,6,7];
console.log(a, b, c); //1 2 [3, 4, 5, 6, 7]
- 拆分数组
console.log(...[1, 2, 3, 4, 5]); //1 2 3 4 5
- 替换apply()方法:es5中,当数组作为实参向函数传参时,需要调用apply方法,es6中则可以使用扩展运算符对数组进行拆分,再进行传参
//es5
function fn(x, y, z) {
console.log(x, y, z);
}
var args = [0, 1, 2];
fn.apply(this,args); //0 1 2
//es6
function f(x, y, z) {
console.log(x, y, z);
}
var args = [0, 1, 2];
fn(...args); //0 1 2
4.复制数组:保证复制一个数组后,改变两个数组其中任意一个值,另一个数组不受影响
let a=[1,2,3,4];
let b=a;
b[0]=8; //改变 a b两个数组其中任意一个值,两个数组均被改变
console.log(a, b);
//a [8,2,3,4] b [8,2,3,4]
//运用扩展符...
let a=[1,2,3,4];
let b=[...a]; //将a 拆分后再赋给b
b[0]=8; //改变 a b两个数组其中任意一个值,另一个数组不受影响
console.log(a, b);
//a [1,2,3,4] b [1,2,3,4]
5.合并数组
//合并数组
let a=[1,2,3];
let b=[4,5,6];
console.log(...a,...b);
四、扩展方法
- 数组的扩展
Array.from() //将类数组转为真正的数组
Array.of() //将一串数值转为数组
arr.find() //参数:回调函数;方法返回符合条件的第一个数据
arr.findIndex() //参数:回调函数;方法返回符合条件的第一个数据的索引
let arr={
0:"a",
1:"b",
length:2
}
console.log(Array.from(arr)); // ["a","b"]
console.log(Array.of(1, 2, 3, 4, 5)); //[1,2,3,4,5]
let arr=[1,2,3,4,5];
console.log(arr.find(function(n){
return n>2;
})); //输出数值 3
console.log(arr.findIndex(function(n){
return n>2;
})); //输出索引 2
}
2.对象的扩展
- 可以直接在对象内部写入变量和函数,作为对象的属性和方法
let obj = {
name:"张三",
sleep(){
return "睡觉";
}
};
- 可以用字面量和表达式作为属性名,字面量和表达式均放在方括号内
var sex="Sex";
var a="age";
var b="Now";
let obj={
[sex]:"男", //
[a+b]:20 //表达式作为属性名
}
//属性输出
console.log(obj[sex]);
console.log(obj[a+b]);
- 可枚举性:影响for…in遍历、keys()方法的获取
对象的三个方法:
Object.getOwnPropertyDescriptor(obj,"属性名") //获取对象obj的该属性配置
Object.defineProperty(obj,"属性名",{属性配置}) //设置对象obj的该属性配置
Object.keys(obj) //获取对象obj的所有的键
属性配置:
value: ""
writable: true 可写性
enumerable: true 可枚举性
configurable: true 可配置性
当对象中某一属性的enumerable值为false时,
则对象的 “for...in遍历” 以及对象的 ”keys()“ 方法获取不到该属性
let obj={
name:"张三",
age:20
}
console.log(Object.getOwnPropertyDescriptor(obj, "name"));
/*输出
* value: "张三"
* writable: true 可写
* enumerable: true 可枚举
* configurable: true 可配置
* */
console.log(Object.getOwnPropertyDescriptor(obj, "age"));
/*输出
* value: 20
* writable: true 可写
* enumerable: true 可枚举
* configurable: true 可配置
* */
//遍历对象
for(var per in obj){
console.log("obj."+per+"="+per);
}
/*两个属性均可遍历到
*obj.name=name
*obj.age=age
*/
//修改age属性的配置
Object.defineProperty(obj,"age",{
value:20,
enumerable: false //设为不可枚举
})
for(var per in obj){
console.log("obj."+per+"="+per);
//输出 obj.name=name
console.log(Object.keys(obj));
//只输出name键["name"]
}
小结:当对象中某一属性的enumerable值为false时,
则在对象属性的 “for...in”遍历 以及对象的 ”keys()“ 方法遍历中均获取不到该属性
- super关键字:指向当前对象的原型对象(与this用法相似)
设置原型对象的方法:
Object.setPrototypeOf(当前对象,给当前对象要设置的原型对象)
let person={
sleep(){
console.log("sleep");
}
}
let student={
usesleep(){
super.sleep();
}
};
// student.prototype=person;
Object.setPrototypeOf(student,person); //设置原型对象
console.log(student);
student.usesleep();
小结:
super 只能写在对象的方法内部,不能直接写在属性上和方法的返回值上
- 函数的扩展
- 可以直接给函数的形参带入了默认值
function method(a=2,b=2){
console.log(a + b);
}
method(); //4
- 形参与解构赋值连用
function method({a="c",b}){
console.log(a, b);
}
method({}); //c undefined
method({a:2,b:"d"}); //2 "d"
- 扩展运算符与函数的连用
function method([a,...b]){
console.log(a, b);
}
method([1,2,3,4,5,6]); //1 (5) [2, 3, 4, 5, 6]
- 箭头函数
let 函数名=(参数)=>返回值
1.参数可以为空
2.返回值为对象时,返回值需要加上圆括号
//es5
function method(val){
return val;
}
console.log(method(1)); //1
//es6写法
let method=(val)=>val;
console.log(method(1)); //1
//返回对象
let method=()=>({name:"张三",age:20}); //返回值加圆括号
console.log(method());
五、对象的新增方法
1.Object.assign()
- 用于合并对象,将若干个对象的可枚举属性合并到目标对象上
let obj1={
name:"张三"
}
let obj2={
name:"李四",
age:20,
sex:"男"
}
console.log(Object.assign({}, obj1, obj2));
//{name: "李四", age: 20, sex: "男"}
小结:
如果要合并的若干个对象上有同名属性,则后者覆盖前者
- Object.assign()方法也可用来复制对象
let a={a:1,b:2,c:{m:0}};
let b=Object.assign({},a);
a.c.m=30;
console.log(a);
console.log(b);
小结:
复制完对象后,修改两个对象中任意一个对象中的值,两个对象对应的值都会发生改变
2.Object.keys(),Object.values(),Object.entries()
Object.keys() //获取键
Object.values() //获取键值
Object.entries() //获取键值对数组
Object.keys(),Object.values(),Object.entries()
let obj={
name:"张三",
age:20,
sex:"男"
};
console.log(Object.keys(obj)); // ["name", "age", "sex"]
console.log(Object.values(obj)); //["张三", 20, "男"]
console.log(Object.entries(obj));
// 0: (2) ["name", "张三"]
// 1: (2) ["age", 20]
// 2: (2) ["sex", "男"]
3.Object.is():比较两个值是否严格相等,与“===”运算符相似
console.log(Object.is({}, {})); //false
console.log(Object.is(NaN, NaN)); //true
console.log(Object.is(+0, -0)); //false
小结:+0与 -0不相等,NaN等于其本身