JavaScript常见面试题(包含ES6)

1. 创建js对象的两种方法

  • 使用new Object()或者{}

2. 创建数组的两种方法

  • 使用new Array()或者[]

3. 数组去重

  1. 遍历数组法,实现思路:新建一新数组,遍历传入数组,值不在新数组就加入该新数组中;注意点:判断值是否在数组的方法“indexOf”是ECMAScript5 方法,IE8以下不支持,需多写一些兼容低版本浏览器代码
  2. 对象键值对法,实现思路:新建一个对象和一个新数组,取出每一个旧数组的值,然后看对象中有没有以该值为键的数据,如果没有则将该值作为键加入对象,取该值的数据类型type作为键的值,并把该值加入新数组,如果对象中有该对应的键,还需要使用indexof判断一下该键对应的值有没有type,没有则按照以上步骤添加新键和将值存入新数组
  3. 数组下标判断法,实现思路:使用indexof,如果当前数组的第i项在当前数组中第一次出现的位置不是i,那么表示第i项是重复的,忽略掉。否则存入结果数组

4.什么是变量提升

  • 无论是那里的变量在它声明之后,js引擎会将这个变量的声明移到该变量作用域的顶部

5.全局变量有什么风险,以及如何保护代码不受干扰?

  • 全局变量的危险之处在于其他人可以创建相同名称的变量,然后覆盖你正在使用的变量
  • 解决方法:
    1. 创建一个包含其他所有变量的全局对象,然后当我们要添加全局变量的时候就可以直接添加到这个对象下
    2. 将所有代码封装到一个可以自动执行的函数里

6.什么是闭包(Closure)?

  • 闭包就是将一个函数定义在一个外部函数的内部,用来读取外部函数的变量,外部函数将这个定义在外部函数的函数作为返回值。
    1. 闭包可以读取函数内部的值 2. 可以是变量的值始终保存在内存里

7.Java和JavaScript有什么不同

  • Java是面向对象的编程语言,JavaScript是面向对象的脚本语言
  • Java运行在虚拟机或者浏览器上,JavaScript运行在浏览器或者node环境上

8.JavaScript的特性是什么

  • 轻量级、解释型的脚本语言
  • 跨平台性
  • 弱类型的脚本语言
  • 单线程
  • 面向对象

9.JS中的参数对象是什么&如何获得传递给函数的参数类型

  • JS 变量arguments表示传递给函数的参数。 使用typeof运算符,可以获得传递给函数的参数类型

10.什么是回调

  • 回调函数是作为参数传递给某个函数的普通js函数,它将在另一个函数执行完之后进行调用,所以称为回调函数

11.列出一些内置方法和返回值

  • Concat:连接两个或多个字符串
  • indexOf() :它返回指定值第一次出现时调用字符串对象中的索引。
  • pop() 它从数组中删除最后一个元素并返回该元素。
  • push() 它将一个或多个元素添加到数组的末尾,并返回数组的新长度

12.列出在JS代码中访问HTML元素的不同方式

  • getElementById(‘idname’): 按id名称获取元素
  • getElementsByClass(‘classname’): 获取具有给定类名的所有元素
  • getElementsByTagName(‘tagname’): 获取具有给定标记名称的所有元素
  • querySelector(): 此函数采用css样式选择器并返回第一个选定元素

12.window 与 document 的区别

  • window是全局对象,它包含属性,方法,history,location
  • documnet也是位于window之下

13JS中的事件冒泡是什么

  • 事件冒泡是HTML DOM中事件传播的一种方式,当一个事件发生时,如果该元素和其祖先元素也定义了该事件的句柄,那么该事件会首先被在最内部的元素捕获和处理,然后被其父元素捕获和处理,然后这样一层层往上

14.JS的原始类型(基本数据类型)和对象类型如何在函数中传递?

  • 原始类型是值传递
  • 对象类型是引用传递

15.JS中的“严格”模式是什么以及如何启用?

  • 严格模式是在代码中引入更好的错误检查的一种方法。
    1. 当使用严格模式时,不能使用隐式声明的变量,或为只读属性赋值,或向不可扩展的对象添加属性。
    2. 可以通过在文件,程序或函数的开头添加use strict来启用严格模式

16.call 和 apply有什么区别

  • call和apply都是用来重新定义函数的执行环境,也就是this的指向,他们的差别在于参数,第一个参数两者都相同,是要重新定义的执行环境(也就是this指向),后面call是传入参数列表,apply是传入参数数组

17.如何在JS中清空数组

  • arrayList = []:将变量arrayList设置为一个新的空数组(相当于新建一个数组),如果其他地方没有对这个数组的引用可以使用这种方法,否则对应堆中数组并没有清空
  • arrayList.length = 0:将变量arrayList的长度设置为0,不管有没有其他地方引用该数组,都能清空
  • arrayList.splice(0, arrayList.length):删除从0开始的length条数据

18.js中的delete有什么用

  • 只能删除对象的属性

19.为什么要将JS源文件的全部内容包装在一个函数中

  • 其实是用来解决不同js模块和库之间潜在的命名冲突问题,这样使得每个模块都有一个私有的命名空间

20.数组操作

  • push():在数组末尾添加一个或多个元素,返回新的长度
  • pop():删除返回数组的最后一个元素
  • shift():删除返回数组的第一个元素
  • unshift():添加一个或多个元素,返回新的长度
  • splice():删除元素并向数组加入新元素splice(index,length,arr1,arr2),删除、添加index位置开始的元素,包括index
  • reverse():将数组元素顺序颠倒
  • sort():对数组元素进行排序(默认按照ASCII),可以自定义排序方式 sort((a,b)=>{只有返回值大于零,a、b位置互换})
  • forEach():用于数组遍历,Array.forEach(遍历处理函数)
  • map():用于对数组里的元素执行相同的函数,返回一个处理后的数组newArray = oldArray.map(遍历处理函数)
  • concat():连接两个或多个数组
  • join():将所有的元素拼接成一个字符串,指定分隔符进行分割array.join(separator),separator是分隔符,可选
  • indexOf():返回指定值在数组中第一次出现位置的下标array.indexOf(值)

21.JavaScript是同步的还是异步的语言

  • 准确来说JavaScript是一门单线程语言,不能同时处理多个任务和流程。所有任务分为两种,分别是同步任务和异步任务
  • 同步任务是直接在主线程排队执行的任务,只有前一个任务执行完毕才能执行后一个任务。
  • 异步任务则是不进入主线程,而进入任务队列的任务,只要异步任务有了运行结果,就会在任务队列放置一个事件。等主线程的同步任务执行完这些异步任务才会进入主线程执行。

22.宏任务和微任务

宏任务是由js运行的环境发起的(setTimeOut,setInterval),微任务是由JavaScript自身发起的(promise,process.nextTick)。Event loop(事件循环)执行顺序

  1. 先执行宏任务的同步代码
  2. 再执行微任务队列
  3. 如果执行环境为浏览器,会先进行渲染页面
  4. 再执行宏任务中的异步事件

23.js的原型链

js的实例对象有一个默认的属性_proto_指向该实例对象构造函数的原型(相当于上一层的实例对象),构造函数中的prototype属性指向原型,原型中的constructor指向构造函数。当我们访问一个对象的属性时,如果在该对象找不到该属性,就回到他的原型中寻找,找不到再去原型的原型中寻找,直到找到null对象,null对象没有原型

24.深拷贝和浅拷贝

他们的区别是否用的是同一块堆内存,浅拷贝只是复制了对象的引用,深拷贝则是新建一个对象,然后将源对象的所有属性和方法复制到新对象

25.事件委托

事件委托就是不在事件的发生地设置响应函数,而在父元素设置响应函数,通过冒泡,父元素可以监听到子元素事件的触发,父元素根据事件源的不同做出不同的响应。
其中有一个兼容性问题是标准浏览器用的是event.target,IE浏览器用的是event.srcElement。我们进行判断的时候会使用到target.nodeName.toLowerCase()转换成小写进行判断

26.ES6

let、const和var之间的区别

  • var只有全局作用域和函数作用域,并且存在变量提升,声明的变量会作为全局对象window的属性
  • let只有块作用域,并且不存在变量提升,在作用域顶部到变量声明之间的地方使用变量会报错,此称为“暂时性死区”
  • const定义的是常量,块作用域,不存在变量提升

promise

promise对象表示将来要发生的事,用来传递异步操作的消息,promise对象有三种状态,pendding(初始状态)/fulfilled(操作成功)/rejected(操作失败),一旦状态改变就不会再变。有了promise对象,我们就可以将异步操作以同步操作的流程写出来,避免了层层嵌套的回调函数。

   	    let promise = new Promise((resolve, reject) => {
   	    	if(success) {
   	    		resolve() // 执行成功
   	    	} else {
   	    		reject()  // 执行失败
   	    	}
   	    })
   	    promise.then(res => {}).catch(err => {})

展开运算符…

将一个数组转为以逗号分隔的参数序列

async和await

  • async作为一个关键字放在函数的前面个,用来表示这个函数是一个异步函数,这个函数的执行不会阻塞后面的代码的执行。改函数的返回值是一个promise对象,如果要获得promise对象的内容我们需要使用then方法
  • await后面可以放任意的表达式,但通常会放一个返回promise对象的表达式,await需要放在async函数里面,await表示等待,需要等待promise对象执行完才执行后面的代码。

箭头函数

  • 箭头函数是ES6的新特性,箭头函数没有this,它所用到的this是父作用域的this
  • 箭头函数无法用call、apply指定this
  • 箭头函数没用arguments参数对象

dom0和dom2

  • dom0中事件使用.onClick:后面的事件会覆盖前面的事件
  • dom2中使用.addEventListener:不会覆盖事件,删除事件用removeEventListener。addEventListener函数的第三个参数是一个布尔值,为true表示在捕获阶段调用事件处理函数,为false表示在冒泡阶段调用事件处理函数

document、documentElement和document.body三者之间的关系

document:表示整个html页面
documentElement表示<html>标签
document.body表示<body>标签

js事件流:事件流描述的是从页面接受事件的顺序。dom2级事件流中包括下面几个阶段:

  1. 事件捕获阶段
  2. 处于目标阶段
  3. 事件冒泡阶段
    一些老版本的浏览器并不支持事件捕获,例如ie8

以上大都是个人理解总结,有些可能会用到第一人称进行叙述。大家切记不要死记硬背,可以参考答案,但是要经过自己的理解,遇到不懂的还是要自己去查查资料,最好能将自己理解的内容重新编辑成自己的话写下来,这样等面试官追问的时候也能说出自己的见解。祝大家都能通过面试,找到自己理想的工作。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值