Abstract: This article shares 5 algorithm questions, handwritten bind function, cross-domain solution, Vuex workflow, new ES6 features, learning CSS layout and more.

1, run the following code, please write the console print order.

console.log(1)
setTimeout(() = >console.log(2), 0)
new Promise((resolve,reject) = >{
  console.log(3)
  setTimeout(() = >resolve(4), 0)
}).then(res= >{
  console.log(res)
  console.log(5)
})
requestAnimationFrame(() = >console.log(6))
console.log(7)
Copy the code

Answer: It could be 1, 3, 7, 6, 2, 4, 5, or 1, 3, 7, 2, 4, 5, 6.

2. Wrap method arr2tree, convert the following array into a tree structure.

// Input: source array
var arr = [
  { id: 0.name: 'news' },
  { id: 1.name: 'sports'.pid: 0 },
  { id: 2.name: 'basketball'.pid: 1 },
  { id: 3.name: 'football'.pid: 1 },
  { id: 4.name: 'NBA'.pid: 2 },
  { id: 5.name: 'CBA'.pid: 2 },
  { id: 6.name: 'entertainment'.pid: 0 },
  { id: 7.name: 'sketch'.pid: 6 },
  { id: 8.name: 'cross'.pid: 6},]// Output: tree structure
var tree = [
  { 
    "id": 0."name": "News"."children": [{"id": 1."name": "Sports"."pid": 0."children": [{"id": 2."name": "Basketball"."pid": 1."children": [{"id": 4."name": "NBA"."pid": 2 }, 
              { "id": 5."name": "CBA"."pid": 2}]}, {"id": 3."name": "Football"."pid": 1}]}, {"id": 6."name": "Entertainment"."pid": 0."children": [{"id": 7."name": "Sketch"."pid": 6 }, 
          { "id": 8."name": "Crosstalk"."pid": 6}]}]Copy the code

Reference answer:


function arr2tree(sourceArr) {
  let obj = {}
  for (let i = 0; i < sourceArr.length; i++) {
    obj[sourceArr[i].id] = sourceArr[i]
  }
  const result = []
  sourceArr.forEach(node= > {
    if(! obj[node.pid]) { result.push(node)return
    }
    obj[node.pid].children = obj[node.pid].children || []
    obj[node.pid].children.push(node)
  })
  return result
}
Copy the code

3. Look at the input and output relationship in the sample code below and wrap the Add () method.

// Input source method => output result
add(1);       / / 1
add(1) (2);    / / 3
add(1) (2) (3); / / 6
add(1) (2.3);  / / 6
add(1.2) (3);  / / 6
add(1.2.3);   / / 6

// Refer to the answer
function add() {
  let args = [].slice.call(arguments); 
  let fn = function(){
   let fn_args = [].slice.call(arguments)
   return add.apply(null,args.concat(fn_args))
  }
  fn.toString = function(){
    return args.reduce((a,b) = >a+b)
  }
  return fn
}
/ / test:
add(1.2) (3) (4.5) (6) / / 21
Copy the code

4. Encapsulate functions to achieve thousands separator.

// Input source method => Keep three decimal places
parseToMoney(1234.56); // return '1,234.56'
parseToMoney(123456789); / / return '123456789'
parseToMoney(1087654.32123); / / return '1087654321'

// Refer to the answer
function parseToMoney(num) {
  num = parseFloat(num.toFixed(3));
  let [integer, decimal] = String.prototype.split.call(num, '. ')
  integer = integer.replace(/\d(? =(\d{3})+$)/g.'$&,)
  return integer + '. ' + (decimal ? decimal : ' ')}Copy the code

5, encapsulation method to find the intersection of any two Number arrays.

For example, num1 = [1, 2, 2, 1], nums = [2, 2, 3], and return [2, 2].

function union (arr1, arr2) {
  return arr1.filter(item= > arr2.indexOf(item)>-1)}/ / test
const a = [1.2.2.1];
const b = [2.3.2];
union(a, b)   / / (2, 2)
Copy the code

6, Talk about the differences between bind, call, and apply, and encapsulate a bind function.

  • Call and apply both solve for changing the direction of this. The function is the same, but the way the parameter is passed is different. In addition to the first argument, Call can accept a list of arguments, and Apply accepts only an array of arguments.
let a = { value: 1 }
function getValue(name, age) {
    console.log(name)
    console.log(age)
    console.log(this.value)
}
getValue.call(a, 'geek'.'10')
getValue.apply(a, ['geek'.'30'])
Copy the code
  • The implementation of BIND is slightly more complicated than the other two functions, because bind returns a function and needs to determine some boundary issues.
Function.prototype.myBind = function (context) {
  if (typeof this! = ='function') {
    throw new TypeError('Error')}const _this = this
  const args = [...arguments].slice(1)
  // Return a function
  return function F() {
    // Since we return a function, we can new F(), so we need to determine
    if (this instanceof F) {
      return new_this(... args, ... arguments) }return_this.apply(context, args.concat(... arguments)) } }Copy the code

7. Please draw and describe the Vuex workflow.

  • See Vuex for complete workflow

8. List the new ES6 features.

  • ES6 new features and key knowledge summary
  • Ruan Yifeng ES6 Introduction Course

9. What are the common CSS layout attributes (schemes)?

  • Learning CSS Layouts

10. What is cross-domain? What is the Browser same-origin policy? What are the common cross-domain solutions? Manually encapsulate a JSONP cross-domain request function.

  • Because browsers have the same origin policy for security reasons. That is, if a protocol, domain name, or port difference is cross-domain, the Ajax request will fail.
  • Common cross-domain solutions are: JSONP, CORS, and proxy.
  • JSONP cross-domain request functions are encapsulated as follows:
// Use JSONP (function encapsulation)
function jsonp(url, jsonpCallback, success) {
  let script = document.createElement('script')
  script.src = url
  script.async = true
  script.type = 'text/javascript'
  window[jsonpCallback] = function (data) {
    success && success(data)
  }
  document.body.appendChild(script)
}
// Test examples
jsonp('http://xxx'.'callback'.function (value) {
  console.log(value)
})

// Use JSONP (no encapsulation)
let script = document.createElement('script');
script.src = 'http://www.baidu.cn/login?username=JasonShu&callback=callback';
document.body.appendChild(script);
function callback (res) {
  console.log(res);
}
Copy the code