ES6 new grammar --- object literal expansion, template string (5)

This lesson learns about object literal expansion and new template strings in ES6

Part 1: Object Literal Expansion

1. Concise writing

  ES6 provides a shorthand for object literal properties.

  1.1: Property Shorthand

        // traditional writing 
        var x = 2, y = 3 ,
            o = {
                x: x,
                and: and
            };

        // ES6 succinct notation 
        var x = 2, y = 3 ,
            o = {
                x,   //When the attribute name is the same as the assignment variable name, 
                y can be abbreviated
            };

  1.2: Method shorthand

        // traditional writing 
        var o = {
            x: function() {
                //...
            },
            y: function() {
                //...
            }
        }

        // ES6 succinct notation 
        var o = {
            x() {
                //...
            },
            and() {
                //...
            }
        }

  1.3 Limitations of the concise approach

  Analyze whether the following code can be refactored in a concise way:

        function runSomething(o) {
            var x = Math.random(),
                y = Math.random();
             return o.something(x, y);    // call property method through o 
        }

        runSomething({
            something: function something(x, y) {
                 if (x > y) {
                     return something(y, x)   // recursively call something() when the condition is not met 
                }
                 return y - x;
            }
        });

  Here the 'something:' attribute and function something() have their own purposes, the attribute something can be called through the o object, and the function something() is called inside itself for recursive implementation .

  Analysis 1: Implement recursion through obj.something() inside the obj object .

        function runSomething(o) {
            var x = Math.random(),
                y = Math.random();
             return o.something(x, y);    // call property method through o 
        }
         var obj = {
            something: function (x, y) {
                 if (x > y) {
                     return obj.something(y, x)   // here we call functiong with obj 
                }
                 return y - x;
            }
        };
        runSomething(obj);

  If the reference point of the obj object does not change , then this is a good way. But we can't control the point of obj .

  Analysis 2: Use this to call the something() method in obj

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

  The this here is the same as the problem in Analysis 1. We cannot guarantee that the something() method is always called by obj , so there will be a binding trap of this. Maybe this does not represent obj itself.

  For example: btn.addEventListener("click", obj.something, false); At this time, this is no longer the obj object itself. Some people may say that you can use obj.something.bind(obj) to bind it back, which is so troublesome There is no need.

  Back to our original 1.3 question:

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

  Here, something in function something() always points to the something() function itself, providing us with a reference for recursion/event binding/unbinding, not entangled with this nor unreliable objects Quote.

  Syntax simplification using ES6:

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

  You can see that the code reports an error , because something(x, y) will be interpreted as: something:function(x, y){...} , so the something method in return is undefined.

Summary: Concise methods are convenient, but should only be used when you don't need them to perform recursion/event binding/unbinding. Otherwise we should still use the traditional way of something: function something(){...}.

  1.4 Computed property names

  Computed property names: One or more property names in an object are computed from an expression.

        var prefix = "user_";
        var o = {
            baz: function () {
                //...
            }
        };
        o[prefix + 'foo'] = function () {    // Any legal expression can be placed in [] 
            // ... 
        }
        o[prefix + 'bar'] = function () {
            // ...
        }

  Computed property names can also appear as concise method names:

        var o = {
            [ "f" + "oo"]() {     // appears as a concise method name 
                // ... 
            }
        }

Part 2: Template Strings

  1. ES6 introduces a new string literal that uses ` as a delimiter. Such string literals support embedding basic string insertion expressions , which will be automatically parsed and evaluated.

  1.1 The traditional way of splicing strings:

        var name = "Kyle" ;
         var greeting = "Hello " + name + "!";    // Use the traditional '+' concatenated string 
        console.log(greeting);
        console.log(typeof greeting);

  1.2 ES6 template string concatenation:

        var name = "Kyle" ;
         var greeting = `Hello${name}!`;    // Using a template string, ${} can take values ​​to variables. 
        console.log(greeting);
        console.log(typeof greeting);

  Characters wrapped with `` are interpreted as a string literal, where expressions of the form ${} are immediately parsed and evaluated online.

  1.3 One advantage of string literals is that strings can be spread over multiple lines :

        // spaces and newlines in text will be saved 
        var text = `
            Now is the time for all good men
            to come to the aid of their
            country!
        `;
        console.log(text);

  2. Insert the expression ${}

  2.1 Any legal expression can appear in an inserted expression , including function calls, online function expression calls, and even other inserted string literals!

        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 Insert Expression Scope

        function foo(str){
            var name = "foo";
            console.log(str);
        }
        function bar(){
            var name = "bar";
            foo(`Hello from ${name} ! `); //The name here is the name in the scope where ${name} appears
        }
        var name = "global";
        bar();              // Hello from bar

  Inserting a string literal is within the lexical scope in which it appears, without any form of dynamic scoping.

  2.3 Label template literals

  This new function is not easy to explain, and it is more intuitive to go directly to the code:

        function foo(strings, ...values){
            console.log(strings);        // The output is an array, ['Everything is', '!'] 
            console.log(values);         // The output is an array, ['awesome'] 
        }
         var desc = 'awesome' ;
        foo `Everything is ${desc}!`;

  What is foo`Everything...` in the above example? In fact, this is a special function call that does not require (...), and the label, that is, the foo part, is a function value to be called. Can be any expression that results in a function.

        function bar() {
            return function foo(strings, ...values){
                console.log(strings);       //['Everything is', '!']
                console.log(values);        // ['awesome']
            }
        }
        var desc = "awesome";
        bar()`Everything is ${desc}`;    // the result of bar() is a function

  Analysis: The first parameter strings is an array of all ordinary strings.

       The second parameter values ​​receives the result value computed by the insertion expression ${}.

  Application: Number formatting to dollar notation

        function bar(strings, ...values) {
             return strings.reduce( function (s, v, idx){   // s represents the return value of the previous call, v represents the current element 
                if (idx > 0 ){
                     if ( typeof values[idx - 1] == 'number' ){
                        s += `$${values[idx - 1].toFixed(2)}`;   // If it is a number, splice it with a '$' symbol. 
                    } else {
                        s += values[idx - 1]
                    }
                }
                return s + v;
            }, "");      // "" as the value of the first parameter of the first call to 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)

  If a number value is encountered in values, splice '$' before it, and then use toFixed(2) to retain two decimal places.

  2.4 Raw Strings

  ES6 provides a built-in function that can be used as a string literal label: String.raw(...). Get the string raw value.

        // The result is 'Hello 
        // World' 
        console.log('Hello\nWorld!' );
        console.log(String.raw`Hello\nWorld !`); // The result is 'Hello\nWorld'

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325404529&siteId=291194637