什么是函数防抖和函数节流?有什么区别?
函数防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
函数节流,就是限制一个函数在一定时间内只能执行一次。
什么是函数柯里化及有什么用?
函数柯里化
就是给函数分步传递参数,每次传递部分参数,并返回一个更具体的函数接收剩下的参数,这中间可嵌套多层这样的接收部分参数的函数,直至返回最后结果。
函数柯里化有什么用?
通过函数柯里化,我们可以实现参数复用、提前返回和延迟执行。通过函数柯里化,在不同的情况下传递不同的参数
谈谈模块化开发
什么是模块化开发?
模块就是完成单一的职责的功能函数或者代码块。
模块化开发是指如何开发新的模块和复用已有的模块来实现应用的功能。
为什么要模块化开发?
可维护性
可测试性
按需加载
代码复用
利于架构
利于协作
对于我们前端来说,特别是解决了javascript中命名空间以及文件依赖的问题。
模块化开发的规范
CommonJS
用于服务端模块化编程,Node.js就采用此规范;
一个文件就是一个模块,require方法用来加载模块,该方法读取一个文件并执行,最后返回文件内部的module.exports对象;
AMD
require.js(前端模块化管理的工具库)实现js文件的异步加载,避免网页失去响应;管理模块之间的依赖性,便于代码的编写和维护;require.js是使用创建script元素,通过指定script元素的src属性来实现加载模块的;
依赖前置,尽早的执行模依赖块,执行顺序不一定;
CMD
Sea.js 依赖就近,且在真正需要使用依赖模块时才执行该模块,顺序固定;
AMD和CMD最大的区别是对依赖模块的执行时机处理不同,而不是加载的时机或者方式不同,二者皆为异步加载模块;
AMD依赖前置,js可以方便知道依赖模块是谁,立即加载;而CMD就近依赖,需要使用把模块变为字符串解析一遍才知道依赖了那些模块。
ES6
ES6使用的是基于文件的模块。所以必须一个文件一个模块,不能将多个模块合并到单个文件中去。
ES6模块API是静态的,一旦导入模块后,无法再在程序运行过程中增添方法。
ES6模块采用引用绑定(可以理解为指针)。这点和CommonJS中的值绑定不同,如果你的模块在运行过程中修改了导出的变量值,就会反映到使用模块的代码中去。所以,不推荐在模块中修改导出值,导出的变量应该是静态的。
ES6模块采用的是单例模式,每次对同一个模块的导入其实都指向同一个实例。
另外,ES6模块好处很多,但是并不支持按需加载的功能, 而按需加载又是Web性能优化中重要的一个环节。好在我们可以借助Webpack来弥补这一缺陷
谈谈你对作用域链的理解
什么是作用域?
作用域就是变量与函数的可访问范围。在JavaScript中,变量的作用域有全局作用域和局部作用域,在ES6之后,又添加了块级作用域的概念,所以在JavaScript中有三种作用域。对于javascript而言,我们定义在局部作用域或者块级作用的变量,会存放在scope局部作用域对象上,而定义在全局作用域的变量,会存放在window/global这个全局对象上。
当我们在局部/块级作用域中,调用一个外部的变量时,就会产生作用域链。函数在哪里创建,它就会从哪里开始向上查找变量;而不是函数在哪里调用。
什么是深拷贝?什么是浅拷贝?如何实现一个深拷贝函数?
深拷贝和浅拷贝都是针对于引用类型(Object)而言,对于基本数据类型而言,赋值直接就是深拷贝。
浅拷贝有两种定义,一种是直接赋值引用,另一种是只拷贝对象的第一层属性,更深层次的引用还是相同的;
深拷贝就是将原有对象重新拷贝一份,不论是修改哪一部分的值,都不会对原有对象造成影响。拷贝的永远是值,而不是引用。