• ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring


    接着上一篇的说。

    arrow functions 箭头函数

     => 更便捷的函数声明

        document.getElementById("click_1").onclick = function(){ console.log("say Hi!"); }
        document.getElementById("click_2").onclick = () => { let a = 1; let b = 2; console.log(a + b); }

    之前的 function 声明可以被 => 代替,书写起来更便捷。

    箭头函数还有个更炫酷也是最使用的用法。

    先看个常见的例子:

        class people{
            constructor(){ this.age = 18; }
            say(){ setTimeout(function(){ console.log("I'm " + this.age + " year old."); },2000) }
        }
        let children = new people();
        children.say();    // I'm undefined year old.

    这里的this指向内层function对象,所以出现undefined,这就是比较蛋疼的bug。为了方便理解上个截图说明

    传统解决方案:

        class people{
            constructor(){ this.age = 18; }
            say(){ 
                var self = this;
                setTimeout(function(){ console.log("I'm " + self.age + " year old."); },2000) 
            }
        }
        let children = new people();
        children.say();    // I'm 18 year old.

    this在函数内传递给一个变量再使用。或者

        class people{
            constructor(){ this.age = 18; }
            say(){ 
                setTimeout(function(){ console.log("I'm " + this.age + " year old."); }.bind(this),2000) 
            }
        }
        let children = new people();
        children.say();    // I'm 18 year old.

    bind(this) 指明this的对象

    再来看看用 => 的做法

        class people{
            constructor(){ this.age = 18; }
            say(){ 
                    setTimeout( ()=>{ console.log("I'm " + this.age + " year old."); },2000) 
               }
        }
        let children = new people();
        children.say();    // I'm 18 year old.

    简单省事儿阅读清晰。

    template string

    这玩儿超好用,一旦用上你会爱不释手,下面来看一段案例:

        class people{
            constructor(name,age,comeFrom){
                this.name = name;
                this.age = age;
                this.comeFrom = comeFrom;
            }
        }
        // 实例化对象
        let XiaoM = new people("小明",18,"中国");
        // 传统写法
        console.log("我叫"+XiaoM.name+",今年"+XiaoM.age+"岁,我来自"+XiaoM.comeFrom+"。");
        // template string写法
        document.write(`我叫<font color="red">${XiaoM.name}</font>,今年<b>${XiaoM.age}</b>岁,我来自${XiaoM.comeFrom}。`);
        console.log(`我叫${XiaoM.name},今年${XiaoM.age}岁,我来自${XiaoM.comeFrom}。`);

    template string有点类似C#中的string.format,不过个人感觉template stringstring.format更直观。

    用反引号(`来标识起始,用${}来引用变量,而且所有的空格和缩进都会被保留在输出之中,是不是非常爽?!

    说明下 反引号在大键盘数字键1的前面一个就是~下面的那个(很惭愧我找反引号找了一会才找到,我开始误以为是单引号)

    React Router从第1.0.3版开始也使用ES6语法了,例:

    <Link to={`/taco/${taco.name}`}>{taco.name}</Link>

    destructuring

    更简介易懂的解构。先来看下数组解构

        arr_animal = ["cat","dog","mouse"];
        // 传统写法
        var c = arr_animal[0];
        var d = arr_animal[1];
        var m = arr_animal[2];
        // destructuring解构
        var [c,d,m] = arr_animal;

    解构也可以跳过数组中的一些元素,如:

        arr_animal = ["cat","dog","mouse"];
        var [,d,] = arr_animal;

    还可以取除开头元素外的剩余元素,如:

        arr_num = [1,2,3,4,5,6,7,8,9,0];
        var [no1,no2, ...noX] = arr_num;
        console.log(noX);    // [3,4,5,6,7,8,9,0]

    注:...noX只能放在最后,否则报错。

     看下对象解构

        var objA = { name: "A",age: 12 };
        var objB = { name: "B",age: 18 };
        var { name: nameA,age: ageA } = objA;
        var { name: nameB,age: ageB } = objB;
        console.log(nameA,ageA); // A 12
        console.log(nameB,ageB); // B 18

    通常用以下写法更简明

         var { name , age } = { name:"XiaoM", age:18 }
         console.log(name,age);    // XiaoM 18

    注:这种写法仅限 解构变量名属性名 相同,否则解构变量为undefined

    看一个嵌套的例子:

        var complicatedObj = {
          arrayProp: [
            "Zapp",
            { second: "Brannigan" }
          ]
        };
        var { arrayProp: [first, { second }] } = complicatedObj;
        console.log(first); // "Zapp"
        console.log(second); // "Brannigan"

     注:这里只能解构 first 和 second  ,不能解构 arrayProp , 因为这里 相对于被解构的 first 和 second 来说 arrayProp 是一个数组。

    若需要解构 arrayProp 

        var complicatedObj = {
          arrayProp: [
            "Zapp",
            { second: "Brannigan" }
          ]
        };
        var { arrayProp } = complicatedObj;
        console.log(arrayProp); // ["Zapp", Object]

    请注意:当解构对象并赋值给变量时,如果你已经声明或不打算声明这些变量(亦即赋值语句前没有letconstvar关键字),你应该注意这样一个潜在的语法错误:

        { blowUp } = { blowUp: 10 };
        // Syntax error 语法错误

    为什么会出错?这是因为JavaScript语法通知解析引擎将任何以{开始的语句解析为一个块语句(例如,{console}是一个合法块语句)。解决方案是将整个表达式用一对小括号包裹:

    ({ safe } = {});

    解构值不是对象、数组或迭代器

    当尝试解构nullundefined时,你会得到一个类型错误:

        var {blowUp} = null;
        // TypeError: null has no properties(null没有属性)

    然而,可以解构其它原始类型,例如:布尔值数值字符串,但是你将得到undefined

        var {wtf} = NaN;
        console.log(wtf);
        // undefined

    这里可能对此感到意外,但经过进一步审查你就会发现,原因其实非常简单。当使用对象赋值模式时,被解构的值需要被强制转换为对象。大多数类型都可以被转换为对象,但nullundefined却无法进行转换。当使用数组赋值模式时,被解构的值一定要包含一个迭代器。

    当你要解构的属性未定义时你可以提供一个默认值

        var [missing = true] = [];
        console.log(missing);
        // true
        var { message: msg = "Something went wrong" } = {};
        console.log(msg);
        // "Something went wrong"
        var { x = 3 } = {};
        console.log(x);
        // 3

    解构的实际应用场景

    多重返回值

    返回一个数组,然后解构

        function returnMultipleValues() {
          return [1, 2];
        }
        var [foo, bar] = returnMultipleValues();

    返回值封装为一个对象并命名属性,然后解构

        function returnMultipleValues() {
          return {
            foo: 1,
            bar: 2
          };
        }
        var { foo, bar } = returnMultipleValues();

    函数参数定义

    作为开发者,我们需要实现设计良好的API,通常的做法是为函数为函数设计一个对象作为参数,然后将不同的实际参数作为对象属性,以避免让API使用者记住 多个参数的使用顺序。我们可以使用解构特性来避免这种问题,当我们想要引用它的其中一个属性时,大可不必反复使用这种单一参数对象。

        function removeBreakpoint({ url, line, column }) {    // ... }

    这种函数设计在开发中非常受欢迎。

    关于destructuring解构的参考资料

    ES6学习笔记目录

    ES6学习笔记<一> let const class extends super

    ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring

    ES6学习笔记<三> 生成器函数与yield

    ES6学习笔记<四> default、rest、Multi-line Strings

    ES6学习笔记<五> Module的操作——import、export、as

  • 相关阅读:
    页面内容[置顶] 采用Div+Css布局——牛腩
    区域函数[置顶] linux 3.4.10 内核内存管理源代码分析5:伙伴系统初始化
    安装应用android批量安装APK
    选择版本Win7系统VS2010下搭建qt开发环境
    字体格式The format of Oracle tnsnames.ora file
    程序执行vhdl中延时器的编写
    概率链接nbu 2416 奇怪的散步
    中国主题ASP.Net课堂实验4
    要求终点HDU1010:Tempter of the Bone
    解决方案编程苦B和二B程序员别忘了养生
  • 原文地址:https://www.cnblogs.com/MirageFox/p/7570032.html
Copyright © 2020-2023  润新知