一面
deepClone
考察:
- 什么是深度克隆。普通数据类型和引用类型的区别
- 数据类型的判断。
答案:
function deepClone(obj, hash = new WeakMap()) {
if(typeof obj !== 'object' || obj === null) {
return obj;
}
if(hash.has(obj)) {
return hash.get(hash);
}
let newObj = Array.isArray(obj) ? [...oobj] : {...obj};
hash.set(obj, newObj);
Reflect.ownKeys(obj).forEach(key => {
newObj[key] = deepClone(obj[key], hash);
});
return newObj;
}
可被追问:
-
如何解决循环引用的问题。上面的hash就是用来解决循环引用的问题
-
普通数据类型和引用类型的区别
-
如何判断一个数据的类型,以及它们的优缺点 | 方式 | 缺点 | | --- | --- | | typeOf | 无法却分数组和对象 | | Instanceof | 当认为改变原型的时候,判断结果不可信 | | Object.prototype.toString.call | 最可信 | | Array.isArray | 只可以判断是否为数组 |
-
Object.keys和Reflect.ownKeys方法的区别
设计模式
详细文章:javascript的23种设计模式
考点:
- 什么是设计模式
- 设计模式的原则
- 设计模式有哪些内容
答案:
设计模式是解决问题的一种思路,和语言无关。在面向对象软件设计的工程中,针对特定的问题的简洁优雅的一种解决方案。通俗一点的说,设计模式就是符合模中场景下某个问题的解决方案。通过设计模式可以增加代码的可重用性,可扩展性,可维护性,最终使得我们的代码高内聚、低耦合。
设计模式的五大设计原则:
- 单一职责:一个程序只需要做好一件事,如果功能过于复杂就拆分开,保证每个部分的独立
- 开放封闭原则:对扩展开放,对修改封闭。增加需求时,扩展新代码,而不是修改源代码,这是软件设计的终极目标
- 接口独立原则:保持接口的单一独立,避免出现“胖接口”。
- 依赖导致原则:面向接口编程,依赖于抽象而不依赖于具体,使用方只专注接口而不用专注具体类的实现,俗称“鸭子类型”。
设计模式:
- 工厂模式
- 抽象工厂模式
常用ES6语法
考察:
- 日常编码
- 是否有对新知识的探究
- js基础
答案:
- 解构
- 箭头函数(为什么有箭头函数,与普通函数的区别,arguments,构造函数,this)
- Set、WeakSet、Map、WeakMap
- 函数入参数的默认参数
- let、const
var、let、const的区别
这个我觉得是简单的,大概率是根据上一个问题直接问的。
考察:
- js基础
答案:
- 三个都是用了声明变量
- var是es6之前就有的,全局声明的变量可以通过window.xx访问
var test = 12;
window.test; // 12
- var不存在暂时死区,比如我们在第三行用var声明了一个变量text,我们在第二行是可以访问这个变量的,不过此时变量的值是undefined
console.log(text);
var test = '这是一个测试文案'
- 如果是let 声明的变量,在声明之前是不可以访问的,否则运行会报错
- const和let都是es6中出现的语法,const主要用于声明常量,const声明的简单数据类型是不可以修改的,const声明的对象,对象的属性是可以改变的
闭包
考点
- 基础概念
- 应用(考察是否有真正的理解)
答案
【概念】闭包是一个函数以及与其周围捆绑的周边环境的状态的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。在js中,闭包会随着函数的创建同时被创建(mdn-闭包)
【应用】其中比较经典的应用有防抖和节流
作用域
考点
- 熟练掌握基础概念
- 应用(属性的方案)
例题来源:(附面试题)深入理解作用域、作用域链和闭包
let x = 1;
function A(y){
let x = 2;
function B(z){
console.log(x+y+z);
}
return B;
}
let C = A(2);
C(3); // 7
答案
作用域是当前执行上下文,值或表达式在其中“可见”或可被访问。如果一个变量或表达式不在当前作用域中,那么它是不可用的,作用域也可以堆叠层次结构,子作用域可以访问父作用域,反过来则不行。【MDN】
继承原型链
考点
- 熟练掌握基础概念
- 实际应用
function Foo () {
this.a = 1;
}
Foo.a = 2;
Foo.prototype.a = 3;
const obj = new Foo();
console.log(obj.a);
console.log(Foo.a);
delete obj.a;
console.log(obj.a);
答案
每一个对象都有一个私有属性(proto),指向它的构造函数原型对象(prototype),该原型对象也有自己的原型对象(ptoto),层层向上,直到一个对象的原型对象是null。根据定义,null没有原型对象,并作为原型连上的最后一环。
项目中的编码规范,如何定位和落实编码规范
考点
- 实际的开发经验
- 开发中是否用心,开发细节和总结
答案
- 通过认为的来纠正编码存在非常大的不可控性,我们可以借助eslint工具,来做我们项目的代码规范。如果没有特殊需求,可以只用使用elint默认规则。对于vue和react项目,官方都有提供默认的编码规则,我们可以直接使用。
- 当项目中初次进入eslint的时候,肯定不能让所有的的文件都eslint报错,我们要用增量报错,逐渐规范整项目的编码规范
- 我们还需要准备编码规范文档,记录编码的规范规则