JS-ES6声明与表达式
文章目录
let&const
仅在代码块内(不是函数)内有效
let
和const
声明的变量会形成一个闭包,仅在当前代码块内有效
{
var a=1;
let b=1;
const c=3.14;
}
console.log(a); //1
console.log(b); //not undefined
console.log(c); //not undefined
{
let a=1; //作用于当前代码块内,包含子代码块
const b=3.14;
{
console.log(a); //1
console.log(b); //3.14
}
不能重复声明
var a=1;
var a=2; //ok
let b=1;
const b=2; //has already been declared
var b=1;
const b=2; //has already been declared
let b=1;
let b=2; //has already been declared
/* ... ... */
for循环setTimeout案例
//因为setTimeout内函数要等for循环完毕再执行,所有代码块内的i都指向一个i,所以输出10个10
for(var i=0;i<10;i++){
setTimeout(function(){
console.log(i);
})
}
//let仅在当前代码块内有效,所以相当于10个代码块内的j都不相通,所以输出0-9
for(let j=0;j<10;j++){
setTimeout(function(){
console.log(j);
})
}
不存在变量提升
console.log(a); //变量已提升但未赋值,所以 undefined
var a=5;
console.log(b); //未声明,所以 not undefined
let b=5;
console.log(c); //未声明,所以 not undefined
const c=3.14;
const声明规则
const a=1; //ok,必须要直接赋值,且只能赋值一次
const b; //error 未设置初始值
b=1;
const c=1;
c=2; //error 常量已被分配
const暂时性死区
若当前代码块内有相应常量的声明,则不会考虑代码块外
const a=5;
{
console.log(a); //not defined
const a=6;
}
解构赋值
数组解构
//基本格式
var [name,age]=["tom",18];
console.log(name+" "+age); //tom 18
//可忽略
var [a,b,c]=[,10];
console.log(a+" "+b+" "+c); //undefined 10 undefined
//可嵌套
var [x,[[y],z]]=[1,[[2],3]];
console.log(x+" "+y+" "+z); //1 2 3
//剩余运算符
var [q,...w]=[1,2,3,4,5];
console.log(q+" "+w); //1 2,3,4,5(w是个数组)
var [q2,...w2]=[1,2];
console.log(q2[0]+" "+w[0]); //undefined(q不是数组) 2(即使只有一个也是数组)
//字符串
var [d,e,f,g,h]="Hello";
console.log(d+e+f+g+h); //Hello
//解构默认值
var [i=1,j]=[5,6]; //有匹配结果时,正常解构
console.log(i+" "+j); //5 6
const [k=5,l=6]=[7]; //即使是const,有匹配结果时,正常解构,不按默认值,所以不会报错
console.log(k+" "+l); //7 6(l没有匹配结果,所以等于默认值)
对象解构
//基本格式
var {name,age}={name:"tom",age:18};
console.log(name+" "+age);
var {foo:bar}={foo:"aaa"}; //此时bar被赋值,(foo只是一个参考变量,为undefined)?猜测
console.log(bar); //aaa
//可忽略可嵌套
var {a,b,c}={b:"bbb",a:"aaa"};
console.log(a+" "+b+" "+c);
var {x:{x1,x2:[x21,x22]}}={x:{x1:"bbb",x2:[,"x22"]}}; //x,x2都为(参考变量)猜测
console.log(x1+" "+x22);
//剩余运算符
var {q,...w}={q:1,u:2,v:5,w:6}; //后面的i j w将赋给前面的w作为属性,所以名字不重复
console.log(q+" "+w.u+" "+w.v+" "+w.w);
//解构默认值
var {i=5,j=6}={i:3}; //注意是等号
console.log(i+" "+j);
var {d:e=15,f:g=16}={d:17,g:18};
console.log(e+" "+g);
Symbol
Symbol是一个新的数据类型
知识点: 数据类型和对象的区别
//对象用new
function Student(name,age){
this.name=name;
this.age=age;
}
var s1=new Student("ming",20);
//数据类型不能new
var n1=Number(5);
知识点: 对象中[]
和.
的区别
var a="b";
var b="a";
var obj={a:"xiaoming",[b]:"18"};
console.log(obj["a"]+"等同于"+obj.a); //[""]相当于.
console.log(obj[a]+"等同于"+obj.b); //obj[a] --> obj["b"] --> obj.b
知识点: for…in循环
var as=["aaa","bbb","ccc"];
for(var a in as){ /*...*/ }
知识点: defineProperty
let a={};
a.name="xiaoming";
// ↑ 等同于 ↓
let b={};
Object.defineProperty(b,"name",{value:"xiaoming"});
知识点: 公有属性/方法和私有属性/方法
公有属性/方法外部可访问,私有属性/方法外部不可访问
function user(username,age){
this.username=username;
var age=age;
this.sayUserInfo=function(){
sayUsername();
sayAge();
}
var sayUsername=function(){
console.log(username);
}
var sayAge=function(){
console.log(age);
}
}
var u=new user("tom",15);
console.log(u.username);
console.log(u.age); //undefined
u.sayUserInfo();
u.sayUsername(); //not a functino
知识点: Object.keys()方法
属性名被转换为数组
var obj={name:"xiaoming",age:20};
var objArr=Object.keys(obj);
console.log(objArr); //["name","age"]
Symbol特性
唯一性
Symbol接受一个字符串作为参数,相同参数的Symbol的值都是不相等的
var s1=String("aaa");
var s2=String("aaa");
console.log(s1===s2); //true
var sy1=Symbol("aaa");
var sy2=Symbol("aaa");
console.log(sy1===sy2); //false
公有但普通方式遍历不到
var obj={};
var sy=Symbol("key1");
obj[sy]="aaa";
console.log(obj[sy]); //Symbol作为属性名时,该属性是公有属性
//但是在for...in和for...of中不会被读取到
for(var i in obj){ //为空所以不执行
console.log(i);
}
//Object.keys(),Object.getOwnPropertyNames()也不会读取到
有专门的方法获取:
console.log(Object.getOwnPropertySymbols(obj)); //可以获取到,返回一个数组,包含所有Symbol类型
console.log(Reflect.ownKeys(obj)); //可以获取到,返回一个数组,包含所有Symbol类型
常见用法
switch例子
const COLOR_RED = "red";
const COLOR_BLUE = "blue";
const MY_BLUE = "blue";
function getConstantName(color) {
switch (color) {
case COLOR_RED :
return "COLOR_RED";
case COLOR_BLUE:
return "COLOR_BLUE";
case MY_BLUE:
return "MY_BLUE";
default:
return "not find color";
}
}
console.log(getConstantName(MY_BLUE)); //会被误当作 COLOR_BLUE
//这样 COLOR_BLUE != MY_BLUE ,即使参数相同,也都是唯一的
const COLOR_RED = Symbol("red");
const COLOR_BLUE = Symbol("blue");
const MY_BLUE = Symbol("blue");
方法
Symbol.for
var a=Symbol("aaa");
var b=Symbol.for("aaa"); //使用for则表示将"aaa"登记,待下次再使用for时将不再创建,直接引用
var c=Symbol.for("aaa"); //指向b
console.log(a===b); //false
console.log(b===c); //true
Symbol.KeyFor
返回一个已登记的 Symbol 类型值的 key
var a=Symbol("aaa");
var b=Symbol.for("aaa");
var c=Symbol.for("aaa");
console.log(Symbol.KeyFor(b)); //aaa
if(! Symbol.KeyFor(a)){ //判断Symbol值是否已被登记
console.log("未登记");
}