欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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用知名符号暴露某些场景的内部实现

  1. 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
  1. [扩展]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]]
  1. [扩展] 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()
  1. [扩展]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]
相关标签: es6 javascript