前端面试题-JS(四)
46 谈谈你对ES6的理解
- 新增模板字符串(为 JavaScript 提供了简单的字符串插值功能)
- 箭头函数
- for-of (⽤来遍历数据—例如数组中的值。)
- arguments 对象可被不定参数和默认参数完美代替。
- ES6 将p romise 对象纳⼊规范,提供了原⽣的 Promise 对象。
- 增加了 let 和 const 命令,⽤来声明变量。
- 增加了块级作⽤域。
- let 命令实际上就增加了块级作⽤域。
- 还有就是引⼊ module 模块的概念
47 ECMAScript6 怎么写class么
- 这个语法糖可以让有 OOP 基础的⼈更快上⼿ js ,⾄少是⼀个官⽅的实现了
- 但对熟悉 js 的⼈来说,这个东⻄没啥⼤影响;⼀个 Object.creat() 搞定继承,⽐class 简洁清晰的多
48 什么是⾯向对象编程及⾯向过程编程,它们的异同和优缺点
- ⾯向过程就是分析出解决问题所需要的步骤,然后⽤函数把这些步骤⼀步⼀步实现,使⽤的时候⼀个⼀个依次调⽤就可以了
- ⾯向对象是把构成问题事务分解成各个对象,建⽴对象的⽬的不是为了完成⼀个步骤,⽽是为了描叙某个事物在整个解决问题的步骤中的⾏为
- ⾯向对象是以功能来划分问题,⽽不是步骤
49 ⾯向对象编程思想
- 基本思想是使⽤对象,类,继承,封装等基本概念来进⾏程序设计
- 优点
- 易维护
- 采⽤⾯向对象思想设计的结构,可读性⾼,由于继承的存在,即使改变需求,那么维护也只是在局部模块,所以维护起来是⾮常⽅便和较低成本的
- 易扩展
- 开发⼯作的重⽤性、继承性⾼,降低重复⼯作量。
- 缩短了开发周期
- 易维护
50 对web标准、可⽤性、可访问性的理解
- 可⽤性(Usability):产品是否容易上⼿,⽤户能否完成任务,效率如何,以及这过程中⽤户的主观感受可好,是从⽤户的⻆度来看产品的质量。可⽤性好意味着产品质量⾼,是企业的核⼼竞争⼒
- 可访问性(Accessibility):Web内容对于残障⽤户的可阅读和可理解性
- 可维护性(Maintainability):⼀般包含两个层次,⼀是当系统出现问题时,快速定位并解决问题的成本,成本低则可维护性好。⼆是代码是否容易被⼈理解,是否容易修改和增强功能。
51 如何通过JS判断⼀个数组
- instanceof ⽅法
- instanceof 运算符是⽤来测试⼀个对象是否在其原型链原型构造函数的属性
var arr = [];
arr instanceof Array; // true
- constructor ⽅法
- constructor 属性返回对创建此对象的数组函数的引⽤,就是返回对象相对应的构造函数
var arr = [];
arr.constructor == Array; //true
-
最简单的⽅法
-
这种写法,是 jQuery 正在使⽤的
Object.prototype.toString.call(value) == '[object Array]'
// 利⽤这个⽅法,可以写⼀个返回数据类型的⽅法
var isType = function (obj) {
return Object.prototype.toString.call(obj).slice(8,-1);
}
- ES5 新增⽅法 isArray()
var a = new Array(123);
var b = new Date();
console.log(Array.isArray(a)); //true
console.log(Array.isArray(b)); //false
52 谈⼀谈let与var的区别
- let 命令不存在变量提升,如果在 let 前使⽤,会导致报错
- 如果块区中存在 let 和 const 命令,就会形成封闭作⽤域
- 不允许重复声明,因此,不能在函数内部重新声明参数
53 map与forEach的区别
- forEach ⽅法,是最基本的⽅法,就是遍历与循环,默认有3个传参:分别是遍历的数组内容 item 、数组索引 index 、和当前遍历数组 Array
- map ⽅法,基本⽤法与 forEach ⼀致,但是不同的,它会返回⼀个新的数组,所以在callback需要有 return 值,如果没有,会返回 undefined
54 谈⼀谈你理解的函数式编程
- 简单说,“函数式编程"是⼀种"编程范式”(programming paradigm),也就是如何编写程序的⽅法论
- 它具有以下特性:闭包和⾼阶函数、惰性计算、递归、函数是"第⼀等公⺠"、只⽤"表达式"
55 谈⼀谈箭头函数与普通函数的区别?
- 函数体内的 this 对象,就是定义时所在的对象,⽽不是使⽤时所在的对象
- 不可以当作构造函数,也就是说,不可以使⽤ new 命令,否则会抛出⼀个错误
- 不可以使⽤ arguments 对象,该对象在函数体内不存在。如果要⽤,可以⽤ Rest 参数代替
- 不可以使⽤ yield 命令,因此箭头函数不能⽤作 Generator 函数
56 谈⼀谈函数中this的指向
-
this的指向在函数定义的时候是确定不了的,只有函数执⾏的时候才能确定this到底指向谁,实际上this的最终指向的是那个调⽤它的对象
-
《javascript语⾔精髓》中⼤概概括了4种调⽤⽅式:
-
⽅法调⽤模式
-
函数调⽤模式
-
构造器调⽤模式
graph LR
A–>B -
apply/call调⽤模式
57 异步编程的实现⽅式
- 回调函数
- 优点:简单、容易理解
- 缺点:不利于维护,代码耦合⾼
- 事件监听(采⽤时间驱动模式,取决于某个事件是否发⽣):
- 优点:容易理解,可以绑定多个事件,每个事件可以指定多个回调函数
- 缺点:事件驱动型,流程不够清晰
- 发布/订阅(观察者模式)
- 类似于事件监听,但是可以通过‘消息中⼼ʼ,了解现在有多少发布者,多少订阅者
- Promise对象
- 优点:可以利⽤then⽅法,进⾏链式写法;可以书写错误时的回调函数;
- 缺点:编写和理解,相对⽐较难
- Generator函数
- 优点:函数体内外的数据交换、错误处理机制
- 缺点:流程管理不⽅便
- async函数
- 优点:内置执⾏器、更好的语义、更⼴的适⽤性、返回的是Promise、结构清晰。
- 缺点:错误处理机制
58 对原⽣Javascript了解程度
- 数据类型、运算、对象、Function、继承、闭包、作⽤域、原型链、事件、 RegExp 、JSON 、 Ajax 、 DOM 、 BOM 、内存泄漏、跨域、异步装载、模板引擎、前端 MVC 、路由、模块化、 Canvas 、 ECMAScript
59 Js动画与CSS动画区别及相应实现
- CSS3 的动画的优点
- 在性能上会稍微好⼀些,浏览器会对 CSS3 的动画做⼀些优化
- 代码相对简单
- 缺点
- 在动画控制上不够灵活
- 兼容性不好
- JavaScript 的动画正好弥补了这两个缺点,控制能⼒很强,可以单帧的控制、变换,同时写得好完全可以兼容 IE6 ,并且功能强⼤。对于⼀些复杂控制的动画,使⽤javascript 会⽐较靠谱。⽽在实现⼀些⼩的交互动效的时候,就多考虑考虑 CSS 吧
60 JS 数组和对象的遍历⽅式,以及⼏种⽅式的⽐较
- 通常我们会⽤循环的⽅式来遍历数组。但是循环是 导致js 性能问题的原因之⼀。⼀般我们会采⽤下⼏种⽅式来进⾏数组的遍历
- for in 循环
- for 循环
- forEach
- 这⾥的 forEach 回调中两个参数分别为 value , index
- forEach ⽆法遍历对象
- IE不⽀持该⽅法; Firefox 和 chrome ⽀持
- forEach ⽆法使⽤ break , continue 跳出循环,且使⽤ return 是跳过本次循环
- 这两种⽅法应该⾮常常⻅且使⽤很频繁。但实际上,这两种⽅法都存在性能问题
- 在⽅式⼀中, for-in 需要分析出 array 的每个属性,这个操作性能开销很⼤。⽤在key 已知的数组上是⾮常不划算的。所以尽量不要⽤ for-in ,除⾮你不清楚要处理哪些属性,例如 JSON 对象这样的情况
- 在⽅式2中,循环每进⾏⼀次,就要检查⼀下数组⻓度。读取属性(数组⻓度)要⽐读局部变量慢,尤其是当 array ⾥存放的都是 DOM 元素,因为每次读取都会扫描⼀遍⻚⾯上的选择器相关元素,速度会⼤⼤降低
61 gulp是什么
- gulp 是前端开发过程中⼀种基于流的代码构建⼯具,是⾃动化项⽬的构建利器;它不仅能对⽹站资源进⾏优化,⽽且在开发过程中很多重复的任务能够使⽤正确的⼯具⾃动完成
- Gulp的核⼼概念:流
- 流,简单来说就是建⽴在⾯向对象基础上的⼀种抽象的处理数据的⼯具。在流中,定义了
⼀些处理数据的基本操作,如读取数据,写⼊数据等,程序员是对流进⾏所有操作的,⽽
不⽤关⼼流的另⼀头数据的真正流向 - gulp正是通过流和代码优于配置的策略来尽量简化任务编写的⼯作
- Gulp的特点:
- 易于使⽤:通过代码优于配置的策略,gulp 让简单的任务简单,复杂的任务可管理
- 构建快速 利⽤ Node.js 流的威⼒,你可以快速构建项⽬并减少频繁的 IO 操作
- 易于学习 通过最少的 API ,掌握 gulp 毫不费⼒,构建⼯作尽在掌握:如同⼀系列流管道
62 说⼀下Vue的双向绑定数据的原理
- vue.js 则是采⽤数据劫持结合发布者-订阅者模式的⽅式,通过Object.defineProperty() 来劫持各个属性的 setter , getter ,在数据变动时发布消息给订阅者,触发相应的监听回调
63 事件的各个阶段
- 1:捕获阶段 —> 2:⽬标阶段 —> 3:冒泡阶段
- document —> target ⽬标 ----> document
- 由此, addEventListener 的第三个参数设置为 true 和 false 的区别已经⾮常清晰了
- true 表示该元素在事件的“捕获阶段”(由外往内传递时)响应事件
- false 表示该元素在事件的“冒泡阶段”(由内向外传递时)响应事件
64 let var const
let
- 允许你声明⼀个作⽤域被限制在块级中的变量、语句或者表达式
- let绑定不受变量提升的约束,这意味着let声明不会被提升到当前
- 该变量处于从块开始到初始化处理的“暂存死区”
var
- 声明变量的作⽤域限制在其声明位置的上下⽂中,⽽⾮声明变量总是全局的
- 由于变量声明(以及其他声明)总是在任意代码执⾏之前处理的,所以在代码中的任意位置声明变量总是等效于在代码开头声明
const
- 声明创建⼀个值的只读引⽤ (即指针)
- 基本数据当值发⽣改变时,那么其对应的指针也将发⽣改变,故造成 const 申明基本数据类型时
- 再将其值改变时,将会造成报错, 例如 const a = 3 ; a = 5 时 将会报错
- 但是如果是复合类型时,如果只改变复合类型的其中某个 Value 项时, 将还是正常使⽤
65 快速的让⼀个数组乱序
requestAnimationFrame 来每 16 ms 刷新⼀次
var arr = [1,2,3,4,5,6,7,8,9,10];
arr.sort(function(){
return Math.random() - 0.5;
})
console.log(arr);