In the autumn of 2019
I have passed the interview, which lasted for 30 minutes. The position is Web front-end development engineer
The following are specific interview questions:
To introduce myself
Q: When did the front end start to learn?
Q: Are you still doing your internship?
Q: Front-end learning?
Q: what front-end books have you read?
The way JavaScript judges arrays
arr instanceof Array
arr.constructor == Array
arr.__proto__ == Array.prototype
Object.prototype.toString.call(arr) == '[object Array]'
Array.isArray(arr)
- Supplement not available
typeof arr
Because this method returns an object for both arrays and objects
A method for deeply copying objects
JSON.parse(JSON.stringify(obj))
- A recursive copy
function deepClone(obj) {
let cloneObj = {}; // Create a new object in heap memoryfor(let key inObj){// Iterate over the argument's keyif(typeof obj[key] ==='object') {cloneObj[key] = deepClone(Obj[key])else{
cloneObj[key] = Obj[key] // Basic type direct copy value}}return cloneObj
}
Copy the code
If the object/array has only one level
If the element of the object/array is of primitive type, then deep copy can be implemented. If the element of the reference type is of reference type, then no deep copy can be implemented. Changing the value of the reference type changes both the copied and copied objects.
Object.assign(newobj,obj)
let cloneObj = { ... obj };
let cloneArr = oldArr.slice(0)
Supplement:
let target = {};
let source = { a: { b: 2 } };
Object.assign(target, source);
console.log(target); // { a: { b: 10 } };
source.a.b = 10;
console.log(source); // { a: { b: 10 } }; console.log(target); // { a: { b: 10 } }; The target is still related to sourse because it contains a reference element. Console. log looks up the value from memory and changes the object element {b: 2} in memory. The console starts with {a: {... }} This process is from the memory of the value of the process, not equivalent to photography (fixed instant state)Copy the code
Defines non-modifiable properties of an object
Object.defineProperty()
Object.defineproperty descriptor {writable:falseDefineProperty (objName, works without any additional information), // Works without any additional information."name", {writable: false, value: "zhangSan"});
Copy the code
- The singleton pattern
// Anonymous function + execute immediately + return object + closure var obj =function(){// Define private attributes and methodsreturn{// Common attributes and methods}}()Copy the code
-
Object.freeze(obj)
After using this method, you cannot add or delete attributes to an object, nor can you make changes to existing attributes.
However, you can override the object completely, as obj = newObj
Purpose:
Consider a scenario where we write a JS in which we define an object that will be open for use by third parties. If you want to make this object safe for use by third parties, you need to avoid the object being “hook”, that is, avoid the object being overwritten. For example, reassigning an object property to a function with malicious code.
What is a closure
A function that has access to variables and methods inside another function.
It’s too basic to expand.
Add a scroll event to the scroll bar, which is triggered once every 1 second to avoid frequent operations
Look at throttling and anti-shaking
Debounce
The so-called shaking prevention means that the function can only be executed once within n seconds after the event is triggered. If the event is triggered again within N seconds, the function execution time will be recalculated.
function debounce(func, wait) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args)
}, wait); }}Copy the code
Throttle
Throttling refers to firing events continuously but executing the function only once in n seconds. Throttling dilutes the execution frequency of the function.
function throttle(func, wait) {
let timeout;
return function() {
let context = this;
let args = arguments;
if(! timeout) { timeout =setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)}}}Copy the code
Supplement:
In fact, there are throttling and anti-shake also divided into immediate execution and non-immediate execution, throttling also divided into timestamp version and timer version
See function throttling and stabilization for details
How to bind events to the LI label under UL
With event delegate, the outer UL is bound to the event. According to the principle of event bubble, the inner LI is also bound. The advantage is that if there are more li tags, there is no need to repeat the binding, and it saves more resources than traversing binding
You can also specify a tag to respond to the event via e.target.nodename
window.onload = function(){
var oUl = document.getElementById("ul1");
oUl.onclick = function(ev){
var ev = ev || window.event;
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase() == 'li'){ alert(123); alert(target.innerHTML); }}}Copy the code
How to use token to defend against CSRF attack
My answer:
Since the CSRF attack cannot obtain the contents of the form, the token is placed in the form of the POST request, and the server verifies whether the user is a real user based on the token in the form.
Authoritative information:
Cross-site Request Forgery (CSRF) Cross-site request forgery
The attacker lures the victim to a third-party site, where a cross-site request is sent to the targeted site. Using the victim in the attacked website has obtained the registration certificate, bypassing the background user authentication, to impersonate the user to perform a certain operation on the attacked website.
Prevention Strategy:
-
Homology detection.
According to the Origin and Referer of the request header, determine whether the request is initiated by a trusted domain name. If not, block it; if not, block it directly
-
CSRF Token
How it works: Make requests carry a Token that a CSRF attacker cannot obtain. By verifying whether the request carries the correct Token, the server can distinguish the normal request from the attack request and defend against CSRF attacks.
Specific operations: when the user logs in, a Token value is generated according to the user name and password encryption, and written into the Cookie and Hidden of the browser at the same time. Then, according to each request, the Token and Cookie are brought to the server for verification and judgment.
Front-end real-time update
- With the Meta tag Refresh, set how long it takes the front end to update the server
setInternal(func, 1000)
- Used after a successful Ajax request
setTimeout()
Recursively invoke ajax requests - web Socket
NetWork analysis of the browser console causes slow loading
I often check the request header and the response header. I just say I don’t know anything about it.
Have you analyzed the site’s performance, such as the Performance tool
Window. The performance. Timing holds various time
Added front-end performance: white screen time, first screen time
See my other blog post for more details: Front-end performance monitoring solutions (first screen, white screen time, etc.)
Differences between COMPUTED and Watch in Vue and application scenarios
Computed attribute computed
Getter methods are defined by default. Setter methods can also be set, which saves more performance than method methods
Listener watch
If it changes, the callback function is called
The way Vue sibling components communicate
Basic things, see Vue official website
Have you used vue-Router before
Well, I can’t remember that, so I said no
How does bubble sort sort
Elements are compared in pairs, finding the largest or smallest element in each iteration
function bubbleSort(arr) {
var len = arr.length;
for (var i = 0; i < len - 1; i++) {
for (var j = 0; j < len - 1 - i; j++) {
ifArr [j] > ARr [j+1]) {var temp = ARr [j+1]; // Element Exchange ArR [J]; arr[j] = temp; }}}return arr;
}
Copy the code
Quick sort
First use the first element as the middle value, the smaller elements are put in front, the larger elements are put behind, then the array is divided into two groups after a traversal, continue to divide each group with the same method until the sorting is completed.
functionquickSort(arr, left, right) { var len = arr.length, partitionIndex, left = typeof left ! ='number'? 0 : left, right = typeof right ! ='number' ? len - 1 : right;
if (left < right) {
partitionIndex = partition(arr, left, right);
quickSort(arr, left, partitionIndex-1);
quickSort(arr, partitionIndex+1, right);
}
return arr;
}
functionPartition (arr, left, right) {if (arr, left, right) {if (arr, left, right) {if (arr, left, right) {if (arr, left, right);for (var i = index; i <= right; i++) {
if (arr[i] < arr[pivot]) {
swap(arr, i, index);
index++;
}
}
swap(arr, pivot, index - 1);
return index-1;
}
function swap(arr, i, j) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function partition2(arr, low, high) {
let pivot = arr[low];
while (low < high) {
while (low < high && arr[high] > pivot) {
--high;
}
arr[low] = arr[high];
while (low < high && arr[low] <= pivot) {
++low;
}
arr[high] = arr[low];
}
arr[low] = pivot;
return low;
}
function quickSort2(arr, low, high) {
if (low < high) {
let pivot = partition2(arr, low, high);
quickSort2(arr, low, pivot - 1);
quickSort2(arr, pivot + 1, high);
}
return arr;
}
Copy the code
A 300-wide div contains two 200-wide divs. How do I keep one constant and the other 100 wide
With flex layout, set flex: 1 to the second div
Have you ever written a blog
There are