14, Ternary operator, object cloning, shallow copy, deep copy, modular review

14, Ternary operator, object cloning, shallow copy, deep copy, modular review

1, Ternary operator

It is also called ternary operator, which is equivalent to the three segment expression of if:

var a = 5;
if(a > 0){
    console.log('Greater than 0');
}else{
    console.log('Less than or equal to 0');
}

a > 0 ? console.log('Greater than 0') //Equivalent to three-stage if
      :console.log('Less than or equal to 0');

1.1 characteristics of ternary operator

You can use a variable to receive the result of the ternary operation, that is, the ternary operation will return the result by default.

var a = 5;
var str = a > 0 ? 'Greater than 0' //This is equivalent to a return here
				: 'Less than or equal to 0';

console.log(str); // 'greater than 0'

If can be nested in if judgment. Of course, ternary operations can also be nested in ternary operations:

var a = 3,
    str = '';
if(a > 0){
    if(a > 3){
        str = 'Greater than 3';
    }else{
        str = 'Greater than 0 and less than or equal to 3';
    }
}else{
    str = 'Less than or equal to 0';
}
console.log(str); //'greater than 0 and less than or equal to 3'

Use the ternary operator to judge:

str = a > 0 ? (
    			a > 3 ? 'Greater than 3' 
                      : 'Greater than 0 and less than or equal to 3'
			  )
            : 'Less than or equal to 0';
console.log(str); //'greater than 0 and less than or equal to 3'

An interview question about three purposes:

var str = 89 > 9 ?(
                    '89' > '9' ? 'Yes'
                               : 'Failed'
                  )
                 : 'The outer layer passed';
console.log(str);

Console output 'failed'.

89 > 9, the result is true, and the three item operation before the colon is nested; When both sides of the comparison operator are strings, compare the character coded ASCII values one by one from the first character; If the ASCII code value of character 8 is less than that of character 9, the comparison ends, it is judged as false, and the result after the colon is returned, that is, 'failed'.

2, Object cloning

Leading knowledge:

Objects created in literal form are actually created by new Object()

——>So the literal object__ proto__ Points to 0bject prototype

——>0bject. Prototype is the prototype object of all objects (non custom prototype)

——>All objects inherit 0bject Properties on Prototype

2.1 shallow copy

Use for in to traverse the object and copy all the properties in one object to another new object.

However, when for in traverses an object, the custom attributes on the prototype chain of the object will also be copied to the new object. What should I do?

Use hasOwnProperty to select only the properties of the source object itself.

Object.prototype.num = 1;
var person1 = {
    name: 'white',
    age: 22,
    friends: {
        first: 'jack',
        second: 'perter',
        third: 'rose'
    } 
}
var person2 = {};
for(key in person1){
    if(person1.hasOwnProperty(key)){
        person2[key] = person1[key]
    }
}
console.log(person1);
console.log(person2);

As like as two peas, the new object is identical to the source object.

Shallow copy process code can be encapsulated:

var person2 = clone(person1, person2);
function clone(origin, target){
    var target = target || {}; //Improve user experience
    for(key in origin){
        if(origin.hasOwnProperty(key)){
            target[key] = origin[key]
        }
    }
    return target;
}

Add an attribute to our new object with the type of original value;

Add a new attribute to the reference value of the new object:

person2.height = 180;
person2.friends.forth = 'ning';
console.log(person1);
console.log(person2);

Print source and new objects:

Shortage of shallow copy:

After shallow copy, change the attribute of the new object. When the attribute value is the reference value, the corresponding reference value of the source object will be changed at the same time. The new object is associated with the source object!

2.2 deep copy

Solve the problem of shallow copy, so that the cloned new object has no relationship with the source object, and the addition, deletion, modification and query of the reference value of the new object will not affect the source object.

Deep copy can also encapsulate the copy process.

The deep copy process is as follows:

// When you copy objects, you copy arrays or objects
Object.prototype.num = 1;
var person1 = {
    name: 'white',
    age: 22,
    friends: {
        first: {
            name: 'jack',
            age: 22
        },
        second: {
            name: 'perter',
            age: 20
        },
        third: {
            name: 'rose',
            age: 33
        }
    },
    car: ['Benz', 'Mazda']
}

var person2 = deepClone(person1,person2);
person2.height = 180;
person2.friends.forth = {
    name: 'ning',
    age: 49
}
person2.car.push('audi');

console.log(person1,person2);

function deepClone(origin, target){
    var target = target || {};//User experience
    var toStr = Object.prototype.toString,//Cache method
        arrType = '[object Array]';

    for(var key in origin){
        // First judge that the object's own attributes are to be copied, not the custom attributes on the prototype chain
        if(origin.hasOwnProperty(key)){
            // Judge whether the attribute value data type is a reference value and the reference value is not equal to null
            if(typeof(origin[key]) === 'object' && origin[key] !== null){
                if(toStr.call(origin[key]) === arrType){
                    // If the reference value is an array, the properties of the new object are declared as an empty array
                    target[key] = [];
                }else{
                    // If the reference value is an object, the properties of the new object are declared as an empty object
                    target[key] = {};
                }
                // Recursion of the contents of the reference value
                deepClone(origin[key], target[key])
            }else{
                // Direct assignment is not a reference value
                target[key] = origin[key];
            }
        }
    }
    
    return target;
}

The new object after deep copy has nothing to do with the source object.

2.3 JSON deep copy (not recommended)

Use JSON Stringify turns the object into a string, and then uses JSON Parse turns a string into a JSON object.

Object.prototype.num = 1;
var person1 = {
    name: 'white',
    age: 22,
    friends: {
        first: {
            name: 'jack',
            age: 22
        },
        second: {
            name: 'perter',
            age: 20
        },
        third: {
            name: 'rose',
            age: 33
        }
    },
    car: ['Benz', 'Mazda']
}

var str = JSON.stringify(person1);
var person2 = JSON.parse(str);
person2.height = 180;
person2.friends.forth = {
    name: 'ning',
    age: 49
}
person2.car.push('audi');
console.log(person2,person1);

Three, modular review

3.1 collaborative operation

Each person creates a scope separately, saves the function returned by IIFE to the global variable and waits for execution.

The module written by each person is not executed immediately. It needs some conditions before execution;

The advantage of modularity is not only to prevent pollution of global variables and create independent space; And save the returned function to GO for execution.

/* Realize three functions:
 *Print a number within a parameter value that can be divided by 3 or 5 or 7
 *Print the nth bit of Fibonacci sequence
 *Print the cumulative value from 0 to a number 
 */

//After the window is executed, execute init

// If it is not written like this, it cannot be executed when init()
// Because the variable has not been assigned, the value is undefined. It becomes a function expression when the assignment is executed
window.onload = function(){
    init();
}
//  Initialization function
function init(){
    console.log(divided(50));
    console.log(fbnq(5));
    console.log(add(100));
}
//  IIFE + closure
// Print a number within a parameter value that can be divided by 3 or 5 or 7
var divided = (function(){
    return function(j){
        var arr = [];
        for(var i = 0; i <= j; i++){
            if( i % 3 == 0 || i % 5 == 0 || i % 7 == 0){
                arr.push(i);
            }
        }
        return arr;
    }
})();
// Print the nth bit of Fibonacci sequence
var fbnq = (function(){
    return function fn(n){
        if(n <= 0){
            return 0
        }
        if(n <= 2){
            return 1;
        }
        return fn(n-1) + fn(n-2);
    }
})();
// Print the cumulative value from 0 to a number 
var add = (function(){
    return function(n){
        var sum = 0;
        for(var i = 0; i <= n; i++){
            sum += i;
        }
        return sum;
    }
})();

3.2 plug in

Execute when it appears. For example, the carousel map plug-in is executed when the web page is opened.

Therefore, the standard form of plug-in is IIFE + constructor correlation + prototype + window exposed to global / received with global variables

Wait for global execution or let it execute directly.

;(function(){
    //Function declaration or function expression can be used
   var Test = function(){
       
   }
   Test.prototype = {
       
   }
    
   window.Test = Test;
})()

Summary: modularization focuses on saving the results returned by IIFE to GO for execution; The plug-in can be executed immediately to achieve the effect.

Keywords: Javascript ECMAScript

Added by Amtran on Wed, 05 Jan 2022 17:38:26 +0200