preface

This paper is some error-prone knowledge points collected and sorted out in the process of learning JavaScript. It will introduce and explain the six aspects of variable scope, type comparison, this pointing, function parameters, closure problems and object copy and assignment from simple to profound, and some ES6 knowledge points are also involved.

JavaScript knowledge

1. Variable scope

var a = 1;
function test() {
    var a = 2;

    console.log(a); / / 2
}

test();Copy the code

A is declared and assigned in the upper function scope and is on the console, so follow the nearest rule to print a equal to 2.

var a = 1;
function test2() {
    console.log(a); // undefined

    var a = 2;
}

test2();Copy the code

The upper function scope is declared and assigned to a, but it is under the console. The variable a is promoted. The output is declared but not yet assigned, so the output is “undefined”.

var a = 1;
function test3() {
    console.log(a); / / 1

    a = 2;
}

test3();Copy the code

The function scope a above is reassigned, undeclared, and under console, so output a in the global scope.

let b = 1;
function test4() {
    console.log(b); // b is not defined

    let b = 2;
}

test4();Copy the code

In the function scope above, let of ES6 is used to re-declare variable B. However, unlike var, let does not have the function of variable promotion, so the output error “B is not defined” is reported.

function test5() {
    let a = 1;

    {
        let a = 2;
    }

    console.log(a); / / 1
}

test5();Copy the code

The function scope above declares a to be 1 with let, and the block-level scope above declares a to be 2. Since console is not in the block-level scope inside the function, output 1.

2. Type comparison

var arr = [],
    arr2 = [1];

console.log(arr === arr2); // falseCopy the code

Compare two different arrays above with console false.

var arr = [],
    arr2 = [];

console.log(arr === arr2); // falseCopy the code

Compare two identical arrays at the top, and since two separate arrays are never equal, console is false.

var arr = [],
    arr2 = {};

console.log(typeof(arr) === typeof(arr2)); // trueCopy the code

Console is true because typeof retrieves NULL, array, and object types.

var arr = [];

console.log(arr instanceof Object); // true
console.log(arr instanceof Array); // trueCopy the code

The above uses instanceof to determine if a variable is an instanceof an object. Since arrays are a type of object in JavaScript, both consoles are true.

3. This point

var obj = {
    name: 'xiaoming'.getName: function () {
        return this.name
    }
};

console.log(obj.getName());  // 'xiaoming'Copy the code

This in the upper object method refers to the object itself, so “xiaoming” is printed.

var obj = {
    myName: 'xiaoming'.getName: function () {
        return this.myName
    }
};

var nameFn = obj.getName;

console.log(nameFn()); // undefinedCopy the code

This will no longer point to the obj object, so it will point to the window object, so console will be “undefined”.

var obj = {
    myName: 'xiaoming'.getName: function () {
        return this.myName
    }
};

var obj2 = {
    myName: 'xiaohua'
};

var nameFn = obj.getName;

console.log(nameFn.apply(obj2)); // 'xiaohua'Copy the code

The above also assigns the method in obj to the variable nameFn, but the apply method points this to obj2, so the final console is ‘xiaohua’.

4. Function parameters

function test6() {
    console.log(Array.prototype.slice.call(arguments)); / / [1, 2]
}

test6(1.2);Copy the code

The arguments class shu’zu object is used to get the array of arguments passed to the function.

function test7 () {
    return function () {
        console.log(Array.prototype.slice.call(arguments)); // There is no output
    }
}

test7(1.2);Copy the code

Return test7(1, 2)(3, 4); return test7(1, 2)(3, 4);

var args = [1.2];

function test9() {
    console.log(Array.prototype.slice.call(arguments)); // [1, 2, 3, 4]
}

Array.prototype.push.call(args, 3.4); test9(... args);Copy the code

Using the above Array. Prototype. Push. The call () method to insert the 3 and 4, the args Array and use the ES6 extension operators (…) Expand the array and pass it to test9, so console is [1, 2, 3, 4].

5. Closure issues

var elem = document.getElementsByTagName('div'); If there are five divs on the page

for(var i = 0; i < elem.length; i++) {
    elem[i].onclick = function () {
        alert(i); / / always 5
    };
}Copy the code

Here’s a common closure problem: Clicking on any div will always bring up a value of 5, because when you trigger the click event I will already be 5.

var elem = document.getElementsByTagName('div'); If there are five divs on the page

for(var i = 0; i < elem.length; i++) {
    (function (w) {
        elem[w].onclick = function () {
            alert(w); // 0,1,2,3,4
        };
    })(i);
}Copy the code

Just wrap an immediate function around the bind click event and pass I to the function.

6. Object copy and assignment

var obj = {
    name: 'xiaoming'.age: 23
};

var newObj = obj;

newObj.name = 'xiaohua';

console.log(obj.name); // 'xiaohua'
console.log(newObj.name); // 'xiaohua'Copy the code

Above we assign the obj object to newObj to change the name property of newObj, but the name property of obj is also tampered with. This is because newObj actually gets a memory address, not a true copy, so the OBj object is tampered with.

var obj2 = {
    name: 'xiaoming'.age: 23
};

var newObj2 = Object.assign({}, obj2, {color: 'blue'});

newObj2.name = 'xiaohua';

console.log(obj2.name); // 'xiaoming'
console.log(newObj2.name); // 'xiaohua'
console.log(newObj2.color); // 'blue'Copy the code

The Object. Assign () method is used to make a deep copy of the Object to avoid tampering with the source Object. The object.assign () method can copy any number of source objects’ own enumerable properties to the target Object and then return the target Object. However, object.assign () is only a level 1 copy of attributes, which is one layer deeper than the shallow copy.

var obj3 = {
    name: 'xiaoming'.age: 23
};

var newObj3 = Object.create(obj3);

newObj3.name = 'xiaohua';

console.log(obj3.name); // 'xiaoming'
console.log(newObj3.name); // 'xiaohua'Copy the code

We can also copy objects using the object.create () method, which creates a new Object with the specified prototype Object and properties.

conclusion

Learning JavaScript is a long process, not overnight. I hope this article introduces some content can help students learn JavaScript more in-depth understanding and master JavaScript syntax, less detours.

At the same time, welcome to follow my wechat official account: Love-Fed, to talk about front-end things.