Administrator
Administrator
Published on 2025-04-14 / 6 Visits
0
0

JS面试点

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,则会被垃圾回收。

对不使用的变量进行手动删除引用,使其尽快被回收。


Comment