前端面试题汇总集锦

2018前端面试题之原理篇

2018-10-17  本文已影响9人  岁寒3友

天下熙熙皆为利来,天下攘攘皆为利往...
又是一年金九银十,肯定很多同行小伙伴们已经换工作了,可能有些在考虑的路上,整理一些原理面试题供大家参考,希望有所帮助,水平有限,如有错误,不吝赐教。

1.什么是作用域?

作用域就是一套规则,用于确定何处以及如何查找变量(标识符)的规则,通俗讲作用域就是查找变量的地方。
在JavaScript中,每一个函数都有各自的作用域(scope)。只有在函数内部的变量才可以访问到该函数域的变量。
在同一个作用域内部,变量名必须唯一。作用域可以嵌套。在最内部的作用域中,可以访问任何外部的作用域的变量。

2.js引擎中存在两种不同的查询方式 RHS(Right-hand Side)和 LHS

var name= "zmy"; 分为编译和运行阶段
A.编译器在当前作用域声明一个变量
B.运行时引擎在作用域中查找变量,找到name然后为其赋值

3.编译器如何工作的?

代码执行前从上到下进行编译,遇到某个var声明的变量,先检查当前作用域 是否存在该变量。如果存在,忽略声明;不存在,则在该作用域声明。

4.什么是闭包?什么时候使用?

1.闭包是指有权访问另一个函数作用域中的变量的函数;--《JavaScript高级程 序设计》
2.当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当 前词法作用域之外执行。--《你不知道的JavaScript》

闭包的应用比较典型是定义模块,我们将操作函数暴露给外部,而细节隐藏在 模块内部

5.【场景模式】:在一款实时性要求比较高的应用里,应用列表的数据,不仅要在应用列表中显示,侧边栏里也会显示应用的数量,还有很多下拉菜单里面也会出现它。如何实现一处数据更新处处更新了?

此题考查是否了解redux /rxjs 类库,比如弄个全局的状态树,各个组件使用全局的状态,这样可以保证数据的一致,但redux 在面对复杂的异步逻辑时就无能为力,此时可以考虑rxjs中的流。

6.观察者模式和发布订阅模式

这两种是在JavaScript常见的设计模式,首先要区分观察者模式和发布订阅模式并非等同,观察者模式是一种紧耦合的状态,而发布/订阅模式是一种松耦合的状态。由于内容篇幅较长读者请自行查阅相关知识,掌握两种设计模式的优缺点最好方法就是动手去实现。

7. typeof 实现原理?

原理是这样的, 不同的对象在底层都表示为二进制, 在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型, null 的二进制表示是全 0, 自然前三位也是 0, 所以执行 typeof 时会返回“object”。 ----《你不知道的JavaScript》
在 javascript 的最初版本中,使用的 32位系统,为了性能考虑使用低位存储了变量的类型信息:

typeof null === 'object';
null instanceof Object === false
if (JSVAL_IS_VOID(v)) {  // 判断是否为 undefined
    type = JSTYPE_VOID;
} else if (JSVAL_IS_OBJECT(v)) {  // 如果不是 undefined,判断是否为对象
    obj = JSVAL_TO_OBJECT(v);
    if (obj &&
        (ops = obj->map->ops,
            ops == &js_ObjectOps
            ? (clasp = OBJ_GET_CLASS(cx, obj),
            clasp->call || clasp == &js_FunctionClass) 
            : ops->call != 0)) { 
        type = JSTYPE_FUNCTION;
    } else {
        type = JSTYPE_OBJECT;
    }
} else if (JSVAL_IS_NUMBER(v)) { //如果不是对象,判断是否为数字
    type = JSTYPE_NUMBER;
} else if (JSVAL_IS_STRING(v)) {  //判断是否为字符串
    type = JSTYPE_STRING; 
} else if (JSVAL_IS_BOOLEAN(v)) { //判断是否为布尔值
    type = JSTYPE_BOOLEAN;
}
8. js中instanceof是如何实现的?

instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。

a instanceof A 意思是说a.proto能不能在A的原型链上找得到,如下判断

a.__proto__ === A.prototype || a.__proto__.__proto__ === A.prototype || ...
9【场景模式】高考剩下几天了倒计时 怎样手写一个倒计时页面 (HTML5 requestAnimationFrame)

计时器一直是javascript动画的核心技术。而编写动画循环的关键是要知道延迟时间多长合适。一方面,循环间隔必须足够短,这样才能让不同的动画效果显得平滑流畅;另一方面,循环间隔还要足够长,这样才能确保浏览器有能力渲染产生的变化
大多数电脑显示器的刷新频率是60Hz,大概相当于每秒钟重绘60次。大多数浏览器都会对重绘操作加以限制,不超过显示器的重绘频率,因为即使超过那个频率用户体验也不会有提升。因此,最平滑动画的最佳循环间隔是1000ms/60,约等于16.6ms

requestAnimationFrame

requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率
在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的CPU、GPU和内存使用量
requestAnimationFrame是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销

10.实现原生ajax请求

ajax的面试题太常见了,但依然很多用人单位会让你白板(手写)原生ajax请求,你掌握了吗?

function createXHR() {
    
  if (window.XMLHttpRequest) {
        
    return new XMLHttpRequest();
    
  } else {
        // 兼容IE5和IE6
    return new ActiveXObject('Microsoft.XMLHttp');
  }

}

var xhr = createXHR();
xhr.onReadyStateChange = function() {
  if (xhr.readyState == 4) {
    // 状态码为200至300之间或304都表示这一请求已经成功
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
            console.log(xhr.responseText)
        } else {
            ...
        }
    }
}

// GET
xhr.open('GET', url);
xhr.send();

// POST
xhr.open('POST', url);
xhr.send(data);
上一篇下一篇

猜你喜欢

热点阅读