JS高频面试题

134 阅读16分钟

let、const、var的区别

1)块级作用域:块作用域由 { }包括,letconst具有块级作用域,var不存在块级作用域。
​
(2)变量提升:var存在变量提升,letconst不存在变量提升,即在变量只能在声明之后使用,否在会报错。
​
(3)重复声明:var声明变量时,可以重复声明变量,后声明的同名变量会覆盖之前声明的变量。constlet不允许重复声明变量。
​
(4)暂时性死区:在使用letconst命令声明变量之前,该变量都是不可用的。这在语法上,称为暂时性死区。使用var声明的变量不存在暂时性死区。
​
(5)初始值设置:在变量声明时,varlet 可以不用设置初始值。而const声明变量必须设置初始值

真数组和伪数组的区别

伪数组:
1、拥有length属性
2、不具有数组的方法
3、伪数组是一个Object,真数组是Array
4、伪数组的长度不可变,真数组的长度是可变的

值类型和引用类型的区别

1、值类型
    1)基本类型数据是值类型
    2)保存与复制的是值本身
    3)使用typeof检测数据的类型
    4) 存放在栈中
2、引用类型
    1)保存与复制的是指向对象的一个指针
    2)使用instanceof检测数据类型
    3)使用 new() 方法构造出的对象是引用型
    4)存放在堆中
值类型:
    1.占用空间固定,保存在栈中(当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁了。因此,所有在方法中定义的变量都是放在栈内存中;栈中存储的是基础变量以及一些对象的引用变量。基础变量的值是存储在栈中,而引用变量存储在栈中的是指向堆中的数组或对象的地址,这就是为什么修改引用类型总会影响到其它指向这个地址的引用变量)
    2.保存与复制的是值本身
    3.使用typeof检测数据的类型
    4.基本类型数据是值类型
引用类型:
    1.占用空间不固定,保存在堆中(当我们在程序中创建一个对象时,这个对象将被保存到运行时数据区中,一边反复利用(因为对象的创建成本通常较大),这个运行时数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(方法的参数传递时很常见),则这个对象依然不会被销毁,只有当一个对象没有任何引用变量引用时,系统的垃圾回收机制才会在核实的时候回收它。)
    2.保存与复制的是指向对象的一个指针
    3.使用instanceof检测数据类型
    4.使用new()方法构造出的对象是引用型
​

怎么理解面向对象

1、面向对象是一种软件开发的思想和面向过程是相对应的,就是把程序看作一个对象,将属性和方法封装其中,以提高代码的灵活性、复用性、可扩展性。
​
2、js面向对象有两大特性:封装、继承 
​
    封装:把相关的信息(无论数据或方法)存储在对象中的能力
​
    继承:由另一个类(或多个类)得来类的属性和方法的能力
​
  3、基本思想是使用对象,类,继承,封装等基本概念来进行程序设计
​
   易维护
​
   易扩展
​
   开发工作的重用性、继承性高,降低重复工作量。
​
   缩短了开发周期

什么是原型和原型链

答: 原型: 函数都有prototype属性,这个属性的值是个对象,称之为原型
   原型链: 对象都有__proto__属性,这个属性指向它的原型对象,原型对象也是对象,也有__proto__属性,指向原型对象的原型对象,这样一层一层形成的链式结构称为原型链.
   
   对象
​
普通对象、数组、正则、Math、arguments...
实例是对象类型的(除了基本类型的字面量创建的值)
prototype 的值也是对象类型的
函数也是对象类型的
​
原型(prototype)
​
​
所有的函数数据类型都天生自带一个属性:prototype(原型),这个属性的值是一个对象,浏览器会默认给它开辟一个堆内存
​
​
在浏览器给 prototype 开辟的堆内存中有一个天生自带的属性: constructor, 这个属性存储的值是当前函数本身
​
​
每一个对象都有一个 __proto__ 的属性,这个属性指向当前实例所属类的 prototype (如果不能确定它是谁的实例,都是 object 的实例)
​
​
每一个类都把供实例调取的公共属性方法存储到自己的原型上(原型 prototype 的作用就是存储一些公共的属性和方法,供它的实例调取和使用)。
JS 在创建对象的时候,都有一个 __proto__的内置属性,用于指向创建它的构造函数的原型对象。
​
​
原型链
​
它是一种基于 __proto__向上查找的机制。当我们操作实例的某个属性或者方法的时候,首先找自己空间中私有的属性或者方法
找到了,则结束查找,使用自己私有的即可
没有找到,则基于** proto** 找所属类 prototype ,如果找到就用这个公有的,如果没找到,基于原型上的_ __proto__继续向上查找, 一直找到 0bject.prototype 的原型为止,如果在没有,操作的属性或者方法不存在
每个对象都有 __proto__ 属性,但只有函数对象才有 prototype 属性

call、apply和bind的区别

答: 1. call和apply方法都可以调用函数,方法内的第一个参数可以修改this的指向
    2. call方法可以有多个参数,除了第一个参数,其他参数作为实参传递给函数
       apply方法最多有2个参数,第二个参数是个数组或伪数组,数组里面的每一项作为实参传递给函数
    3. bind方法不能调用函数,它会创建一个副本函数,并且绑定新函数的this指向bind返回的新的函数

GET和POST的请求的区别

Post 和 Get 是 HTTP 请求的两种方法,其区别如下:

●
应用场景:GET 请求是一个幂等的请求,一般 Get 请求用于对服务器资源不会产生影响的场景,比如说请求一个网页的资源。而 Post 不是一个幂等的请求,一般用于对服务器资源会产生影响的情景,比如注册用户这一类的操作。
●
是否缓存:因为两者应用场景不同,浏览器一般会对 Get 请求缓存,但很少对 Post 请求缓存。
●
发送的报文格式:Get 请求的报文中实体部分为空,Post 请求的报文中实体部分一般为向服务器发送的数据。
●
安全性:Get 请求可以将请求的参数放入 url 中向服务器发送,这样的做法相对于 Post 请求来说是不太安全的,因为请求的 url 会被保留在历史记录中。
●
请求长度:浏览器由于对 url 长度的限制,所以会影响 get 请求发送数据时的长度。这个限制是浏览器规定的,并不是 RFC 规定的。
●
参数类型:post 的参数传递支持更多的数据类型。

如果我们直接在浏览器的地址栏 输入 接口的地址 方式 也是 属于 get请求中的一种!!

POST和PUT请求的区别

●
PUT请求是向服务器端发送数据,从而修改数据的内容,但是不会增加数据的种类等,也就是说无论进行多少次PUT操作,其结果并没有不同。(可以理解为时更新数据)
●
POST请求是向服务器端发送数据,该请求会改变数据的种类等资源,它会创建新的内容。(可以理解为是创建数据)

项目中常遇到的http响应状态码有哪些

答: 200  请求成功,  2开头的异步表示请求成功
		304  3表示重定向  304表示该数据可以由客户端的缓存来提供
		400  请求格式错误,  4开头的一般表示请求错误
		404  请求的资源(网页)不存在,  
		500  内部服务器错误,  5开头的一般都是指服务器错误

原生 ajax 请求的步骤

答:1.创建异步对象 var xhr = new HTMLHttpRequest()
    2.设置请求行  xhr.open()
    3.设置请求头  xhr.setRequestHeader()   
    4.设置请求体  xhr.send();
    5.监听数据响应  xhr.addEventListener("load",function(){})

返回false的情况有哪些

答: 0  ""   null  false  NaN  undefined 不成立的表达式

如何阻止冒泡和默认行为

答: 阻止冒泡和捕获  e.stopPropagation()
    阻止默认行为   e.preventDefault()

jsonp的原理

 利用script标签的src属性具有天然可跨域的特性,由服务端返回一个预先定义好的Javascript函数的调用,并且将服务器数据以该函ruhe数参数的形式响应给浏览器.

什么是同源策略?怎么解决跨域问题

答: 同源策略: 同源策略是浏览器的一种安全策略, 所谓同源是指域名、协议、端口完全相同,不同源则跨域。
   解决跨域的方法: 
			1. 通过jsonp跨域
			2. 跨域资源共享(CORS )

localStorage、sessionStorage和cookie的区别

答: 共同点: 都是保存在浏览器端,且同源的。
	区别: 
	1. 请求不同: 
		cookie 数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。
				sessionStorage 和 localStorage不会自动把数据发给服务器,仅在本地保存。
	2. 存储大小限制也不同: 
		cookie 数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。
		sessionStorage 和 localStorage虽然也有存储大小的限制,但比cookie大得多,sessionStorage约5M、localStorage约5M 。
	3. 数据有效期不同: 
		 sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持; 
		 localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;
		 cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。

怎么理解函数的防抖和节流

答:
1、定义:
防抖: 就是指触发事件后在n秒内函数只能执行一次,如果在n秒内又触发了事件,则会重新计算函数执行时间。
     例如:设定1000毫秒执行,当你触发事件了,他会1000毫秒后执行,但是在还剩500毫秒的时候你又触发了事件,那就会重新开始1000毫秒之后再执行

节流: 就是指连续触发事件但是在设定的一段时间内中只执行一次函数。
     例如:设定1000毫秒执行,那你在1000毫秒触发在多次,也只在1000毫秒后执行一次
     
2、防抖和节流的实现:
    <body>
    <input type="text" class="ipt" />
    <script>
      var timerId = null
      document.querySelector('.ipt').onkeyup = function () {
        // 防抖
        if (timerId !== null) {
          clearTimeout(timerId)
        }
        timerId = setTimeout(() => {
          console.log('我是防抖')
        }, 1000)
      }

      document.querySelector('.ipt').onkeyup = function () {
        // 节流
        console.log(2)
        if (timerId !== null) {
          return
        }

        timerId = setTimeout(() => {
          console.log('我是节流')
          timerId = null
        }, 1000)
      }

    </script>
  </body>

js的运行机制是什么

答:js是单线程执行的,页面加载时,会自上而下执行主线程上的同步任务,当主线程代码执行完毕时,才开始执行在任务队列中的异步任务。具体如下  
    1.所有同步任务都在主线程上执行,形成一个执行栈。
    2.主线程之外,还存在一个"任务队列(eventloop队列或者消息队列)"。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
    3.一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。哪些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
    4.主线程不断重复上面的第三步。

token

答: token 是服务端生成的“令牌”,来标识不同身份的
    用来鉴别用户的身份的,在登录成功后可以获取到

git如何管理一个项目和git如何解决合并冲突

1、git管理项目流程
答: 1、git init初始化git仓库(新项目才有这一步)
    2、git clone将远程仓库的项目资料下载下来
    3、git checkout -b dev (dev 创建并切换到dev分支)
    4、git add .将工作区文件存在暂存区
    4、git commit -m  ""从暂存区存到仓储区
    5、git checkout master切到master分支
    6、git merge dev 合并分支,合并后要将分支删除
    7、使用git push将其上传到远程仓库
    8、第二上班,先pull一下,更新最新代码

iframe有那些缺点?

    iframe会阻塞主页面的Onload事件;
    搜索引擎的检索程序无法解读这种页面,不利于SEO;
    iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。

你如何优化自己的代码?

代码重用

拆分函数避免函数过于臃肿:单一职责原则

适当的注释,尤其是一些复杂的业务逻辑或者是计算逻辑,都应该写出这个业务逻辑的具体过程

内存管理,尤其是闭包中的变量释放

谈谈this对象的理解

普通函数中:this ==> window

箭头函数: 没有this指向 

定时器中:this ==> window

构造函数中:this ==> 当前实例对象

对象的方法中:this ==> 当前实例对象

原型对象的方法中:this ==> 当前实例对象

事件处理函数中:this ==> 事件触发对象

this指向、new关键字

this对象是执行上下文中的一个属性,它指向最后一次调用这个方法的对象,在全局函数中,this等于window,而当函数被作为某个对象调用时,this等于那个对象。 在实际开发中,this 的指向可以通过四种调用模式来判断。

函数调用,当一个函数不是一个对象的属性时,直接作为函数来调用时,this指向全局对象。

方法调用,如果一个函数作为一个对象的方法来调用时,this指向这个对象。

构造函数调用,this指向这个用new新创建的对象。

第四种是 apply 、 call 和 bind 调用模式,这三个方法都可以显示的指定调用函数的 this 指向。apply接收参数的是数组,call接受参数列表,`` bind方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this指向除了使用new 时会被改变,其他情况下都不会改变。
通过call()、apply()、bind()方法把对象绑定到this上,叫做显式绑定。对于被调用的函数来说,叫做间接调用。

call、apply、bind三者的第一个参数都是this要指向的对象

new

首先创建了一个新的空对象

设置原型,将对象的原型设置为函数的prototype对象。

让函数的this指向这个对象,执行构造函数的代码(为这个新对象添加属性)

判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。

数组的遍历方法有哪些

方法特点
forEach()数组方法,不改变原数组,没有返回值
map()数组方法,不改变原数组,有返回值,可链式调用
filter()数组方法,过滤数组,返回包含符合条件的元素的数组,可链式调用
every() 和 some()数组方法,some()只要有一个是true,便返回true;而every()只要有一个是false,便返回false.
find() 和 findIndex()数组方法,find()返回的是第一个符合条件的值;findIndex()返回的是第一个返回条件的值的索引值

怎么理解同步和异步

	1、javascript是单线程。单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。于是就有一个概念——任务队列。
	2、同步任务,顾名思义,就是立即执行的任务,同步任务一般会直接进入到主线程中执行;而异步任务,就是异步执行的任务,比如ajax网络请求,setTimeout 定时函数等都属于异步任务,异步任务会通过任务队列( Event Queue )的机制来进行协调。

node中模块分为几大类

1 内置模块 也叫内置模块 在安装node的时候自带就有了,比如 fs是文件系统模块、http是创建服务器模块

2 自定义模块 自己创建的模块,也可以理解为一个js文件

3 第三方模块 其他程序员创建的模块,并且发布到了npm网站上可以提供其他用户下载使用

如何判断当前的js文件是运行在浏览器端还是ndoe端

通过判断 this 对象是否为window,如果不为window,当前脚本没有运行在浏览器中 this === window ? 'browser' : 'node';

console.log(this)

什么是错误优先的回调函数?

错误优先的回调函数用于传递错误和数据。第一个参数始终应该是一个错误对象, 用于检查程序是否发生了错误。其余的参数用于传递数据。

fs.readFile(filePath, function(err, data) {  
    if (err) {
        // 出错处理
    }else{

      // 正常的业务
    }
});

什么是webpack

webpack是一个打包模块化javascript的工具,在webpack里一切文件皆模块,通过loader转换文件,通过plugin注入钩子,最后输出由多个模块组合成的文件,webpack专注构建模块化项目

Webpack的优点是什么

  1. 专注于处理模块化的项目,能做到开箱即用,一步到位
  2. 通过plugin扩展,完整好用又不失灵活
  3. 通过loaders扩展, 可以让webpack把所有类型的文件都解析打包
  4. 社区区庞大活跃,经常引入紧跟时代发展的新特性,能为大多数场景找到已有的开源扩展