ES6笔记三—解构与符号
程序员文章站
2022-07-15 11:18:27
...
解构与符号
解构
对象解构
什么是解构
使用ES6的一种语法规则,将一个对象或某个属性提取到某个变量中
let obj = {
name:"java",
age:20,
method(){}
}
// let name = obj.name;
// let age = obj.age;
// let method = obj.method;
//上述提取对象属性不方便
let {name,age,method} = obj;//解构,一步到位
console.log(name,age,method);
在解构中使用默认值
let obj = {
name:"java",
age:20,
method(){}
}
//在对象中如果没有prop属性,则prop为默认值
let {name,age,method,prop="默认值" } = obj;
console.log(name,age,method,prop);//prop = "默认值"
非同名属性解构
// {属性名:变量名}
let obj = {
name:"java",
age:20,
method(){},
address:{
city:"湖南"
}
}
let {name,meny:age="默认值",method} = obj;
console.log(name,meny,method);//meny=20
//我要解构obj中的city属性
//此处定义了两个变量:name,city,address不是变量表示进一步解构
let {address:{city}}= obj;
console.log(city);
数组解构
数组本身就是对象,因此可以用对象解构的方式
const num = ["a","b","c"];
const {
0:a,
1:b,
2.c
} = num;
console.log(a,b,c);//"a" "b" "c"
//也可以用数组方式解构
const [a,b,c] = num;
console.log(a,b,c);//"a" "b" "c"
//交换两个变量
let a =1 ,b = 2;
let [b,a] = [a,b];
console.log(a,b);//2,1
符号
普通符号
- 符号是ES6新增的一个数据类型,它通过使用函数
Symbol(符号名)
来创建
//创建符号
const syb = Symbol();
const syb1= Symbol("abc");
console.log(syb,syb1);//Symbol() Symbol(abc);
- 符号设计的初衷,是为了给对象设置私有属性,私有属性:只能在对象内部使用,外部无法访问
const obj ={
a:1,
b:2,
getRandow(){}//对象内部函数,只为帮助某些函数实现一个功能,就没有必要展示给外界(防止给调用者产生麻烦)
}
-
符号具有以下特点:
- 没有字面量
"jlls"//字符串字面量 2000//数字字面量 undefined true fales {} //符号没有,只能用Symbol函数
- 使用typeof得到的类型是symbol
- 每次调用Symbol函数得到的符号永远不相等,无论符号名是否相同
const syb1 = Symbol(); const syb2 = Symbol(); console.log(syb1 === syb2);//fales
- 符号可以作为对象的属性名存在,这种属性称为符号属性
- 开发者可以通过设计,让这些属性无法通过常规方式被外界访问
- 符号属性是不能枚举的,因此在for-in循环中无法读取符号属性,Object.keys方法也无法读取符号属性
- Object.getOwnPropertyNames尽管可以得到无法枚举的属性,但是仍然无法读取到符号属性
- ES6新增Obect.getOwnPropertySymbol方法,可以读取符号
let syb = Symbol("这是一个符号属性"); const obj ={ a:1, b:2, [syb]:3//符号属性 }
//设计外界无法访问属性 let obj = (()=>{ let getrandow = Symbol(); return { a:1, [getrandow](){ console.log("私有属性"); } } })() obj.a;//1 obj.getrandow//报错 let getrandow = Symbol(); obj[getrandow]//报错,符号永远不相等
let syb = Symbol(); const obj = { [syb]:1, a:2 } for(let prop in obj){ console.log(prop); } console.log(Object.getOwnPropertyNames(obj)); //得到的是一个符号属性的数组 const sybs = Object.getOwnPropertySymbol(obj); console.log(sybs);
-
符号无法被隐式转换,因此不能被用于数学运算,字符串拼接或其他隐式转换的场景,但符号可以显示转换为字符串,通过String构造函数进行转换即可,console.log之所以可以输出符号,是它内部进行显式转换
let syb = Symbol();
console.log(syb+"123");//隐式转换 ,报错
console.log(syb*2);//隐式转换 ,报错
//符号可以显示转换
let str = new Sring(syb);
console.log(str);
//console.log就是用new String然后改个颜色输出
共享符号
根据某个符号名称(符号描述)
Symbol.for("符号名称/符号描述");
let syb = Symbol.for();
let syb1 = Symbol.for();
let syb2 = Symbol.for("a");
console.log(syb === syb1);//true
console.log(syb === syb2);//fales
const obj = {
a:1,
[Symbol()]:2
};
console.log(obj[Symbol()]);//报错,每次调用Symbol函数得到的符号永远不相等
const obj1={
a:1,
[Symbol.for()]:2
}
console.log(obj1[Symbol.for()]);//2
共享符号实现原理
function symbolFor(name){
let global = {};
return function(name){
if(!global[name]){//不存在
global[name] = Symbol(name);//不存在就创建
}
return global[name];
}
}
知名(公共,具名)符号
知名符号是一些具有特殊含义的共享符号,通过Symbol的静态属性得到
ES6延续了ES5的思想:减少魔法,暴露内部实现
因此,es6用知名符号暴露某些场景的内部实现
-
Symbol.hasInstance
该符号用于定义构造函数的静态成员,它将影响instanceof
的判定
//instanceof 之前是不可以修改的,我们只知道它用于判定构造函数,并不清楚如何实现, 这个就是所谓魔法,
//运用知名符号可以参与它的实现
//instanceof实际上就是调用了Symbol.hasInstance
obj instanceof A
//等效于
A[Symbol.hasIntance](obj);//该方法所在位置:Function.prototype[Symbol.hasIntance]
function A(){
}
//修改Symbol.hasInstance
Object.defineProperty(A,Symbol.hasInstance,{
value:function(){
return fales;
}
})
let obj = new A();
console.log(obj instanceof A);//true 因为A[Symbol.hasInstance](obj)返回true,所以obj instanceof A 为true
colsole.log(A[Symbol.hasInstance](obj));//true
- [扩展]
Symbol.isConcatSpreadable
该知名符号会影响数组的concat
方法
const arr =[1];
const arr1 = [2,3];
//拼接方式可以用Symbol.isConcatSpreadable修改
//arr1[Symbol.isConcatSpreadable] = true;//则用分割的拼接方式
arr1[Symbol.isConcatSpreadable] = fales;//拼接方式则为[1,[2,3]]
const result = arr.concat(arr1);
console.log(result);//[1,[2,3]]
//该方法拼接有两种情况:
//[1,2,3] 该种拼接方式叫分割
//[1,[2,3]]
- [扩展]
Symbol.toPrimitive
该知名符号会影响类型转换的结果
const obj = {
a:1,
b:2
}
// Symbol.toPrimitive可以改变类型
//obj在进行类型转换时调用该函数
obj[ Symbol.toPrimitive] = function(){
return 2;
}
console.log(obj+1);//3
//console.log(obj+1);//[object Object]1 obj要类型转换,先调用valueOf(),如果返回的不是一个原始值(String,Number,underfined,null,Boolean),则调用toString()
- [扩展]
Symbol.toStringTag
该知名符号会影响Obect.prototype.toString的返回值
class Person{
[Symbol.toStringTag] = "Person";
}
const p = new Person();
const arr = [1,2,3];
console.log(Object.prototype.toString.call(p));//[object Person]
//console.log(Object.prototype.toString.call(p));//[object Object]
//console.log(Obect.prototype.toString.call(arr));//[object Array]
上一篇: 3.中文乱码、简单数据校验、访问web元素(我的struts2笔记)
下一篇: 第三周笔记