2019最新前端面试题整理(持续更新中)

1.写出下面程序的运行结果:
console.log([] == ![])	// true
console.log([] == [])	// false
console.log([] == {})	// false
console.log(new String('a') == new String('a')) // false
console.log(isNaN(NaN))	// true
console.log(isNaN('32131dsafdas'))	// true
console.log(NaN === NaN)	// false
console.log(NaN === undefined)	// false
console.log(undefined === undefined)	// true
console.log(typeof NaN)	 // number

console.log({} + [])	// 0
console.log([] + {})	// "[object Object]"
console.log({} + {})	// "[object Object][object Object]"
console.log([]+ [])	// ""
console.log({} + 1)	// 1
console.log([] + 1)	// "1"

隐式类型转换参考:https://blog.csdn.net/m0_37793545/article/details/87862847

2.写出下面程序的运行结果:
  var name = 'world';
  (function () {
    if (typeof name === 'undefined') {
      var name = 'jack'
      console.log('hi' + name)
    } else {
      console.log('hello' + name)
    }
  })()
  
  // hijack
3.写出下面程序的运行结果:
  var test = (function (a) {
    this.a = a;
    return function (b) {
      return this.a + b
    }
  }(function (a, b) {
    return a
  }(1, 2)))
  test(4)
  
  // 5
4.写出下面程序的运行结果:
  var x = 1,
    y = z = 0

  function add(n) {
    return n = n + 1
  }
  y = add(x)

  function add(n) {
    return n = n + 3
  }
  z = add(x)
  console.log(x, y, z)
  
  // 1 4 4
5.写出下面程序的运行结果:
  function bar() {
    return foo;
    foo = 10;

    function foo() {}
    var foo = 11
  }
  alert(typeof bar())

  // function
  (2)
  var a = 1
  function a() {}
  console.log(a) // 1
  (3)
  var b = 1
  if (true) {
  	console.log(b)	//	1
  	var b = 2
  	var c = 3
  	console.log(c)	//	3
  }
  console.log(b)	//	2
  console.log(c)	//	3
6.写出下面程序的运行结果:
  var x = 3;
  var foo = {
    x: 2,
    baz: {
      x: 1,
      bar: function () {
        return this.x
      }
    }
  }
  var go = foo.baz.bar
  go()
  foo.baz.bar()
  
  // 3
  // 1
7.写出下面程序的运行结果:
  console.log([1, 2] + [2, 1])
  
  // 1,2,2,1
8.判断一串字符串是否为回文
  var test = '12344321'
  var test1 = test.split('').reverse().join('')
  console.log(test === test1)
9.数组去重,数组排序
  //去重:
  (1)Array.from(new Set([1,2,3,5,2,1,22,'1']))
  (2)
  var array = [1, 2, 1, 1, '1']; 
  function unique(array) {
    var res = array.filter(function(item, index, array){
      return array.indexOf(item) === index;
    })
    return res;
  }
  console.log(unique(array));
  (3)
  function unique(arr) {
    arr = arr.sort()
    let res = []
    for (let i = 0; i < arr.length; i++) {
      if (arr[i] !== arr[i-1]) {
          res.push(arr[i])
      }
    }
    return res
  }

更多去重方式:https://juejin.im/post/5949d85f61ff4b006c0de98b
数组排序总结:https://juejin.im/post/57dcd394a22b9d00610c5ec8#heading-24

10.js继承的实现方式
  // (1) 借助构造函数实现继承
  function Parent() {
    this.name = 'parent'
  }
  function Child() {
    Parent.call(this)
    this.age = 18
  }
  // 这种方式只能实现部分继承,即父类的构造方法中的属性,子类可以继承,其缺点是,父类原型上的属性或方法,子类无法继承。
  // (2)借助原型链实现继承
  function Parent() {
    this.name = 'parent'
    this.play = [1, 2, 3]
  }
  function Child() {
    this.age = 18
  }
  Child.prototype = new Parent()
  // 这种继承方式的缺点是用子类Child实例化两个对象后,var s1 = new Child(); var s2 = new Child(); s1.play.push(4); console.log(s2.play); 也会打印出[1,2,3,4],其原因是两个对象的__proto__指向了同一个原型对象。
  // (3)组合方式(继承的完美实现)
  function Parent() {
    this.name = 'parent'	
  }
  function Child() {
    //	将父对象的构造函数绑定在子对象上
    Parent.call(this)
    this.age = 18
  }
  //  将Parent的prototype拷贝给Child
  Child.prototype = Object.create(Parent.prototype)
  //  修正Child的prototype对象指向的构造函数
  Child.prototype.constructor = Child
11.JavaScript事件循环机制相关问题
// 请写出以下代码执行的顺序

setTimeout(function () {
    console.log(1);
});

new Promise(function(resolve,reject){
    console.log(2)
    resolve(3)
}).then(function(val){
    console.log(val);
})
console.log(4);

// 2 4 3 1
在同步代码执行完成后才回去检查是否有异步任务完成,并执行对应的回调,而微任务又会在宏任务之前执行。
同步代码=>异步代码(微任务=>宏任务)
宏任务: setTimeout
微任务: Promise.then
12.伪数组转数组
var a={length:2,0:'aaa',1:'bbb'};  
// ES6:
Array.from(a)
// ES5:
Array.prototype.slice.call(a);//  ["aaa", "bbb"]   

var a={length:2};  
Array.prototype.slice.call(a);//  [undefined, undefined]  
13.写出下面程序的运行结果:
  function Foo() {
    getName = function() {
      alert(1)
    }
    return this
  }
  Foo.getName = function() {
    alert(2)
  }
  Foo.prototype.getName = function() {
    alert(3)
  }
  var getName = function() {
    alert(4)
  }
  function getName() {
    alert(5)
  }
  //请写出以下输出结果:
  Foo.getName() // 2
  getName() // 4
  Foo().getName() // 1
  getName() // 1
  new Foo.getName() // 2
  new Foo().getName() // 3
  new new Foo().getName() // 3
  // 详细解释 https://www.jb51.net/article/79461.htm
14. 函数防抖与函数节流

(1) 函数防抖

    function debounce(func, delay) {
      var timeout
      return function(e) {
        console.log('清除', timeout, e.target.value)
        clearTimeout(timeout)
        var context = this,
          args = arguments
        console.log('新的', timeout, e.target.value)
        timeout = setTimeout(function() {
          console.log('----')
          func.apply(context, args)
        }, delay)
      }
    }

    var validate = debounce(function(e) {
      console.log('change', e.target.value, new Date() - 0)
    }, 380)
    // 绑定监听
    document.querySelector('input').addEventListener('input', validate)

(2) 函数节流

	// 函数节流
	    function throttle(fn, threshhold) {
      var timeout
      var start = new Date()
      var threshhold = threshhold || 160
      return function() {
        var context = this,
          args = arguments,
          curr = new Date() - 0

        clearTimeout(timeout) //总是干掉事件回调
        if (curr - start >= threshhold) {
          console.log('now', curr, curr - start) //注意这里相减的结果,都差不多是160左右
          fn.apply(context, args) //只执行一部分方法,这些方法是在某个时间段内执行一次
          start = curr
        } else {
          //让方法在脱离事件后也能执行一次
          timeout = setTimeout(function() {
            fn.apply(context, args)
          }, threshhold)
        }
      }
    }
    var mousemove = throttle(function(e) {
      console.log(e.pageX, e.pageY)
    })

    // 绑定监听
    document.querySelector('#panel').addEventListener('mousemove', mousemove)

15. 什么是hash函数

hash(散列、杂凑)函数,是将任意长度的数据映射到有限长度的域上。直观解释起来,就是对一串数据m进行杂糅,输出另一段固定长度的数据h,作为这段数据的特征(指纹)。也就是说,无论数据块m有多大,其输出值h为固定长度。

hashmap,hash值(key)存在的目的是加速键值对的查找

详解:https://www.zhihu.com/question/26762707

16. Vue 组件 data 为什么必须是函数

每个实例可以维护一份被返回对象的独立的拷贝,否则;将导致多个实例共享一个对象,其中一个组件改变data属性值,其它实例也会受到影响。

17. jQuery.extend()和jQuery.fn.extend()的区别
jQuery.extend()为扩展jQuery类本身.为类添加新的方法。如 $.wang()
jquery.fn.extend(object);给jQuery对象添加方法。如 $('#test').wang()
18. Vue中的虚拟Dom diff 算法
(1)所谓的virtual dom,也就是虚拟节点。它通过JS的Object对象模拟DOM中的节点,然后再通过特定的render方法将其渲染成真实的DOM节点
dom diff 则是通过JS层面的计算,返回一个patch对象,即补丁对象,在通过特定的操作解析patch对象,完成页面的重新渲染
(2)DOM DIFF
比较两棵DOM树的差异是Virtual DOM算法最核心的部分.简单的说就是新旧虚拟dom 的比较,如果有差异就以新的为准,然后再插入的真实的dom中,重新渲染。
比较只会在同层级进行, 不会跨层级比较。新旧虚拟dom比较的时候,是先同层比较,同层比较完看看时候有儿子,有则需要继续比较下去,直到没有儿子。

比较后会出现四种情况:
1、此节点是否被移除 -> 添加新的节点 
2、属性是否被改变 -> 旧属性改为新属性
3、文本内容被改变-> 旧内容改为新内容
4、节点要被整个替换 -> 结构完全不相同 移除整个替换

详解:https://juejin.im/post/5ad6182df265da23906c8627

19.常见Http状态码
// 100  Continue  继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息
// 200  OK   正常返回信息
// 201  Created  请求成功并且服务器创建了新的资源
// 202  Accepted  服务器已接受请求,但尚未处理
// 301  Moved Permanently  请求的网页已永久移动到新位置。
// 302 Found  临时性重定向。
// 303 See Other  临时性重定向,且总是使用 GET 请求新的 URI。
// 304  Not Modified  自从上次请求后,请求的网页未修改过。

// 400 Bad Request  服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。
// 401 Unauthorized  请求未授权。
// 403 Forbidden  禁止访问。
// 404 Not Found  找不到如何与 URI 相匹配的资源。

// 500 Internal Server Error  最常见的服务器端错误。
// 503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)。
20. 什么情况出现跨域,如何解决?

同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。若地址里面的协议、域名和端口号均相同则属于同源。

jsonp跨域、nginx反向代理、node.js中间件代理跨域、后端设置http header、后端在服务器上设置cors。

21. 重绘和回流

重绘:当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。

回流:当Render Tree(DOM)中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。
回流要比重绘消耗性能开支更大。
回流必将引起重绘,重绘不一定会引起回流。

详解:https://juejin.im/post/5a9923e9518825558251c96a

22. 浏览器从加载到渲染的过程,比如输入一个网址到显示页面的过程。

加载过程:

  • 浏览器根据 DNS 服务器解析得到域名的 IP 地址
  • 向这个 IP 的机器发送 HTTP 请求 服务器收到、处理并返回 HTTP 请求
  • 浏览器得到返回内容

渲染过程:

  • 根据 HTML 结构生成 DOM 树
  • 根据 CSS 生成 CSSOM
  • 将 DOM 和 CSSOM 整合形成 RenderTree
  • 根据 RenderTree 开始渲染和展示
  • 遇到

你可能感兴趣的:(js)