数据类型 (9种)
基本数据类型(栈):Number,String,Boolean,null,undefined,symbol(创建唯一值),bigint(后两个为ES6新增)
引用数据类型(堆):object,function
判断数据类型
1、typeof typeof 是一个操作符,返回该类型的字符串(全小写字母)形式表示,包括以下 7种:number、string、boolean、undefined、symbol、object、function 等。(对于 null,返回 object 类型。)
对于基本类型,除 null 以外,均可以返回正确的结果。
对于引用类型,除 function ,一律返回 object 类型。
2、instanceof 检测的是原型,instanceof 只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型。
3、toString是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] Object.prototype.toString.call('')
4、constructor是原型prototype的一个属性,当函数被定义时候,js引擎会为函数添加原型prototype,并且这个prototype中constructor属性指向函数引用, 因此重写prototype会丢失原来的constructor。
var、let、const
let 和 const 的优点?
let 和 const 有了块级作用域,变量声明不会提升相比于 var
var、let、const的区别
var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改。
普通函数、匿名函数、箭头函数
普通函数中的this:谁调用了函数或者方法,this指向谁
匿名函数中的this:指向是window,而不是调用该匿名函数的对象;
箭头函数中的this
箭头函数中的this是在函数定义的时候就确定下来的
箭头函数中的this指向父级作用域的执行上下文;
箭头函数无法使用apply、call和bind方法改变this指向
箭头函数与普通函数区别
箭头函数是匿名函数不能作为构造函数不能使用new
箭头函数不绑定arguments,需要用运算符解决…解决
箭头函数不绑定this,会捕获其所在的this值,作为自己的this值
箭头函数通过call()或apply()调用一个函数,只传入了一个参数,对this并没有影响.
箭头函数没有原型属性
new操作符具体干了什么呢
创建一个新的对象obj
将对象与构建函数通过原型链连接起来
将构建函数中的this绑定到新建的对象obj上
根据构建函数返回类型作判断,如果是原始值则被忽略,如果是返回对象,需要正常处理。
call, apply(数组), bind
作用:
都可以改变函数内部的this指向。
区别点:
call 和 apply 会调用函数,并且改变函数内部this指向。
call 和 apply 传递的参数不一样,call 传递参数arg1,arg2…形式 apply 必须数组形式[arg]
bind 不会调用函数,可以改变函数内部this指向。
eventloop, 宏任务和微任务
不停检查 Call Stack 中是否有任务(也叫栈帧)需要执行,如果没有,就检查 Event Queue,从中弹出一个任务,放入 Call Stack 中,如此往复循环。
1、所有同步任务都在主线程上执行,形成一个执行栈
2、主线程之外,还存在一个"消息队列"。只要异步操作执行完成,就到消息队列中排队
3、一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取消息队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行
4、主线程不断重复上面的第三步
宏任务(setTimeout, setInterval,setImmediate) Macrotask 宏任务是指Event Loop在每个阶段执行的任务
微任务 (Promises, Object.observe)Microtask 微任务是指Event Loop在每个阶段之间执行的任务
new promise 与同步一起,先微后宏
闭包 (概念, 用途, 手写)
一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围), 这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
闭包的特点:
让外部访问函数内部变量成为可能;
可以避免使用全局变量,防止全局变量污染;
可以让局部变量常驻在内存中;
会造成内存泄漏(有一块内存空间被长期占用,而不被释放)
function makeFunc() {var name = "Mozilla";function displayName() {alert(name);}return displayName;
}var myFunc = makeFunc();
myFunc();
继承 (extends, 原型链继承, 构造函数继承, 组合继承, 寄生组合继承)
深拷贝和浅拷贝
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象共享同一块内存。
深拷贝会创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
实现浅拷贝方法:
(1)Object.assign方法
(2)for in方法
实现深拷贝方法:
(1)采用递归去拷贝所有层级属性
(2)使用JSON.stringify和JSON.parse实现深拷贝:JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象;
(3)热门的函数库lodash,也有提供_.cloneDeep用来做深拷贝
Promise
Promise对象, 可以将异步操作以同步的流程表达出来。使用 Promise 主要有以下好处:
可以很好地解决回调地狱的问题(避免了层层嵌套的回调函数)。
语法非常简洁。Promise 对象提供了简洁的API,使得控制异步操作更加容易
new Promise(function(resolve, reject) then,catch,finally捕获错误
Promise.all(iterable) 方法返回一个 Promise 实例,此实例在 iterable 参数内所有的promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中promise 有一个失败(rejected),此实例回调失败(reject),失败的原因是第一个失败 promise的结果。
Promse.race Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
Ajax请求过程
创建 XMLHttpRequest 对象,也就是创建一个异步调用对象;
创建一个新的 HTTP 请求,并指定该 HTTP 请求的方法、 URL 以及验证信息;
设置响应 HTTP 请求状态变化的函数;
发送 HTTP 请求;
获取异步调用返回的数据;
使用 JavaScript 和 DOM 实现局部刷新。
AMD、CMD、CommonJs、ES6的对比
他们都是用于在模块化定义中使用的,前三个是ES5中提供的模块化编程的方案,
AMD: 是RequireJS在推广过程中对模块定义的规范化产出(依赖前置、异步定义)
通过define()函数定义,第一个参数是一个数组,里面定义一些需要依赖的包,第二个参数是一个回调函数,通过变量来引用模块里面的方法,最后通过return来输出。
CMD:是SeaJS在推广过程中对模块定义的规范化产出,(同步模块,没有前置依赖)
通过define()定义,没有依赖前置,通过require加载jQuery插件,CMD是依赖就近,在什么地方使用到插件就在什么地方require该插件,即用即返,这是一个同步的概念
CommonJs:是通过module.exports定义的,通过node.js后端使用的。
import/export:是ES6中定义新增的,对模块进行导出导入的
require,import和import()函数的区别
import命令会被 JavaScript 引擎静态分析,先于模块内的其他模块执行(叫做”连接“更合适)。
import()函数,完成动态加载。异步加载
require是运行时加载模块,只有运行时才知道,同步加载
ES6转化为ES5
https://blog.csdn.net/weixin_44135121/article/details/104161852
Parser 解析
第一步主要是将 ES6 语法解析为 AST 抽象语法树。简单地说就是将代码打散成颗粒组装的对象。这一步主要是通过 babylon 插件来完成。
Transformer 转换
第二步是将打散的 AST 语法通过配置好的 plugins(babel-traverse 对 AST 进行遍历转译)和 presets (es2015 / es2016 / es2017 / env / stage-0 / stage-4 其中 es20xx 表示转换成该年份批准的标准,env 是最新标准,stage-0 和 stage-4 是实验版)转换成新的 AST 语法。这一步主要是由 babel-transform 插件完成。plugins 和 presets 通常在 .babelrc 文件中配置。
Generator 生成
第三步是将新的 AST 语法树对象再生成浏览器都可以识别的 ES5 语法。这一步主要是由 babel-generator 插件完成