Part1 Handwritten Code
On-site handwritten code is a very common type of interview questions in interviews nowadays, examining basic data structures and algorithm capabilities.
1. Implementation of array deduplication
Basic array deduplication
Array.prototype.unique = function(){ var result = []; this.forEach(function(v){ if(result.indexOf(v) < 0){ result.push(v); } }); return result;}•Use the hash table to deduplicate, this is a way to exchange space for time
Array.prototype.unique = function(){ var result = [],hash = {}; this.forEach(function(v){ if(!hash[v]){ hash[v] = true; result.push(v); } }); return result;}There is a bug in the above method. For arrays [1,2,'1','2',3], the deduplication result is [1,2,3]. The reason is that the object will cast the attribute index when the object indexes. Arr['1'] and arr[1] both get the values of arr[1], so some changes need to be made:
Array.prototype.unique = function(){ var result = [],hash = {}; this.forEach(function(v){ var type = typeof(v); //Get element type hash[v] || (hash[v] = new Array()); if(hash[v].indexOf(type) < 0){ hash[v].push(type); //Storage type result.push(v); } }); return result;}•Sort first and then remove the repetition
Array.prototype.unique = function(){ var result = [this[0]]; this.sort(); this.forEach(function(v){ v != result[result.length - 1] && result.push(v); //Compare only with the last element of result});}2 Quick sorting implementation
Method 1 (do not use js array method as much as possible):
function quickSort(arr){ qSort(arr,0,arr.length - 1);}function qSort(arr,low,high){ if(low < high){ var partKey = partition(arr,low,high); qSort(arr,low, partKey - 1); qSort(arr,partKey + 1,high); }}function partition(arr,low,high){ var key = arr[low]; //Use the first element as the classification basis while(low < high){ while(low < high && arr[high] >= arr[key]) high--; arr[low] = arr[high]; while(low < high && arr[low] <= arr[key]) low++; arr[high] = arr[low]; } arr[low] = key; return low;}Method 2 (using js array method):
function quickSort(arr){ if(arr.length <= 1) return arr; var index = Math.floor(arr.length/2); var key = arr.splice(index,1)[0]; var left = [],right = []; arr.forEach(function(v){ v <= key ? left.push(v) : right.push(v); }); return quickSort(left).concat([key],quickSort(right));}In addition, it should be noted that the average time complexity of quick sort O(nlogn), the worst case is an orderly case, the time complexity is squared n, and the quick sorting is unstable.
Part2 JavaScript related
1 JavaScript basic data types
JavaScript data types include primitive types and reference types, and there are five primitive types:
Number (value) String (string) Boolean (boolean) Null (empty) Undefined (undefined)
There is a reference type:
Object(Object)
Through typeof(x), you can return the data types "number", "string", "boolean", "undefined", and "object" of a variable x. One thing to note here: the typeof operator returns object for null types.
"JavaScript Advanced Programming":
This is actually a bug in the initial implementation of JavaScript, which was later used by ECMAScript. Null is now considered a placeholder for the object, thus explaining this contradiction. But technically it's still the original value.
2 Talk about JavaScript scope chain
When executing a piece of JavaScript code (global code or function), the JavaScript engine will create a scope for it, also known as the Execution Context. After the page is loaded, a global scope will be created first, and then each function will be executed, a corresponding scope will be established, thus forming a scope chain. Each scope has a corresponding scope chain, the head of the chain is the global scope, and the tail of the chain is the current function scope.
The purpose of the scope chain is to parse identifiers. When the function is created (not executed), this, arguments, named parameters and all local variables in the function will be added to the current scope. When JavaScript needs to find the variable X (this process is called variable resolution), it will first search for whether there is an X attribute from the end of the chain in the scope chain, that is, the current scope. If it is not found, continue to search along the scope chain until the chain head, that is, the global scope chain, and the variable is not found, it is believed that there is no x variable on the scope chain of this code, and a reference error (ReferenceError) exception is thrown.
3 How to understand JavaScript prototype chain
Each object in JavaScript has a prototype attribute, which we call it a prototype, and the value of the prototype is also an object, so it also has its own prototype, which connects a prototype chain. The header of the prototype chain is object, and its prototype is relatively special, with a value of null.
The function of the prototype chain is used for object inheritance. The prototype property of function A is an object. When this function is used as a constructor to create an instance, the prototype property of the function will be assigned to all object instances as a prototype. For example, if we create a new array, the array method will be inherited from the prototype of the array.
When accessing an attribute of an object, first look for the object itself, and return if it is found; if it is not found, continue to look for the properties of its prototype object (if it is still not found, it will actually search upward along the prototype chain until the root). As long as it is not overwritten, the properties of the object prototype can be found in all instances, and if the entire prototype chain is not found, it will return undefined;
4 JavaScript variable declaration in advance
The authoritative guide to JavaScript explains this: JavaScript variables are available before declaration, and this feature of JavaScript is informally called hoisting, that is, all variables declared in JavaScript functions (but not involve assignments) are "advanced" to the top of the function.
From an example:
var scope = "global";function myFunc(){ console.log(scope); var scope = "local";}What the console prints out is not "global" but "undefined". This is because in the scope of the function myFunc, the local variable scope declaration is advanced to the top of the function. At this time, scope only declares and does not assign values, so the output is undefined. In fact, the above code is the same as the following:
var scope = "global";function myFunc(){ var scope; console.log(scope); scope = "local";}5 How to understand and apply JavaScript closures
The concepts given in the literature on the specific definition of closures are very abstract. I think closures are a syntax mechanism that enables functions to all local variables of other functions.
For example:
function outFunc(){ var name = "Vicfeel"; function inFunc(){ console.log(name); } return inFunc;}inFunc(); //Console displays "Vicfeel"We can see this example that the local variable name of outFunc can still be accessed in the function inFunc.
Closure application examples, simulates the private properties of a class. Taking advantage of the properties of the closure, local variables can only be accessed in the sayAge method, and name is also accessed externally, thus implementing the private properties of the class.
function User(){ this.name = "Vicfeel"; //The total attribute var age = 23; //Private attribute this.sayAge:function(){ console.log("my age is " + age); } } var user = new User(); console.log(user.name); //"Vicfeel" console.log(user.age); //"undefined" user.sayAge(); //"my age is 23"To learn more about closures, I recommend Ruan Yifeng's network log - Learn Javascript closure (Closure).
6 The essence of new construction object
function User(){this.name = "Vicfeel";this.age = 23;}var user = new User();Through the new operator, the following operations are actually completed in the constructor User:
• Create a new object whose type is object;
• Set the internal, accessible and prototype properties of this new object as set in the constructor (referring to the constructor pointed to by prototype.construtor);
•Execute constructor;
•Returns the newly created object.
function User(){ //this = {}; //this.constructor = User; this.name = "Vicfeel"; this.age = 23; //return this; } var user = new User();If the constructor returns a newly created this object by default, if a variable is manually returned, it is invalid if the variable is of the original type, and if it is an object, it is returned.
7 JavaScript Agent
When we need to add events to many elements, we can trigger the processing function by adding events to their parent node and delegating events to the parent node.
For example, we need to dynamically add many li to an ul, and we need to traverse li to add click events one by one.
<ul id='list'></ul> var count = 100; var ulList = document.getElementById("list"); //Dynamic construction node for(var i = count;i--;){ var liDom = document.createElement('li'); ulList.appendChild(liDom); } //Binding click event var liNode = ulList.getElementByTagName("li"); for(var i=0, l = liNodes.length; i < l; i++){ liNode[i].onClick = function(){ //li click event} }As we all know, DOM operations are very performance-consuming. So repeated event binding is simply a performance killer. The core idea of event proxy is to listen to as many events as possible through as few bindings as possible. How to do it? The answer is to use the event bubble mechanism to bind the parent node ul (Event Bubble), and then use event.target to determine which node triggers the event, thereby reducing the binding of many EventHandlers.
var count = 100; var ulList = document.getElementById("list"); //Dynamic construction node for(var i = count;i--;){ var liDom = document.createElement('li'); ulList.appendChild(liDom); } //Binding click event var liNode = ulList.getElementByTagName("li"); liNode.onClick = function(e){ if(e.target && e.target.nodeName.toUpperCase == "LI") { // li click event} }New content will be updated continuously...