直通互联网大厂前端面试系列(二)——JS / ES6+

传送门

  • 直通互联网大厂前端面试系列(零)——目录总纲
  • 直通互联网大厂前端面试系列(一)——HTML/CSS
  • 直通互联网大厂前端面试系列(二)——JS / ES6+
  • 直通互联网大厂前端面试系列(三)——网络基础
  • 直通互联网大厂前端面试系列(四)——主流框架
  • 直通互联网大厂前端面试系列(五)——算法

写在前面

JavaScript = ECMAScript + DOM(文档对象类型) + BOM(浏览器对象类型)。我们的重头戏来了,因为JS的内容实在太多了,所以我把算法、框架、网络部分的内容都放到了后面的分类里,这样也有利于我们的聚焦。
ES的变化可谓相当之快,2015年后每年一个版本(BOM和DOM相对变化不大)。多亏了babel,我们可以很愉快的使用ES的最新特性,而不用考虑兼容性的问题,相应的,我们每年都要学习一些新的语法。既然选择了前端,那持续学习是跑不了的了,同学们做好心理准备,心里默念,我们是最pang棒的!

长期如何学习

如果你之前有过编码经验,那么你一定知道我下面说的有多重要

  • 深入底层原理,JS也是一门编程语言,只要是编程语言其本质一定是相通的,这一点无论学习任何一种语言都是必然的。虽然是老生常谈,但是真理往往都是经得住岁月考验的。你理解的深度,决定了你以后的高度,出来混迟早要还的,缺的课早晚要补回来的。
  • 注意编码规范,建议越早使用eslint越好,推荐最严格的airbnb的标准,它可以非常有效地规范你的代码风格。良好的代码风格能够让你少写bug,快速修复bug,让别人替你修完bug少骂几句娘。就冲这几点!够不够?!够不够?!
  • 多看经典的书,看书绝对是提升自己思维高度的最佳途径。私以为经过了一段时间的实战,再去看书,才是最有效果的。因为这时候是带着问题去看书的,每当看到与问题相呼应的地方,一定会有一种茅塞顿开的感觉,记忆尤其深刻。对于新手来说,多加练习反而才是重要的,要在实战中多积累问题,多思考,这也算是一种厚积薄发。不过呢,有些书即使是新手也是必须看的,“前端圣经”系列要是没看过的话,实在是有点说不过去了。另外,针对老鸟,我推荐两本让我记忆深刻的书《鸟哥的linux私房菜》、《码农翻身》。

短期如何突击

短期能突击的,就是几个最容易考的难点,无论你是老鸟还是菜鸟,面试前最好都突击一下,这些必考:

  • js数据类型及判断
  • 闭包与作用域
  • this与执行上下文
  • 原型链与继承(原型、构造函数、实例)
  • 异步任务
  • ES6+常用特性

别看知识点就这么几个,围绕着它们出的题可谓变化无穷,想当年我随便见到它们其中一个,都会腿发抖。那么让我们来看一下它们能变化到什么程度

临阵如何磨枪

JS的题一定是占了面试绝大部分内容的,毕竟平时80%以上的开发时间都是用的它,最后强调一遍,下面的题,一定要保证每个知识点都弄明白了,这些题值得反复地做。不怕做的慢,一定不要自欺欺人。哪怕一天能啃下来一道题,也是可以接受的。

请说出以下代码打印的结果
if (1 == true) {console.log(1);};

if (1 === true ) {console.log(2);};

if ([]) {console.log(3);};

if ([] == []) {console.log(4);};

if ([] === []) {console.log(5);};

if (undefined == null) {console.log(6);};

if ('' == null) {console.log(7);};

if (NaN == NaN) {console.log(8);};

追问:

  • JS的数据类型有哪些?哪些是引用类型?它们有什么特点?
  • 什么是浅拷贝?什么是深拷贝?请用JS实现一个深拷贝
  • 如何判断数组类型?方法越多越好
  • typeof 和 instanceof 有什么区别?
  • == 和 === 有什么区别?==时发生了什么?
  • 函数中的 arguments 是数组吗?若不是,如何将它转化为真正的数组
  • 请说下Array的forEach、map、every、some、filter、reduce各有什么功能
  • 如何遍历一个对象?方法越多越好
以下代码的结果是什么?请解释你的答案。
var fullname = 'John Doe';
var obj = {
  fullname: 'Colin Ihrig',
  prop: {
    fullname: 'Aurelio De Rosa',
    getFullname: function () {
      return this.fullname;
    }
  }
};
 
console.log(obj.prop.getFullname());
 
var test = obj.prop.getFullname;
 
console.log(test());
实现Function.prototype.bind方法, 使得以下程序最后能输出’success’
function Animal(name, color) {
  this.name = name;
  this.color = color;
}
Animal.prototype.say = function () {
  return `I'm a ${this.color} ${this.name}`;
};
const Cat = Animal.bind(null, 'cat');
 
const cat = new Cat('white');
 
if (cat.say() === 'I\'m a white cat' && cat instanceof Cat && cat instanceof Animal) {
  console.log('success');
}

追问:

  • bind、call和apply有什么区别?
  • 什么是闭包?请实现一个“有缓存功能”的加法
  • 请用JS实现throttle(函数节流)函数。函数节流解释: 对函数执行增加一个控制层,保证一段时间内(可配置)内只执行一次。此函数的作用是对函数执行进行频率控制,常用于用户频繁触发但可以以更低频率响应的场景
  • debounce和throttle的区别?请用JS实现debounce
  • es6中的箭头函数与普通函数有什么区别?
请用至少2种方法,实现Cat继承Animal的属性,并比较各方法的优缺点
function Animal() {    
    this.species = "动物";  
}

function Cat(name, color) {    
    this.name = name;    
    this.color = color;  
}

追问:

  • 什么是原型链?什么是原型对象?
  • JS的最顶层对象是什么?它的原型对象是什么?
  • 什么是构造函数?什么是实例?
  • 如何通过一个实例访问它的构造函数及原型对象?
  • new一个实例,经历了什么过程?
  • es6中的static的作用是什么?用es5如何实现?
以最小的改动解决以下代码的错误(可以使用es6)
const obj = {
  name: " jsCoder",
  skill: ["es6", "react", "angular"],
  say: function () {
    for (var i = 0, len = this.skill.length; i < len; i++) {
      setTimeout({
        console.log('No.' + i + this.name);
        console.log(this.skill[i]);
        console.log('--------------------------');
      }, 0);
      console.log(i);
    }
  }
};
obj.say();
 
/*
期望得到下面的结果:
1
2
3
No.1 jsCoder
es6
--------------------------
No.2 jsCoder
react
--------------------------
No.3 jsCoder
angular
--------------------------
*/

追问:

  • 如果不修改,会打印出什么结果?
  • let、const、var有什么区别?
  • 什么是函数作用域?还有什么其他作用域?如何工作的?
请说出以下代码打印的结果
async function async1() {
  console.log('async1 start');
  await async2();
  console.log('async1 end');
}
 
async function async2() {
  console.log('async2');
}
 
console.log('script start’);
setTimeout(function() {
    console.log('setTimeout');
}, 0);  

async1();

new Promise(function(resolve) {
    console.log('promise1');
    resolve();
  }).then(function() {
    console.log('promise2');
});

console.log('script end');

追问:

  • JS单线程是怎么运作的?请说下“异步”和“同步”的区别
  • 处理异步任务的方法有哪些?
  • 如何将一个普通异步函数封装为Promise?
  • 请实现一个同步的delay方法

你可能感兴趣的:(直通互联网大厂前端面试系列(二)——JS / ES6+)