Coordinate Hangzhou, 18 years of graduation, including internship one and a half years of development experience. It’s an expatriate interview. Ali’s interviewers are on the back two sides.

It was supposed to be an online test for me, but there was a problem with the server there, and I couldn’t open the web page, so I had to answer questions over the phone. Most of what I write below are questions from the test, and some of the questions I added over the phone…

  1. Try to center child elements vertically and horizontally in as many ways as possible

    <div class="father">
        <div class="child">  
        </div>
    </div>
    
    <style>
        .father {
            width: 300px;
            height: 300px;
        }
        .child{}</style>
    Copy the code

Child can be a lot of things, just to give you a sense of it

  • Text-align + line-height
.father{
  text-align: center;
  line-height: 300px;
}
Copy the code
  • Fixed width and height: Absolute + margin
.father{
  position: relative;
}
.child{
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -150px 0 0 -150px;
}
/* 或者 */
.child{
  position: absolute;
  left: 0;
  top: 0; 
  right: 0; 
  bottom: 0;
  margin: auto;
}
Copy the code
  • Absolute + translate
.father{
  position: relative;
}
.child{
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
}
Copy the code
  • Variable height: Flex
.father{ display: flex; } .child{ margin:auto; } /* /. Child {justify-content: center; align-items: center; }Copy the code
  • The table:
.father{
  display: table; 
}
.child{
  display: table-cell;
  text-align: center;
  vertical-align: middle;
}
Copy the code
  1. Implement the following three-column layout in as many ways as possible, with.main in the middle

<div class="container">
  <div class="main"></div>
  <div class="sub"></div>
  <div class="extra"></div>
</div>
Copy the code
  • floating
  • Flex layout: Use the order property
  • Gird layout: grid-template-areas
  1. Execute the following code, and what is the output?

console.log(+false) // 0, where the unary operator performs a weak conversion, and the corresponding +true returns 1
console.log('1' + 2 + '3' + 4) // '1234' will be concatenated when it encounters a string
console.log(4 + 3 + 2 + '1')  // add '91' together
Copy the code
  1. Run the following code, what does it output?

var x = 3;
var foo = {
  x: 2.baz: {
    x: 1.bar: function() {
      return this.x; }}}var go = foo.baz.bar;

console.log(go());  / / 3
console.log(foo.baz.bar()); / / 1
Copy the code

A. this B. this C. this D. this

This is provided by the caller, depending on how the function is called. If the function is called by an object, this refers to that object, such as foo.baz.bar(). If a function is called independently such as go(), then this inside the function refers to undefined. But in non-strict mode, it is automatically referred to as the global object Window.

  1. Implement the following function to output the input string in reverse order

function reverse(str) {
  let res = str.split(' ');
  return res.reverse().join(' ');
}

reverse('hello world! '); // output: '! dlrow olleh'
Copy the code

Advanced problem

'hello world! '.reverse();  // output: '! dlrow olleh'
Copy the code
  • This problem requires adding methods to the String prototype, but there are some modifications to consider:
String.prototype.reverse = function reverse() {
  let res = this.split(' ');
  return res.reverse().join(' ');
}
Copy the code
  1. Implementing the sleep function

Required usage:

/** - Makes the currently running asynchronous operation (promise or async) stop waiting for several seconds - - @param ms */
(async() = > {console.log('hello')
  await sleep(2000) // Wait two seconds
  console.log('world')
})()
Copy the code
const sleep = ms= > return new Promise(resolve= > setTimeout(resolve, ms))
Copy the code
  1. Implement the throttle function

    Usage:

    const throFun = () => console.log('hello'); const thro = throttle(throFun, 300); document.body.onscroll = () => { thro(); // Calls are triggered at least once every 300 milliseconds}Copy the code
    /** - @param delay {number} - @param action {function} - @param delay {number} - @return {function} returns the client called function */
    function throttle(action, delay) {
      var previous = 0;
      // Returns a function using a closure and uses the variable previous outside the closure
      return function() {
        var _this = this;
        var args = arguments;
        var now = new Date(a);if(now - previous > delay) { action.apply(_this, args); previous = now; }}}Copy the code
  2. Implements the Debounce anti-shock function

    Usage:

    const throFun = (a)= > console.log('hello');
    const thro = debounce(throFun, 300);
    document.body.onscroll = (a)= > {
      thro();  // Execute only when idle time is greater than 300 ms
    }
    Copy the code
    @param delay {number} - @param action {function} - @param delay {number} - @param action {function} - @return {function} returns the client called function */
    function debounce(action, delay) {
      var timer; // Maintain a timer
      return function () {
          var _this = this; // call debounce to execute scoped this
          var args = arguments;
          if (timer) {
              clearTimeout(timer);
          }
          timer = setTimeout(function () {
              action.apply(_this, args); // Apply to the object that called debounce, equivalent to _this.action(args);
          }, delay);
      };
    }
    Copy the code
  3. What are the methods of array de-duplication?

const arr = [1.2.3.4.4.3.2.1];
// New Set ES6
return [...new Set(arr)]; // Here again ask me... The use of the

// Method 2: double-layer for loop (then say this is bad, let me just use one layer for loop method)
function unique(arr){
  var res=[];
  for (var i = 0; i < arr.length; i++) {
    for (var j = i+1; j < arr.length; j++) {
      if (arr[i] === arr[j]) {
        ++ i;
        j = i;
      }
    }
    res.push(arr[i]);
  }
  return res;
}

// Method 3: single-layer for loop + indexOf
function unique(array){
    var res = [];
    for(var i = 0; i < array.length; i++) {
        // If the first occurrence of the ith element in the current array is at position I, the array is stored. Otherwise the representation is repeated
        if (array.indexOf(array[i]) === i) {
            res.push(array[i])
        }
    }
    return res;
}
// The method is as follows
function unique(array){
    let res = [];
    for(var i = 0; i < array.length; i++) {
        if (res.indexOf(array[i]) === - 1) { res.push(array[i]); }}return res;
}

// Method 4: If you can tolerate changing the original array, how can you improve the performance
function unique(array){
    // Note that the for loop must be backtracked, otherwise there will be problems
    for(var i = array.length - 1; i > 0; i--) { 
        if(array.indexOf(array[i]) ! == i) { array.splice(i,1); }}// Save memory space by declaring one less variable.
    return array;
}
Copy the code
  1. Scene questions, examine the event proxy, event listening, DOM custom attributes, etc

Title description:

  • The page has an element, A, that has A data-href attribute that holds A link address, 🔗
  • Implement A function to jump to A link if the clicked element is A or if A is found in its upper node

Implementation idea:

  • First add a listener to the window for the click event, and then declare an intermediate variable targetNode to record the node
  • The loop then determines whether the current targetNode has the data-href attribute
  • If so, jump, break. If it does not exist, the parent of the node is assigned to targetNode
  • Loop until you determine that targetNode is the outermost node

Post-interview code:

window.addEventListener('click', (e) => {
    let targetNode = e.target
    while(targetNode ! = =document) { As long as the current node is not the outermost document
        console.log(targetNode)
        if (targetNode.getAttribute('data-href')) { // Use hasAttribute instead
            window.open(targetNode.dataset.href)
            break
        } else { // If you don't find it, keep looking
            targetNode = targetNode.parentNode
        }
    }
})
Copy the code

Conclusion:

  • I feel that this question is very good, and the interviewer has been guiding my thinking during the answer process. For example, AT the beginning, I thought of using DOM to judge whether the node is a superior and subordinate relationshipcontains()Then the interviewer considers performance, preferably using native apis. Then I’ll say parentNode. Then I looked it upMDNAnd found thatcontainsThis method is a native API, which is supported by IE5 above:

    But that’s not the point either. The point is that you can’t implement this scenario using the CONTAINS method because you need the parent node (the upper node) to be known. But this scenario is to look up the node by knowing the child node (the target returned by clicking the event).

  • When I was talking about using dataset to get custom attributes, the interviewer asked if there was any other way considering compatibility. I answeredgetAttribute().
  • When I was talking about how to find nodes layer by layer, I thought of calling functions recursively at first, but the interviewer immediately interrupted me and said that it was unnecessary and wasted performance. And then prompt me to say what is the way to cycle. Finally, while comes to mind
  1. Other problems

  • What methods do ES6 arrays have
  • React uses state management tools like Redux and Mobx.

1.Redux encourages one Store per app, Mobx encourages multiple stores; 2.Redux is functional programming, while Mobx’s model is object-oriented; 3.Redux uses pull as React, but Mobx uses push as React. 4.Redux encourages data formalization and reduces redundancy, while Mobx allows data redundancy but still keeps data consistent. 5.Redux is more strict, and reducer actions must be called to trigger state changes. One of Mobx’s initial selling points was to directly modify data, but in practice, people still found that such disorganization and discipline is bad, so Mobx still provided the concept of action. A bit different from Redux’s action, Mobx’s action is just a function and doesn’t require a dispatch. To force action, don’t modify Observable data directly. Use Mobx configure as follows:

import {configure} from 'mobx';

configure({enforceActions: true});
Copy the code
  • React virtual DOM and diff algorithm
  • React Key functions