ES6部分参考:ES6教程
let与var区别:代码块作用域、不能重复声明、不存在变量提升。
Symbol原始数据类型:表示独一无二的值,Symbol类型非Object类型,不可用new。 使用场景:作为对象属性名,避免重名属性覆盖;替代枚举常量;实现类的private属性和方法。
Symbol类型的key是不能通过Object.keys()
或者for...in
来枚举的,它未被包含在对象自身的属性名集合(property names)之中。也正因为这样一个特性,当使用JSON.stringify()
将对象转换成JSON字符串的时候,Symbol属性也会被排除在输出内容之外:我们可以利用这一特点来更好的设计我们的数据对象,让“对内操作”和“对外选择性输出”变得更加优雅。
专门针对Symbol的API:
// 使用Object的API
Object.getOwnPropertySymbols(obj) // [Symbol(name)]
// 使用新增的反射API
Reflect.ownKeys(obj) // [Symbol(name), 'age', 'title']
Map 对象保存键值对:Maps 和 Objects 的区别
- 一个Map 的键可以是任意值,但一个Object 的键只能是字符串或者 Symbols。
- Map 中的键值是有序的(FIFO 原则),而添加到对象中的键则不是(ASCII码顺序)。
- Map 的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算。
- Object 都有自己的原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。
Proxy 与 Reflect 是 ES6 为了操作对象引入的 API 。Proxy 可以对目标对象的操作进行拦截,然后进行操作处理。Reflect的就是Object的一个实例,主要将Object对象的一些静态方法放到Reflect对象上(明显属于语言内部的方法,如Object.defineProperty,Object.getOwnPropertyDescriptor),显得更优雅。
class 的本质是 function。它可以看作一个语法糖,让对象原型的写法更加清晰。
ES6 引入了模块化,其设计思想是在编译时就能确定模块的依赖关系,以及输入和输出的变量。ES6 的模块自动开启严格模式,不管你有没有在模块头部加上 use strict;。每个模块都有自己的上下文,每一个模块内声明的变量都是局部变量,不会污染全局作用域。
Promise的then 方法将返回一个 resolved 或 rejected 状态的 Promise 对象用于链式调用,且 Promise 对象的值就是返回值。
ES6 新引入了 Generator 函数,可以通过 yield 关键字,把函数的执行流挂起,为改变执行流程提供了可能,从而为异步编程提供解决方案。// 待深入
async 是 ES7 才有的与异步操作有关的关键字,和 Promise , Generator 有很大关联的。async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。await 关键字仅在 async function 中有效。await 将等待 Promise 正常处理完成并返回其处理结果。
1、JS单线程机制,何为事件循环,事件队列?JS和Node事件循环区别?
(一)https://www.cnblogs.com/johnnyzen/p/7894984.html --
(二)https://zhuanlan.zhihu.com/p/26962590 --
重点:
JavaScript引擎属于单线程作业。所谓单线程,是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个,也不妨叫它主线程。JavaScript引擎属于单线程作业,意味着:在同一时间只能执行一个代码块,这些代码块的执行就阻塞了异步事件的处理。[From JavaScript忍者秘籍]
HTML5 虽然增加了 Web Worker 标准,允许 JavaScript 创建多个线程,但子线程完全受主线程控制,不能操作 DOM,所以本没有改变 JavaScript 单线程的本质,但是其他耗时较久的任务可以通过 Web Worker 完成。
主线程内的任务执行完毕为空,会去 Event Queue 读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的 Event Loop (事件循环)。在事件循环中,每进行一次循环操作称为tick。
事件循环 机制和 消息队列 的维护是由事件触发线程控制的。事件触发线程 同样是浏览器渲染引擎提供的,它会维护一个 消息队列。
Event Loop在浏览器与node环境中的区别:
浏览器环境每次执行一个宏任务,再去检查微任务
node会清空当前所处阶段的队列,即执行所有task,再去检查微任务
浏览器的内核是多线程的,它们在内核控制下相互配合以保持同步,一个浏览器通常由以下常驻线程组成:GUI 渲染线程,javascript 引擎线程,浏览器事件触发线程,定时触发器线程,异步 http 请求线程。
应用:
定时器修正,setTimeout(func, 0)改变执行顺序。
setTimeout(fn,0)的含义是,它在"任务队列"的尾部添加一个事件,因此要等到主线程把同步任务和"任务队列"现有的事件都处理完,才会得到执行。在某种程度上,我们可以利用setTimeout(fn,0)的特性,修正浏览器的任务顺序。
2、防抖与节流
(一) https://mp.weixin.qq.com/s/U2cJoTODETIiYNUjk-sJCg
重点:
节流
和防抖
都是用来控制某些函数的调用频率。
节流的意思是函数被连续触发时,每隔delay时间执行一次。
防抖的意思是函数被连续触发时,稳定delay时间不触发后执行。
应用:
面试时要求手写实现。
3、模块化与闭包
重点:
闭包:通俗的讲就是函数a的内部函数b,被函数a外部的一个变量引用的时候,就创建了一个闭包。
模块化其实是建立在单例模式基础之上的,因此模块化开发和闭包息息相关。
4.1、JavaScript in操作,iterator(遍历器)属性,for of(ES6)语句
(一)in操作
4.2、JavaScript Object构造函数,JavaScript对象属性描述符,typeof、instanceof、Object.prototype.toString判断类型
(二)JavaScript对象属性描述符 -- get/set描述字面量写法
(三)
重点:
直接定义在构造函数上的属性/方法是静态的(只能通过构造函数访问/调用), 定义在构造函数的原型和实例上的属性/方法是非静态的。
5、内存泄漏、内存溢出、JavaScript垃圾回收
(二)垃圾回收机制
重点:
不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)。对于持续运行的服务进程(daemon),必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。
当程序运行需要的内存超过了剩余的内存时,就抛出内存溢出的错误。
6、JavaScript的this指向、
重点:
记住,js中的this指向是哪个对象触发函数执行,this就指向哪个对象。这个对象就是上下文context。
实际上 this 是隐藏的第一个形参。在你调用 person.sayHi() 时,这个 person 会「变成」 this。
7、ES5实现继承的方式,与ES6继承的区别
(一)es5实现继承
(二)ES5与ES6继承的区别
8、JavaScript常用设计模式