functionFoo() { getName = function () { console.log(1); }; // console.log("this is" + this); returnthis; } Foo.getName = function () { console.log(2); }; Foo.prototype.getName = function () { console.log("baidu" && "google"); }; var getName = function () { console.log(4); }; functiongetName() { console.log(5); }
Foo.getName(); getName(); Foo().getName(); getName(); new Foo.getName(); new Foo().getName(); newnew Foo().getName();
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// 2 Foo.getName(); // 4 Both var and function declaration are promoted, andt the function is overwritten before the variable is promted. getName(); // 1 Foo().getName(); // 1 Foo() return this is window, widown.getName has been rewritten. getName(); // 2 According the rule, it's the same as new (Foo.getName)(), so the answer is 2. [Foo.getName() --> new] new Foo.getName(); // google (new Foo()).getName(), the Foo object constructor does not have getName, find it in prototype object. [Foo.getName --> Foo.prototype.getName] new Foo().getName(); // google new((new Foo()).getName)() newnew Foo().getName();
Tips
Operator precedence
For ‘&&’, if the former is true, then execute the latter, otherwish only execute the former. For ‘||’, if the former is true, only execute the former, the latter don’t have to execute, otherwish have to execute the latter.
// ... // This method only expend one layer. const flatten1 = (arr) => { return [].concat(...arr); };
// join and split // This method will involve implicit conversion, some values will be affected like undefined, null,etc. const flatten2 = (arr) => { return arr.join(",").split(","); };
// toString and split // This method will involve implicit conversion, some values will be affected like undefined, null,etc. const flatten3 = (arr) => { return arr.toString().split(","); };
// Recursion and reduce const flatten4 = (arr) => { return arr.reduce((pre, cur) => { // we can filter some unwanted values. if (cur === undefined || cur === null) { return pre; } returnArray.isArray(cur) ? pre.concat(flatten4(cur)) : pre.concat(cur); }, []); };
// ES6 const flatten5 = (arr) => { // es6 flat method only expand one layer by default // return arr.flat() return arr.flat(Infinity); };
Currying can convert a multi-argument function to a single-argument function and return a new function which can take the remaining arguments and return a result.
// Recursion const deepCopy = (val) => { let newObj; if (typeof val === "object") { if (Array.isArray(val)) { newObj = []; for (let i of val) { newObj.push(deepCopy(i)); } } elseif (val === null) { return val; } elseif (val.constructor === RegExp) { return val; } else { newObj = {}; for (let i in val) { newObj[i] = deepCopy(val[i]); } } } else { // It isn't an object return val; }
return newObj; };
// Object.assign is shallow copy, but the target is a new Object. const deepCopy1 = (val) => { returnObject.assign({}, val); };
// This can't copy the undefined, function and RegExp etc // if the value is null, it will report the error. const deepCopy2 = (val) => { returnJSON.parse(JSON.stringify(val)); };
-------------The end of this article, thanks for reading-------------