zoukankan      html  css  js  c++  java
  • ES6新语法之---对象字面量扩展、模板字符串(5)

    这节课学习ES6中对象字面量扩展和新增模板字符串

    第一部分:对象字面量扩展

    1.简洁写法

      ES6对于对象字面量属性提供了简写方式。

      1.1:属性简写

            //传统写法
            var x = 2, y = 3,
                o = {
                    x: x,
                    y: y
                };
    
            //ES6简洁写法
            var x = 2, y = 3,
                o = {
                    x,  //属性名和赋值变量名相同时,可简写
                    y
                };

      1.2:方法简写

            //传统写法
            var o = {
                x: function() {
                    //...
                },
                y: function() {
                    //...
                }
            }
    
            //ES6简洁写法
            var o = {
                x() {
                    //...
                },
                y() {
                    //...
                }
            }

      1.3简洁方法的局限

      分析下面代码是否可以通过简洁方法重构:

            function runSomething(o) {
                var x = Math.random(),
                    y = Math.random();
                return o.something(x, y);   //通过o调用属性方法
            }
    
            runSomething({
                something: function something(x, y) {
                    if (x > y) {
                        return something(y, x)  // 当不符合条件时,递归调用something()方法
                    }
                    return y - x;
                }
            });

      这里的'something:'属性和function something()各有用途,属性something可以通过o对象调用,而function something()在自身内部调用用于递归实现

      分析1:在obj对象内部通过obj.something()实现递归

            function runSomething(o) {
                var x = Math.random(),
                    y = Math.random();
                return o.something(x, y);   //通过o调用属性方法
            }
            var obj = {
                something: function(x, y) {
                    if (x > y) {
                        return obj.something(y, x)  // 这里我们使用obj调用functiong
                    }
                    return y - x;
                }
            };
            runSomething(obj);

      如果obj对象的引用指向不发生改变的话,那么这是一个很好的办法。但obj的指向我们并不能控制

      分析2:使用this调用obj中的something()方法

            var obj = {
                something: function(x, y) {
                    if (x > y) {
                        return this.something(y, x)  // 这里使用this调用
                    }
                    return y - x;
                }
            };

      这里的this和分析1中的问题一样,我们无法保证something()方法始终是obj调用的这样就会存在this的绑定陷阱,可能this表示的并不是obj本身。

      例如:btn.addEventListener("click", obj.something, false);此时的this就不再是obj对象本身了,可能有人说可以使用obj.something.bind(obj)再绑定回去,这么麻烦就没必要了。

      再回头看我们最初1.3中的问题:

            runSomething({
                something: function something(x, y) {
                    if (x > y) {
                        return something(y, x)
                    }
                    return y -x;
                }
            })

      这里面function something()中的something总是指向这个something()这个函数本身,为我们提供了一个用于递归/事件绑定/解绑的引用,不会和this纠缠也不需要不可靠的对象引用。

      使用ES6的语法简化:

            runSomething({
                something(x, y) {
                    if (x > y) {
                        return something(y, x)      // Uncaught ReferenceError: something is not defined
                    }
                    return y -x;
                }
            })

      可以看到代码报错,因为其中something(x, y)会被解释为:something:function(x, y){...},这样return中的something方法就是未定义的。

    总结:简洁方法很方便,但是应该只在不需要他们执行递归/事件绑定/解绑时候使用。否则我们还是应该使用 something: function something(){...}这种传统的方式。

      1.4计算属性名

      计算属性名:对象中一个或多个属性名是通过某个表达式计算得来的。

            var prefix = "user_";
            var o = {
                baz: function () {
                    //...
                }
            };
            o[prefix + 'foo'] = function () {   //[]中可以放任意合法表达式
                // ...
            }
            o[prefix + 'bar'] = function () {
                // ...
            }

      计算属性名也可以作为简洁方法的名称出现:

            var o = {
                ["f" + "oo"]() {    // 作为简洁方法的名称出现
                    //...
                }
            }

    第二部分:模板字符串

      1.ES6引入了一个新的字符串字面量,使用`作为界定符,这样的字符串字面值支持嵌入基本的字符串插入表达式,会被自动解析和求值。

      1.1传统拼接字符串方式:

            var name = "Kyle";
            var greeting = "Hello " + name + "!";   //使用传统的'+'拼接字符串
            console.log(greeting);
            console.log(typeof greeting);

      1.2ES6模板字符串拼接:

            var name = "Kyle";
            var greeting = `Hello${name}!`;   //使用模板字符串,${}可以对变量取值。
            console.log(greeting);
            console.log(typeof greeting);

      字符使用``包裹,会被解释为一个字符串字面量,其中${}形式的表达式会被立即在线解析求值。

      1.3字符串字面量的一个优点,字符串可以分散在多行

            // text中的空格和换行会被保存
            var text = `
                Now is the time for all good men
                to come to the aid of their
                country!
            `;
            console.log(text);

      2.插入表达式${}

      2.1插入表达式中可以出现任何合法的表达式,包括函数调用、在线函数表达式调用,甚至其他插入字符串字面量!

            function upper(s) {
                return s.toUpperCase();
            }
            var who = "reader";
            var text = `
                A very ${upper("warm")} welcome
                to all of you ${upper(`${who}s`)}
                `;
            console.log(text);

      2.2插入表达式作用域

            function foo(str){
                var name = "foo";
                console.log(str);
            }
            function bar(){
                var name = "bar";
                foo(`Hello from ${name}!`);  //这里的name使用的是${name}所出现的作用域中的name
            }
            var name = "global";
            bar();              // Hello from bar

      插入字符串字面量在它出现的词法作用域内,没有任何形式的动态作用域。

      2.3标签模板字面量

      这个新功能不好解释,直接上代码比较直观:

            function foo(strings, ...values){
                console.log(strings);       //输出结果是数组,['Everything is', '!']
                console.log(values);        //输出结果是数组,['awesome']
            }
            var desc = 'awesome';
            foo `Everything is ${desc}!`;

      上例中foo`Everything...`是什么?其实这是一类不需要(...)的特殊函数调用,标签也就是foo部分是一个要调用的函数值。可以是任意结果为函数的表达式。

            function bar() {
                return function foo(strings, ...values){
                    console.log(strings);       //['Everything is', '!']
                    console.log(values);        // ['awesome']
                }
            }
            var desc = "awesome";
            bar()`Everything is ${desc}`;   //bar()的结果是一个函数

      分析:第一个参数strings为所有由普通字符串组成的数组。

           第二个参数values接收的是由插入表达式${}计算的结果值。

      应用:数字格式化为美元表示法

            function bar(strings, ...values) {
                return strings.reduce(function(s, v, idx){  //s表示上一次调用返回值,v表示当前元素之
                    if(idx > 0){
                        if(typeof values[idx - 1] == 'number'){
                            s += `$${values[idx - 1].toFixed(2)}`;  //如果是数字,给其拼接上'$'符号。
                        } else {
                            s += values[idx - 1]
                        }
                    }
                    return s + v;
                }, "");     //""作为reduce第一次调用的第一个参数的值
            }
            var amt1 = 11.99;
                amt2 = amt1 * 1.08,
                name = "Kyle";
            var result = bar`
                Thanks for your purchase, ${amt1}! Your
                product cost was ${amt1}, which with tax
                comes out to ${amt2}.
            `;
            console.log(result)

      如果values中遇到number值,就在其前拼接'$',然后使用toFixed(2)保留两位小数位。

      2.4原始字符串

      ES6提供了一个内建函数可以用作字符串字面量标签:String.raw(...)。得到字符串原始值。

            //结果我为'Hello
            //World'
            console.log('Hello
    World!');
            console.log(String.raw`Hello
    World!`); //结果为'Hello
    World'
  • 相关阅读:
    反射/元类/项目的生命周期
    面向对象高级
    面向对象之封装/鸭子类型
    面向对象之继承
    面向对象1
    包/logging模块/hashlib模块/openpyxl模块/深浅拷贝
    python 几行代码实现自动回复功能
    python crypto rsa 加密运用
    pytohn 单下划线与双下划线的区别
    python 线程小练习
  • 原文地址:https://www.cnblogs.com/diweikang/p/8999152.html
Copyright © 2011-2022 走看看