[Front-end Interview] JavaScript Basics (2)

Preface

The last article introduced the important concepts in JavaScript in detail, involving knowledge points such as closures, prototypes, scope, execution context, etc. This article will focus on summarizing some interview questions about handwritten code in JavaScript.

Question 1: What are the module loading schemes in JavaScript?

  • CommonJS: Import the module through require, and define the output interface of the module through module.exports. This module loading solution is a server-side solution. It introduces modules in a synchronous manner. Because the files on the server-side are stored on the local disk, the reading is very fast, so there is no problem with synchronous loading. But if it is on the browser side, because the loading of the module requires a network, it is more appropriate to use asynchronous loading.
  • AMD: This solution uses asynchronous loading to load the module. The loading of the module does not affect the execution of the following statements. All my encounters that rely on this module are defined in a callback function, and the callback function is executed after the loading is completed. require.js implements the AMD specification.
  • CMD: This solution and AMD solution are both to solve the problem of asynchronous module loading. sea.js implements the CMD specification. The difference between him and require.js lies in the processing of dependencies and the timing of execution of dependent modules when the module is defined. The treatment is different.
  • ES6's proposal: use import and export to import and export modules. This scheme is different from the above three schemes.

Derivative question 1: What is the difference between AMD and CMD?

  1. The handling of dependencies is different when the module is defined. AMD respects pre-dependency, and declares the dependent modules when defining a module; CMD respects nearby dependencies and requires only when it is used in a certain module.
  2. The timing of execution of dependent modules is different. AMD directly executes the dependent module after the dependent module is loaded, and the dependent execution order and attribute order may not be the same. CMD does not execute after the dependent module is loaded, but only downloads. After all the dependent modules are loaded, enter the callback function logic, and execute the corresponding module when the require statement is encountered, so that the execution order of the modules is consistent with the order we wrote.

Question 2: The difference between in and hasOwnProperty

  • in operator: check whether there is a corresponding attribute on the prototype chain of the specified object.
  • hasOwnProperty: Check whether there is a corresponding property value on the specified object itself.
  • The difference between the two is that in will look up the prototype chain, but hasOwnProperty will not.

Question 3: Deep cloning

I wrote an article about deep cloning before: Interviewer: Can you realize deep cloning with JavaScript? You can read this article.

    function DeepClone(source) {
      // 判断目标是数组还是对象
      const targetObj = source.constructor === Array ? [] : {}
      for (let key in source) {
        if (source.hasOwnProperty(key)) {
          //   如果是对象就递归
          if (source[key] && typeof source[key] === 'object') {
            targetObj[key] = source[key].constructor === Array ? [] : {}
            targetObj[key] = DeepClone(source[key])
          } else {
            targetObj[key] = source[key]
          }
        }
      }
      return targetObj
    }

Question 4: How to simulate const in the ES5 environment?

      function _const(key, value) {
        Object.defineProperty(window, key, {
          enumerable: false,
          configurable: false,
          get() {
            return value
          },
          set(data) {
            if (data !== value) {
              throw new TypeError('error')
            }
            return value
          }
        })
      }
      _const('a',2)
      console.log(a)

Question 5: Simulate and implement the call function

// ES6语法 
 Function.prototype.call2 = function(content, ...keys) {
        content = content || window
        content.fn = this
        const result = content.fn(...keys)
        delete content.fn
        return result
      }


// ES5语法
 Function.prototype.call3 = function(content, ...keys) {
        content = content || window
        content.fn = this
        let args = []
        for (let i = 1; i < arguments.length; i++) {
          args.push('arguments[' + i + ']')
        }
        let result = eval('content.fn(' + args + ')')
        delete content.fn
        return result
      }

Question 6: Simulate the apply function

// ES6语法
      Function.prototype.apply2 = function(content, keys) {
        content = content || window
        content.fn = this
        const result = content.fn(...keys)
        delete content.fn
        return result
      }

// ES5语法

      Function.prototype.apply3 = function(content, keys) {
        content = content || window
        content.fn = this
        let result = eval('content.fn(' + keys + ')')
        delete content.fn
        return result
      }

Question 7: Simulate the realization of the bind function

      Function.prototype.bind2 = function(content, ...keys) {
        content = content || window
        const self = this
        function fn() {}
        let bound = function(...keys2) {
          self.apply(
            this instanceof self ? this : content,
            [].concat(keys, keys2)
          )
        }
        fn.prototype = this.prototype
        bound.prototype = this.prototype
        return bound
      }

      var a = '2'
      var obj = { a: 1 }
      function fn(b, c, d) {
        console.log(this.a, b, c, d)
      }
      var fn2 = fn.bind2(obj, 1, 2)
      fn2(4)

 You can refer to this article: Interviewer asked: Can you simulate the bind method of JS

Question 8: Simulate the realization of the new operator

      function newObj(ctor, ...keys) {
        if (typeof ctor !== 'function')
          throw new Error('ctor is not a function')
        // new.target 指向构造函数
        newOperator.target = ctor
        const obj = Object.create(ctor.prototype)
        const result = ctor.apply(obj, keys)
        const isObject = result !== null && typeof result !== 'object'
        const isFunction = typeof result !== 'function'
        if (isObject || isFunction) {
          return result
        } else {
          return obj
        }
      }

 You can refer to this article: Interviewer asked: Can you simulate the new operator of JS

Question 9: Flattening the array

 For a multi-level nested array like [1, [1, 2], [1, 2, [4, 4, 4]]], how do we flatten it to [1, 1, 2, 1, 2, 4, 4, 4] What about such a one-dimensional array:

// 方法1
      const arr = [1, [1, 2], [1, 2, [4, 4, 4]]]
      const test = arr.flat(Infinity)
      console.log(test)   //[1, 1, 2, 1, 2, 4, 4, 4]

// 方法2
      const test = JSON.stringify(arr).replace(/(\[|\])/g, '')
      console.log('[' + test + ']')

// 方法3
      function flat(target) {
        return target.reduce(function(arr, item) {
          return [].concat(arr, typeof item === 'object' ? flat(item) : item)
        }, [])
      }
      console.log(flat(arr))

Question 10: Simulate the realization of promise

      class MyPromise {
        constructor(executor) {
          // 初始化状态
          this.state = 'pending'
          // 保存成功的值
          this.value = undefined
          // 保存成功的回调函数
          this.onFulfilledCallBacks = []
          // 保存失败的值
          this.reason = undefined
          // 保存失败的回调函数
          this.onRejectedCallBacks = []
          //   成功后调用的函数
          let resolve = value => {
            if ((this.state = 'pending')) {
              this.state = 'fulfilled'
              this.value = value
              this.onFulfilledCallBacks.forEach(item => item())
            }
          }
          //   失败后调用的函数
          let reject = value => {
            if ((this.state = 'pending')) {
              this.state = 'rejected'
              this.reason = value
              this.onRejectedCallBacks.forEach(item => item())
            }
          }
          //   如果executor报错,直接reject
          try {
            executor(resolve, reject)
          } catch (error) {
            reject(error)
          }
        }

        then(onFulfilled, onRejected) {
          if (this.state === 'fulfilled') {
            onFulfilled(this.value)
          }
          if (this.state === 'rejected') {
            onRejected(this.reason)
          }
          if (this.state === 'pending') {
            this.onFulfilledCallBacks.push(() => {
              onFulfilled(this.value)
            })
            this.onRejectedCallBacks.push(() => {
              onRejected(this.reason)
            })
          }
        }
      }

      let promise = new MyPromise(function(resolve, reject) {
        setTimeout(function() {
          reject(213213123)
        }, 2000)
      })
      promise.then(
        function(value) {
          console.log(value)
        },
        function(error) {
          console.log(error)
        }
      )

Recommend everyone to read this article: BAT front-end classic interview questions: the most detailed handwritten Promise tutorial in history

Question 11: How does ES5 implement inheritance?

I won’t go into details here. I have summarized it before: Object inheritance mode in JS

Question 12: Simulate the implementation of instanceof

      function myInstanceOf(leftValue, rightValue) {
        if (typeof leftValue !== 'object' || rightValue === null) return false
        let rightProto = rightValue.prototype
        let leftProto =leftValue.__proto__
        while(true){
            if(leftProto === null){
                return false
            }
            if(leftProto === rightProto){
                return true
            }
            leftProto = leftProto.__proto__
        }
      }

 For details, please refer to this article: Talk about the implementation principle of typeof instanceof

At last

The above is a summary of some of the questions and answers of the handwritten code in the front-end interview. Finally, I summarized some collection of interview questions for everyone. Welcome everyone to learn! I wish you all get your favorite offer! Recently, we will also summarize the relevant knowledge points of css and vue, welcome everyone to pay attention! !

"Interview" 45 Summary of Classic JavaScript Questions on Daoxe.com (8500 words)

40+JavaScript basic interview questions (with answers)

70 JavaScript interview questions, including answers, self-test JS mastery

100+ JavaScript interview questions to help you check the missing

 

Guess you like

Origin blog.csdn.net/qq_44313091/article/details/108022434