面试题汇总

好未来二面:

打印结果:

function ClassA() {
  this.x = 'hello';
}

ClassA.prototype.x = 'world';

var a = new ClassA();
a.x = 'what'
console.log(a.x);
delete a.x;
console.log(a.x)
a.x = undefined;
console.log(a.x)

输出:
面试题汇总

function someFunction() {
  var a = 0;
  return function () {
    return a++;
  }
}

let f1 = someFunction();
let f2 = someFunction();

console.log(f1()); 
console.log(f2()); 

let f = someFunction();
console.log(f()); 
console.log(f());

输出:
面试题汇总

说说作用域和闭包

(LHS是变量赋值操作,RHS是变量取值操作)
作用域:一套用于如何处理变量的规则
闭包:一个变量在它自身作用域外被使用了,就叫发生了闭包
丁爷博客

webSocket怎么去做消息确认呢?没有Ajax的回调这种。

端点一面:

vue2响应式原理

Object.defineProperty去实现数据双向绑定,然后设置了一个Dep类和一个Watcher类,Watcher是收集节点和节点使用的属性,Dep是用于管理Watcher,主要功能有添加一个新watcher实例,当数据发生变化,Dep就通知所有使用到数据的watcher去更新。

vue3响应式原理相对于vue2有什么提升?

vue3用到的变量才去返回new Proxy(data),不用对数组进行重构,深度监听,不用再写\(set和\)delete

vue-router的原理

利用URL的hash和利用History interface在Html5中新增的方法。hash有push、replace方法;HTML5History有back、go、forword、pushState、replaceState

继承的几种方式,怎么做的?

经典、原型、寄生、组合、寄生组合
经典:在子类构造函数中调用父类构造函数

//es5
function A() {
  this.color = ['red']
}

function B(name) {
  A.call(this)
  this.name = name
}
//面向对象
class A {
  constructor() {
  }
}

class B extends A {
  constructor() {
    super()  
  }
}

原型:ES5通过添加Object.create()方法原型式继承的概率规范化了

    function obj(p) {
      function F() {}
      F.prototype = p
      return new F()
    }
    let p1 = obj()
//es5
let p2 = Object.create()

寄生:在里面创建一个对象,然后在该对象上添加属性,最后返回该对象

    function other(original) {
        const clone = Object.create(original); //原型继承
        clone.say = function () {
          console.log("say Hi");
        };
        return clone;
      }

组合:将经典和原型链组合在一起

      function Person() {
        this.name = "人类";
      }
      Person.prototype.run = function () {
        console.log("人类跑步");
      };

      function Robot(name) {
        //通过经典继承的方式继承父类实例的属性
        Person.call(this);
        this.name = name;
      }

      //通过原型链来继承原型上的方法和属性
      Robot.prototype = new Person();

寄生组合:

      function usefulFunction(Father, Son) {
        //这里借用寄生式
        function F() {}
        F.prototype = Father.prototype;
        //这里借用组合式
        const p = new F();
        p.constructor = Son;
        Son.prototype = p;
      }

丁大爷的博客

nextTick原理和为什么要用nextTick

原理:基于事件循环,将要更新的数据放入宏队列,先更新微队列在更新宏队列。
为什么要用:因为vue是异步更新,所以直接拿是拿不到更新后的数据,用nextTick才能拿到

js怎么判断数据类型?

  • typeOf:只能判断出number、string、boolean、undefined、function、symbol、Object,null型也会被识别为Object
  • Object.prototype.toString.call():能辨认出所有类型
  • constructor:作为原型prototype的属性,不能识别null和undefined两种类型
  • instanceOf:判断A的原型链上是否有B,只能判断两个变量是否有实例关系,不能判断一个对象实例具体属于那种类型。
//简单实现instanceOf
    function myInstanceOf(a, b) {
      const O = b.prototype
      if(a === null) {
        return false
      }
      a = a.__proto__
      while(true) {
        console.log(a);
        if(a === null) {
          return false
        }
        if(a === O) {
          return true
        }
        a = a.__proto__
      }
    }

Promise实现的过程

Promise的静态方法,说说作用和区别:

resolve和reject:resolve创建了一个决议到传入值得promise,reject创建一个立即被拒绝得promise
all和race:all接收一个或多个值得数组,返回一个promise,如果所有值都完成,这个promise的结果是完成,否则是立即被拒绝;race等待第一个完成或者全部拒绝
then和catch:then的结果是将resolve的返回值进行相应包装,返回一个新创建的promise对象;catch是then方法参数中resolve取null/undefined的别名,用于发生错误时的回调函数
finally:不管怎样,都会在最后调用一次

promise和await/async又什么区别?

Promise是ES6的新特性,async/await是ES7中的提案
Async让try/catch可以同时处理同步和异步错误,如果Promise连续调用无法知道错误出在哪里

flex实现两栏布局

  • 两栏布局分为以下几种情况:
  • 一栏固定宽度,一栏自适应
  • 一栏不定宽,一栏自适应
  • 两栏等高
  • 左右宽度比为1:2,右边又分为上下结构,高度比为1:1
上一篇:js的面向对象+继承


下一篇:如何删除本地项目文件中的.svn文件