跟着coderwhy学习JavaScript高级(十五)

248 阅读3分钟

ES6

字符串模板

  • 在ES6之前,如果我们想要将字符串和一些动态的变量(标识符)拼接到一起,是非常麻烦和丑陋的(ugly)
    const name = "malong";
    const age = 18;
    const height = 1.88;
    
    console.log(`my name is ${name}`);
    console.log(`我是成年人吗? ${ age > 18 ? '是' : '否'}`)
    
    function foo() {
        return "function is foo";
    }
    
    console.log(`mu function ${foo()}`);
  • 标签模板字符串的使用
     function foo(...args) {
      console.log(args);
    }
    
    const name = "why";
    const age = 18;
    
    foo`Hello${name}Wor${age}ld`;
  • 如果我们使用标签模板字符串,并且在调用的时候插入其他的变量:
    • 模板字符串被拆分了;
    • 第一个元素是数组,是被模块字符串拆分的字符串组合;
    • 后面的元素是一个个模块字符串传入的内容;

image.png

函数的默认参数

  • 在ES6之前,我们编写的函数参数是没有默认值的,所以我们在编写函数时,如果有下面的需求
    • 传入了参数,那么使用传入的参数;
    • 没有传入参数,那么使用一个默认值;
    // ES5 写法
    function foo( x , y) {
        x = 20 || x;
        y = 30 || y;
        console.log(x, y);
    } 
    
    
    // ES6 写法
    function foo( x = 20 , y = 30) {
        console.log(x , y)
    }
    
    foo(10,20); // 10 20
    foo(); // 20 30
    
    foo(0,"") // es5 有bug  es6没有bug

函数的剩余参数

ES6中引用了rest parameter,可以将不定数量的参数放入到一个数组中:

  • 如果最后一个参数是 ... 为前缀的,那么它会将剩余的参数放到该参数中,并且作为一个数组;
    // 剩余参数只能放到最后面
    function foo( m, n, ...args) {
      console.log(m, n)
      console.log(args)

      console.log(arguments)
    }
    // args 是一个数组 (ES6新增想要替代arguments)
    // arguments 是伪数组
    // args只包含那些没有对应形参的实参,arguments 对象包含了传给函数的所有实参
    foo(20, 30, 40, 50, 60)
    

箭头函数

箭头函数是没有显式原型的,所以不能作为构造函数,使用new来创建对象

    var foo = () => {
        console.log("foo");
    }
    
    console.log(foo.prototype); //undefined
    var f = new foo(); //TypeError: foo is not constructor

展开运算符

  • 在函数调用时使用
    const names = [1,2,3];
    
    function foo(x, y, z){
        console.log(x,y,z);
    }
    // 展开运算符
    foo(...names);
  • 在数组构造时使用
    const names = [1,2,3];
    const address = [1,2,4];
    
    const newObj = [...names , ...address]; // 1,2,3,1,2,4
  • 在构建对象字面量时,也可以使用展开运算符,这个是在ES2018(ES9)中添加的新特性
    const names = [1,2,3]
    const address = "test";
    
    // {0: 1, 1: 2, 2: 3, address: 'test', age: 18}
    const newObj = { ...names, address, age: 18};
  • 展开运算符浅拷贝
    const info = {
        name: "why",
        friend: {name: "kebi"}
    }
    
    const obj = { ...info, name:"coderwhy" };
   
    obj.friend.name = "test";
    console.log(info.friend.name); // 会被改变成test

image.png

Symbol

  • Symbol在通常在对象中表示唯一的属性名
    // 在对象中,属性名key是唯一的,相同的会覆盖,但是Symbol就是用来创建一个独一无二的值
    // 可以让其不被覆盖
    
   const s1 = Symbol("abc");
   const s2 = Symbol("bcd");
   
   const obj = {};
   
   // 1.写法1:属性名赋值 , 不能使用.的语法
   obj[s1] = "abc";
   obj[s2] = "bcd";
   //obj.s1 = "abc" 错误
   
   // 2.写法2 Object.defineProperty
   Object.defineProperty(obj,s1,{
        configurable: true,
        writable: true,
        enumerable: true,
        value: "abc"
   })
   
   
   // 3.写法3 字面量
   const info = {
       [s1]: "abc",
       [s2]: "bcd"
   };
   
   // 获取Symbol的key 有固定的方法 使用循环 Object.keys都是获取不到的
   const symbolKyes = Object.getOwnPropertySymbols(info);

    // symbol 的key
    console.log(symbolKyes)

    // 遍历info for of遍历的是value   ---- for in 遍历的是key
    for (const item of symbolKyes) {
      console.log(info[item])
    }
  • 相同值的Symbol
    // 使用for  让描述相同 就可以了
    const s1 = Symbol.for("aaa");
    const s2 = Symbol.for("aaa");
    console.log(s1 === s2); // true
    
    // keyFor 也可以 key要是 Symbol创建出来的
    const s3 = Symbol.keyFor(s1);
    const s4 = Symbol.keyFor(s2);
    console.log(s3 === s4); //true
    
    const s5 = Symbol("aaa");
    const s6 = Symbol("aaa");
    console.log(s5 === s6); // false