Golden three silver four job-hopping season, just encountered the epidemic help, I was also forced to participate in the interview army at the beginning of the year, in a week of the interview process met some more basic and high-frequency interview questions recorded

JSON.parse

Json.parse (json.stringify (obj)) is often used for deep copy and is easy to use, but most developers tend to ignore its problems when using it

  • The problem
  1. He cannot clone special objects such as functions, regexps, etc

  2. Discard constructor for objects; all constructors will point to objects

  3. Object with a circular reference

// The constructor
function person(pname) {
  this.name = pname;
}

const Messi = new person('Messi');  / / function function say() {  console.log('hi'); };  const oldObj = {  a: say,  b: new Array(1),  c: new RegExp('ab+c'.'i'),  d: Messi };  const newObj = JSON.parse(JSON.stringify(oldObj));  // The function cannot be copied console.log(newObj.a, oldObj.a); // undefined [Function: say] // Sparse array copy error console.log(newObj.b[0], oldObj.b[0]); // null undefined // Unable to copy the regular object console.log(newObj.c, oldObj.c); // {} /ab+c/i // The constructor points to an error console.log(newObj.d.constructor, oldObj.d.constructor); // [Function: Object] [Function: person] Copy the code

apply

Apply’s role is to modify the current execution context of the calling function. On the basis of understanding its role, think about the general idea of simulating apply, which is more helpful for personal growth. Do not rote some code fragments when you do not understand

Function.prototype._apply = function (targetObject, argsArray) {
  // If it is not passed, it is set to an empty array
  if(typeof argsArray === 'undefined' || argsArray === null) {
    argsArray = []
  }
  // Whether to pass the execution context. If not specified, point to window  if(typeof targetObject === 'undefined' || targetObject === null) { targetObject = window  }   // Use Symbol to set key  const targetFnKey = Symbol('key')  // Assign a value to the function called _apply  targetObject[targetFnKey] = this  // Execute the function and return after deletion  constresult = targetObject[targetFnKey](... argsArray) delete targetObject[targetFnKey]  return result } Copy the code

Use Symbol as key to prevent duplication. For example, the targetFnKey is set to CB. When the incoming targetObject has a cb method, it will be deleted after execution, causing problems

new

  • Implementation process
    1. Create an empty object as the object instance to be returned
    2. Point the empty object’s prototype to the constructor’s prototype property
    3. Assign the empty object to this inside the function
    4. Execute constructor internal code
function _new(/* Constructor */ constructor, /* Constructor argument */ params) {
  // Convert arguments to an array
  var args = [].slice.call(arguments);
  // Fetch the constructor
  var constructor = args.shift();
// Create an empty object that inherits the constructor's prototype property var context = Object.create(constructor.prototype); // Execute the constructor var result = constructor.apply(context, args); // If the result is an object, return it directly, otherwise return the context objectreturn (typeof result === 'object' && result ! = null) ? result : context;} Copy the code

In order to understand the principle of new, we need to add two small points

  1. New.target, which can be used inside a function, if the current function is called with new, then new.target refers to the current function, otherwise undefined
function NewTargetTest() {
  console.log(new.target === NewTargetTest)
}

NewTargetTest() // false
new NewTargetTest() // true Copy the code
  1. The constructor hides the return
  • The constructor returns the constructed this object by default
function ReturnTest(name) {
  this.name = name
}

const returnText = new ReturnTest('wy')
console.log(returnText.name) // wy Copy the code
  • Modifying the above code to show an empty object {} overwrites the default return of this
function ReturnTest(name) {
  this.name = name
  return {}
}

const returnText = new ReturnTest('wy') console.log(returnText.name) // undefined Copy the code
  • Tweaks the above code to show that it returns a primitive type of data will not affect the this object returned by the constructor
function ReturnTest(name) {
  this.name = name
  return 'test'
}

const returnText = new ReturnTest('wy') console.log(returnText.name) // wy Copy the code

Summary: In the constructor, if the display returns an object, the default this object is overridden, but the basic data type is not

The singleton pattern

The singleton pattern is a common design pattern. The singleton pattern ensures that a class has only one instance and provides a global access point, which can save memory very well. In JS, you can combine the mandatory package implementation

function Animal(name) {
  this.name = name
}

const AnimalSingle = (function () {
 let animalSingle = null   return function (name) {  if(animalSingle){  return animalSingle  }  return animalSingle = new Animal(name)  } }) (); const animal1 = new AnimalSingle('dog') const animal2 = new AnimalSingle('cat')  console.log(animal1.name); // dog console.log(animal2.name); // dog Copy the code

An Animal is instantiated only once, and each subsequent instance returns the first instance.

compose

Compose is one of the most important functions in functional programming and is widely used because of its clever design. For example, the compose function is used to compose functions, to concatenate them, to compose multiple functions, so that the output of one function is the input parameter of the other function, and once the first function starts executing, it’s going to start executing like a domino

  • Lodash version
var compose = function(funcs) {
    var length = funcs.length
    var index = length
    while (index--) {
        if (typeoffuncs[index] ! = ='function') {
 throw new TypeError('Expected a function');  }  }  return function(. args) {  var index = 0  var result = length ? funcs.reverse()[index].apply(this, args) : args[0]  while (++index < length) {  result = funcs[index].call(this, result)  }  return result  } } Copy the code
  • Version of the story
function compose(. funcs) {
    if (funcs.length === 0) {
        return arg= > arg
    }

 if (funcs.length === 1) {  return funcs[0]  }   return funcs.reduce((a, b) = > (. args) = >a(b(... args)))} Copy the code
  • The test code
function composeReduce1(arg) {
  console.log('composeReduce1', arg);
  return 'composeReduce1'
}
function composeReduce2(arg) {
 console.log('composeReduce2', arg);  return 'composeReduce2' } function composeReduce3(arg) {  console.log('composeReduce3',arg); }   // For the Lodash version, the compose parameter is an array [composeReduce1, composeReduce2, composeReduce3] let composeChild = compose(composeReduce1, composeReduce2, composeReduce3) composeChild('init')  / / output // composeReduce3 init // composeReduce2 composeReduce3 // composeReduce1 composeReduce2 Copy the code

Attributes read

Cannot read Property of undefined is a common error that will be reported if you accidentally get an empty object or value

  • The data structure
const obj = {
  user: {
      posts: [
          { title: 'Foo'.comments: [ 'Good one! '.'Interesting... ']},          { title: 'Bar'.comments: [ 'Ok']}, { title: 'Baz'.comments: []} ]. comments: []  } } Copy the code
  • The && short circuit operator performs accessibility sniffing
obj.user && obj.user.posts
Copy the code
  • try… catch
let result
try {
    result = obj.user.posts[0].comments
}
catch {
 result = null } Copy the code
  • Extraction method – Reduce
const getByReduce = (attrArr, resObj) = >{
  return  attrArr.reduce((res, key) = > {
    return (res && res[key]) ? res[key] : null
  }, resObj)
}
 console.log(getByReduce(['user'.'posts'.0.'comments'], obj)) // [ 'Good one!', 'Interesting...' ] console.log(getByReduce(['user'.'post'.0.'comments'], obj)) // null Copy the code
  • Extraction method – Kelsey
const getByCurry = attrArr= > {
  return resObj= > {
    return attrArr.reduce((res, key) = > {
      return res && res[key] ? res[key] : null;
    }, resObj);
 }; };  const getUserComments = getByCurry(['user'.'posts'.0.'comments']);  console.log(getUserComments(obj)); // [ 'Good one!', 'Interesting...' ] console.log(getUserComments({ user: { posts: []}}));// null Copy the code

The prototype of pollution

Stereotypes can be used to contaminate the patterns and properties above the stereotype chain

let person = {name: 'lucas'}

console.log(person.name)

person.__proto__.toString = (a)= > {alert('evil')}
 console.log(person.name)  let person2 = {}  console.log(person2.toString()) Copy the code
  • To solve
    • freezeObject.prototype, so that stereotypes cannot extend properties
    • meetconstructorAs well as__proto__Sensitive property to prevent its operation

JSONP

Implement a JSONP, although jSONP still has some usage scenarios, even though it can only support get type requests, but still need to understand the entire process

Take Baidu search as an example. When searching in Baidu, when the content of the input box changes, the keyword will be searched, which is realized through JSONP

function jsonp(url, callback, successCallback) {
  let script = document.createElement('script');
  script.src = url;
  script.async = true;
  script.type = 'text/javascript';
  window[callback] = function(data) {  successCallback && successCallback(data);  };   document.body.appendChild(script); }  jsonp(  'https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=1461, 21119185, 59295, 22297, 20295, 67, 29 221&wd=%E5%88%98%E5%BE%B7%E5%8D%8E%20&bs=%E5%88%98%E5%BE%B7%E5%8D%8E&pbs=%E5%88%98%E5%BE%B7%E5%8D%8E&csor=4&pwd=%E5%88%9 8%E5%BE%B7%E5%8D%8E&cb=jQuery1102024053669643223596_1570162206732&_=1570162206766'. 'jQuery1102024053669643223596_1570162206732'. function(data) {  console.log(data);  } ); Copy the code

Returns the content

{
  q: 'Andy Lau'.  p: false.  g: [
    { type: 'sug'.sa: 's_1'.q: 'Andy Lau Wenhui' },
 { type: 'sug'.sa: 's_2'.q: What's Andy Lau's birthday? },  { type: 'sug'.sa: 's_3'.q: 'Andy Lau's Film Collection in Mandarin online viewing' },  { type: 'sug'.sa: 's_4'.q: 'Andy Lau at 17' },  { type: 'sug'.sa: 's_5'.q: 'Who is Andy Lau's wife?' },  { type: 'sug'.sa: 's_6'.q: Andy Lau's Birthday },  { type: 'sug'.sa: 's_7'.q: 'Andy Lau today' },  { type: 'sug'.sa: 's_8'.q: Andy Lau Songs },  { type: 'sug'.sa: 's_9'.q: 'Andy Lau Louis Koo' },  { type: 'sug'.sa: 's_10'.q: 'How old is Andy Lau this year' } ]. slid: '9198684244459417731' } Copy the code