new的实现原理
1.判断传入的是否为构造函数
2.创建空对象,同时设置对象的原型为构造函数的prototype
3.设置this为创建的空对象
4.执行构造函数
5.判断返回值为对对象或引用对象则返回这个值,若是一个原始值则返回创建对象
数组有哪些原生方法
1.shift
2.unshift
3.push
4.pop
5.filter
6.map
7.reduce
8.foreach
9.concat
10.sort
11.reverse
12.toString
13.slice
14.splice
15.indexOf
16.every、some
什么是DOM和BOM
DOM为文档对象模型,主要是用对象树来表示文档中的元素。
BOM为浏览器对象模型,主要是通过对象来表示浏览器中的元素,如window,它可以获取浏览器的一些信息,如window.location对象、window.screen对象,其中document也为window的子对象。
对类数组对象的理解,如何转化为数组
类数组拥有和数组相同的数据结构、同时还维护一个length属性。但是类数组中没有数组原生的方法。
通过Array.from可将类数组转化为数组。或者因为类数组数据结构和数组相同所以支持一些原生的数组方法,如Array.prototype.slice.call()来对类数组进行截取转化为数组。
对ajax的理解,实现一个ajax请求
ajax是对httpxmlrequest的一个封装,可以使用js进行异步请求。
js为什么要进行变量提升,造成了什么问题
因为在js编译时可以一次性将所有需要使用的变量或者函数声明,可以提升性能。
因为会变量提升,有时候进行异步操作时会读取同一个对象造成意外的错误。同时因为无法控制声明位置,所以只要在作用域中错误都会是undefined,这样不利于纠错。
js有哪些类型,有什么区别
基础类型:number、string、undefined、null、boolean
引用类型:object、symbol、bigInt
基础数据类型存放在内存的栈区域
引用数据类型存放在内存的堆区域
基础数据类型没有自带的方法
引用数据类型有自带的方法
数据类型检测的方法有哪些
1.typeOf xx === 'xx'
2.instanceOf()
3.constructor
4.Object.prototype.toString()
null和undefined的区别
null从字面意思来理解为空指针,原本是用来表示对象指针为空。
undefined意为没有定义
instanceof实现原理和实现
instanceOf通过查找输入对象的原型链中是否有对应对象来返回
function myInstanceof(left,right){
let proto = Object.getPrototypeOf(left)
const prototype = right.prototype
while(true){
if(!proto){
return false
}
if(proto === prototype){
return true
}
proto = Object.getPrototypeOf(proto)
}
}
为什么0.1+0.2 !==0.3,如何解决这个问题
因为js使用的时IEEE 754,在表示浮点数时会造成精度损失,0.1+0.2后不等于0.3,而是在很小的精度误差内。
可以通过设置精度范围或者直接舍入进行解决
==操作符强制转换的规则
会尽量转为数字进行比较
仅null和undefined进行比较时会相等
遇到对象时优先使用其valueOf方法,不行后使用toSrting方法。
Object.is()和===、==的区别
==在进行比较时,会对双方进行强制类型转换
===在进行比较时,不会对双方进行强制类型转化
Object.is()和===差不多,只是在-0和+0判断是为假,NaN和NaN时为真
let、const、var的区别
这三者都是声明变量的方式
var是ES6之前的语法。
var可以重复声明,会变量提升,为函数作用域。在最外层声明时会给windows对象添加一个全局的属性。
let和const都为ES6之后的语法。
let和const都没有变量提升、同时不能重复声明,作用域为块级作用域,它们的区别是const声明的变量不能修改。
箭头函数和普通函数的区别
箭头函数相较于普通函数写法更加简洁。
箭头函数没有this对象,如果在箭头函数中使用this则会向父级作用域进行寻找。
箭头函数无法使用当作构造函数
箭头函数没有arguments参数
箭头函数没有prototype
原型、原型链的理解
每个构造函数都有一个prototype属性,用来存放每个对象实例共享的方法和属性。每个实例中都会有一个__proto__属性,用于存放实例对象原型,即构造函数的prototype属性。在每个prototype属性中,都存有__proto__属性指向上一代原型。这样就形成了原型链。
原型链指向
promise的理解
promise是异步编程的一种解决方案,promise中一般包含了异步代码,它解决了回调地狱的问题。
promise拥有三个状态prending、fullfilled、rejected,对应为执行中、满足、拒绝。一旦转变状态就不可变了。
promise中的代码为同步代码,会立即执行,只有then、catch、finally中的代码为异步执行,为微任务。
promise的基本用法
const promise = new Promise((reslove,reject)=>{
}).then(res).catch().finally()
const promise1 = new Promise((reslove,reject)=>{
}).then(res).catch().finally()
const promise2 = new Promise((reslove,reject)=>{
}).then(res).catch().finally()
promise.all([promise,promise1,promise2]).then(res)
promise.race([promise,promise1,promise2]).then(res)
async和await的理解
async为一个promise的语法糖,可以用来修饰函数,表示这个函数内部可以使用await,同时将函数返回值包装为promise对象,在函数进行返回时,会将其转化为reslove(retrunValue)。
await为一个等待的语法,用于等待表达式,必须在async函数中使用,如果它等待得到的是一个promise对象,则会阻塞后面的代码,直到promise对象reslove,如果不是promise对象,则直接返回该对象。
async和awit对于promise的优势
async和awit不需要写大段的调用链,尽可能能接近同步的写法。
闭包的理解
闭包本质是作用域链的调用,函数内可以调用函数外的对象,同时可以保留上下文在内存中。
作用域、作用域链的理解
全局作用域:全局作用域为最外层的作用域,任何位置都可以调用全局作用域中的对象,但是如果泛滥定义全局对象,会造成对象使用的混乱,同时全局对象只有在程序结束后才会清除,在这期间一直存在内存中,如果全局对象过多会导致内存溢出。
函数作用域:声明的函数或者使用var声明的对象为函数作用域,函数作用域只有函数内部能够调用。
块级作用域:用const、let声明的对象为块级作用域,只能在块中使用。
作用域链:即如果使用的对象在本作用域中不存在,则会向外层作用域寻找。
执行上下文的理解
上下文分为全局执行上下文、函数执行上下文
全局执行上下文为最外层的执行上下文
函数执行上下文为每个函数执行时就会创建
执行上下文栈,在执行时若创建了执行上下文,则会将其压入执行上下文栈中,执行完毕则将其弹出。
在执行时,会创建一个全局上下文window。
this的理解
this用于指向最后一个调用的对象
函数执行的this指向window
作为方法执行时this指向这个对象
使用new时this指向生成的这个对象
使用call、bind、aplly调用时,this指向设置的对象
优先级 new > call、bind、aplly > 方法调用 > 函数调用
call和apply的区别
call和apply都是使用指定的对象调用某个函数,用于修改函数内部的this
call传入的第一个参数和apply相同,都是调用的对象,第二个参数不同,call为不定个数的参数,apply则传入的是数组。
实现call、apply、bind
function myCall(context){
const args = [...arguments].slice(1)
context = context || window
context.fn = this
const res = context.fn(...args)
delete context.fn
return res
}
对象创建的方式有哪些
对象继承的方式有哪些
浏览器的回收机制
浏览器会定期回收变量,在那些无法使用的变量会被回收,使用闭包可以避免变量被回收,全局变量只有在页面卸载的之后会回收。
浏览器回收机制有两种:
一种是标记回收:浏览器会从根节点开始遍历每个对象,对其进行标记,标记完成后进入清理阶段,如果变量不可达则不会被标记,便会被清除。
一种是引用回收:浏览器会为每一个变量添加一个计数器,若变量被创建、引用则会加一,若变量引用失效则减一,如果变量的计数为0,则会被垃圾回收。
对不使用的变量进行手动删除引用,使其尽快被回收。