前端面试常见js面试题汇总

1.js有几种数据类型,其中基本数据类型有哪些?

基本类型:Undefined、Null、Boolean、Number、String和Symbol。

引用类型:Object、Array和Function等。

2.js有哪些内置对象?

数据封装类对象:Object、Array、Boolean、Number 和 String

其他对象:Function、Arguments、Math、Date、RegExp、Error

3.判断 js 类型的方式

1.最常见的判断方法:typeof

可以判断出'string','number','boolean','undefined','symbol',’function’,但判断 typeof(null) 时值 为 'object'; 判断数组和对象时值均为 'object'。

2.判断已知对象类型的方法: instanceof

原理是构造函数的 prototype 属性是否出现在对象的原型链中的任何位置;

3.根据对象的constructor判断:

alert(c.constructor === Array) ----------> true

4.通用但很繁琐的方法: prototype

Object.prototype.toString.call():常用于判断浏览器内置对象,对于所有基本的数据类 型都能进行判断,即使是 null 和 undefined

5.无敌万能的方法:jquery.type()

jQuery.type( undefined ) === "undefined"

4.js的typeof返回有哪些类型

1.String

2.Number

3.Boolean

4.Object

5.Function

6.undefined

5.Javascript中的定时器有哪些?他们的区别及用法是什么?

setTimeout 只执行一次

setInterval 会一直重复执行

6.js字符串操作函数

列举了常用的字符串函数

1.length – 返回字符串的长度,所谓字符串的长度是指其包含的字符的个数。

2.concat() – 将两个或多个字符的文本组合起来,返回一个新的字符串。

3.indexOf() – 返回字符串中一个子串第一处出现的索引。如果没有匹配项,返回 -1 。

4.lastIndexOf() – 返回字符串中一个子串最后一处出现的索引,如果没有匹配项,返回 -1 。

5.charAt() – 返回指定位置的字符。

6.substr() 函数 -- 返回从string的startPos位置,长度为length的字符串

7.substring() – 返回字符串的一个子串。传入参数是起始位置和结束位置。

8.slice() – 提取字符串的一部分,并返回一个新字符串。

9.split() – 通过将字符串划分成子串,将一个字符串做成一个字符串数组。

10.match() – 检查一个字符串是否匹配一个正则表达式。

11.replace() – 用来查找匹配一个正则表达式的字符串,然后使用新字符串代替匹配的字符串。

12.search() – 执行一个正则表达式匹配查找。如果查找成功,返回字符串中匹配的索引值。否则返回 -1 。

13.toLowerCase() – 将整个字符串转成小写字母。

14.toUpperCase() – 将整个字符串转成大写字母。

7.数组的splice方法?

1.删除——可以删除任意数量的项,只需要指定2个参数:要删除的第一项的位置和要删除项的项数。例如,splice(0,2)会删除数组中的前两项。

2.插入——可以向指定位置插入任意数量的项,只需要提供3个参数:插入起始位置、0(要删除的项数)和要插入的项。 如果要插入多个项,可以再传入第四、第五,一直任意多个项。例如,splice(2,0,”red”,”green”)会从位置2开始插入字符串“red”和”green”。

3.替换——即删除和插入数量相等项数的综合应用,可以指向指定位置插入任意数量的项,且同时删除任意数量的项,只需要指定3个指定参数:起始位置、要删除的项数和要插入的任意数量项。 插入的项数是不必与删除的项数相等。例如,splice(2,2,”red”,”green”)会删除当前数组位置2的项,然后再从位置2开始插入字符串“red”和“green”。

splice()方法始终都会返回一个数组,该数组中包含从元素数组中删除的项(如果没有删除任何项,则返回一个空数组)。

8.for...in和for...of的区别?

均可以遍历数组和对象。

简单总结就是,for in遍历的是数组的索引(即键名),而for of遍历的是数组元素值(即value)。for-in总是得到对象的key或数组字符串的下标。for-of总是得到对象的value或数组字符串的值,另外还可以用于遍历Map和Set。

使用for-in遍历数组会存在以下问题:

var arr = [1, 2, 4, 5, 7];
for (var index in arr) {
  console.log(myArray[index]);
}

1.index索引为字符串型数字(注意,非数字),不能直接进行几何运算。

2.遍历顺序有可能不是按照实际数组的内部顺序(可能按照随机顺序)。

3.使用for-in会遍历数组所有的可枚举属性,包括原型。例如上例的原型方法method和name属性都会被遍历出来,通常需要配合hasOwnProperty()方法判断某个属性是否该对象的实例属性,来将原型对象从循环中剔除。

for (var key in myObject) {
  if(myObject.hasOwnProperty(key)){
    console.log(key);
  }
}

9.给一个对象添加属性和方法的三种方案**?**

常用的有三种:

1.直接在空对象上面添加;

2.构造函数原型上添加;

3.立即执行函数中定义空对象添加属性和方法后返回。

10.类数组转换为数组的方法

Array.prototype.slice.call(arguments);

Array.from()

11.改变数组长度的方法有哪些?

shift、unshift、pop、push

12.写出最简单的去重方式

1.es6的new Set()方式

[...new Set([1,3,4,5,1,2,3,3,4,8,90,3,0,5,4,0])]

2.es5的Array filter()

[1,3,4,5,1,2,3,3,4,8,90,3,0,5,4,0].filter(function(elem,index,Array){

return index === Array.indexOf(elem);

})

13.javascript对象的几种创建方式

1,工厂模式

2,构造函数模式

3,原型模式

4,混合构造函数和原型模式

5,动态原型模式

6,寄生构造函数模式

7,稳妥构造函数模式

14.javascript继承的6种方法

1,原型链继承

2,借用构造函数继承

3,组合继承(原型+借用构造)

4,原型式继承

5,寄生式继承

6,寄生组合式继承

15.ES6中的箭头函数和普通函数有什么区别?

1.普通函数中的this总是指向调用它的那个对象,箭头函数没有自己的this,他的this永远指向其定义环境,任何方法都改变不了其指向,如call()、bind()、apply()。(正是因为它没有this,所以也就不能用作构造函数,也没有原型对象)

2.箭头函数不能当作构造函数,也就是说,不能使用new命令,否则会报错。

3.箭头函数没有原型属性。

4.箭头函数不能使用yield命令,因此箭头函数不能用作genertor函数。

5.箭头函数不能使用argument对象,该对象在函数体内不存在。如果要用,可以用rest参数代替。

6.变量提升:由于js的内存机制,function的级别最高,而用箭头函数定义函数的时候,需要var(let、const)关键字,而var所定义的变量不能得到变量提升。故箭头函数一定要定义于调用之前。

16.this对象的理解

1.this总是指向函数的直接调用者(而非间接调用者);

2.如果有new关键字,this指向new出来的那个对象;

3.在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window。

17.call() 和 apply() 的区别和作用?

作用:动态改变某个类的某个方法的运行环境(执行上下文)。

apply()函数有两个参数:第一个参数是上下文,第二个参数是参数组成的数组。如果上下文是null,则使用全局对象代替。如:function.apply(this,[1,2,3]);

call()的第一个参数是上下文,后续是实例传入的参数序列。如:function.call(this,1,2,3);

18.闭包的概念?优缺点?

闭包的概念:闭包就是能读取其他函数内部变量的函数。

优点:

1.避免全局变量的污染

2.希望一个变量长期存储在内存中(缓存变量)

缺点:

1.内存泄露(消耗)

2.常驻内存,增加内存使用量

19.说说你对Promise的理解

Promise是一个异步编程的解决方案,简单来讲,Promise类似一个盒子,里面保存着在未来某个时间点才会结束的事件。

依照 Promise/A+ 的定义,Promise 有三种状态:

pending:进行中

fulfilled :已经成功

rejected :已经失败

状态改变,只能从 pending 变成 fulfilled 或者 rejected,状态不可逆。

构造一个 Promise,最基本的用法如下:

var promise = new Promise(function(resolve, reject) {
if (...) { // succeed
resolve(result);
} else { // fails
reject(Error(errMessage));
}
});

Promise 实例拥有 then 方法(具有 then 方法的对象,通常被称为 thenable)。它的使用方法如下:

promise.then(onFulfilled, onRejected)

接收两个函数作为参数,一个在 fulfilled 的时候被调用,一个在 rejected 的时候被调用,接收参数就是 future,onFulfilled对应 resolve, onRejected 对应 reject。

20.介绍下 promise.all

Promise.all()方法将多个Promise实例包装成一个Promise对象(p),接受一个数组(p1,p2,p3)作为参数,数组中不一定需要都是Promise对象,但是一定具有Iterator接口,如果不是的话,就会调用Promise.resolve将其转化为Promise对象之后再进行处理。
使用Promise.all()生成的Promise对象(p)的状态是由数组中的Promise对象(p1,p2,p3)决定的。

1.如果所有的Promise对象(p1,p2,p3)都变成fullfilled状态的话,生成的Promise对象(p)也会变成fullfilled状态,p1,p2,p3三个Promise对象产生的结果会组成一个数组返回给传递给p的回调函数。

2.如果p1,p2,p3中有一个Promise对象变为rejected状态的话,p也会变成rejected状态,第一个被rejected的对象的返回值会传递给p的回调函数。Promise.all()方法生成的Promise对象也会有一个catch方法来捕获错误处理,但是如果数组中的Promise对象变成rejected状态时,并且这个对象还定义了catch的方法,那么rejected的对象会执行自己的catch方法。并且返回一个状态为fullfilled的Promise对象,Promise.all()生成的对象会接受这个Promise对象,不会返回rejected状态。

21.promise的优缺点?

优点:解决了回调地狱的问题,将异步操作以同步操作的流程表达出来。

缺点:

1.无法取消promise。

2.如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。

3.当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

4.当执行多个Promise时,一堆then看起来也很不友好。

22.异步编程的发展史?

JS的异步发展史,可以认为是从 callback -> promise -> generator -> async/await。async/await 使得异步代码看起来像同步代码,异步编程发展的目标就是让异步逻辑的代码看起来像同步一样。

23.DOM 事件有哪些阶段?谈谈对事件代理的理解

分为三大阶段:

1.一开始从文档的根节点流向目标对象(捕获阶段)

2.然后在目标对向上被触发(目标阶段)

3.之后再回溯到文档的根节点(冒泡阶段)。

事件代理简单说就是:事件不直接绑定到某元素上,而是绑定到该元素的父元素上,进行触发事件操作时(例如'click'),再通过条件判断,执行事件触发后的语句(例如'alert(e.target.innerHTML)')

好处:(1)使代码更简洁;(2)节省内存开销

24.DOM怎样添加、移除、替换、插入、创建和查找节点

1.创建新节点

createDocumentFragment() //创建一个DOM片段

createElement() //创建一个具体的元素

createTextNode() //创建一个文本节点

2.添加、移除、替换、插入

appendChild()

removeChild()

replaceChild()

insertBefore() //在已有的子节点前插入一个新的子节点

3.查找

getElementsByTagName() //通过标签名称

getElementsByName() //通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的)

getElementById() //通过元素Id,唯一性

25.null和undefined的区别?

null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。

undefined:

(1)变量被声明了,但没有赋值时,就等于undefined。

(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。

(3)对象没有赋值的属性,该属性的值为undefined。

(4)函数没有返回值时,默认返回undefined。

null:

(1)作为函数的参数,表示该函数的参数不是对象。

(2)作为对象原型链的终点。

26.字符串和数字的相互转换?

1.数字 --> 字符串

value.toString()、 "" + value、String(value)

2.字符串 --> 数字

+value、Number(value)、parseInt(string, radix)、 parseFloat(value)

27.new操作符具体干了什么呢?

(1)创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。

(2)属性和方法被加入到 this 引用的对象中。

(3)新创建的对象由 this 所引用,并且最后隐式的返回 this 。

28.JSON 的了解?

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它是基于JavaScript的一个子集。数据格式简单, 易于读写, 占用带宽小。

格式:采用键值对,例如:{'age':'12', 'name':'back'}

29.eval是做什么的?

它的功能是把对应的字符串解析成JS代码并运行;

应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。

由JSON字符串转换为JSON对象的时候可以用eval,var obj =eval('('+ str +')')。

30.浅拷贝和深拷贝的问题

浅拷贝只是增加了一个指针指向已存在的内存地址;深拷贝是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。

浅拷贝的方法:

1.Object.assign()

2.扩展运算符(...)

3.Array.prototype.slice()

4.直接赋值=

深拷贝的方法:

1.JSON.stringify()

2.递归

通过JSON.stringify实现深拷贝有几点要注意:

1.拷贝的对象的值中如果有函数,undefined,symbol则经过JSON.stringify()序列化后的 JSON字符串中这个键值对会消失

2.无法拷贝不可枚举的属性,无法拷贝对象的原型链

3.拷贝Date引用类型会变成字符串

4.拷贝RegExp引用类型会变成空对象

5.对象中含有NaN、Infinity和-Infinity,则序列化的结果会变成null

6.无法拷贝对象的循环应用(即obj[key] = obj)

31.请解释一下 JavaScript 的同源策略。

概念:同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。它最早出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。

这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议。

指一段脚本只能读取来自同一来源的窗口和文档的属性。

32.为什么要有同源限制?

我们举例说明:比如一个黑客程序,他利用Iframe把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名,密码登录时,他的页面就可以通过Javascript读取到你的表单中input中的内容,这样用户名,密码就轻松到手了。

缺点:

现在网站的JS 都会进行压缩,一些文件用了严格模式,而另一些没有。这时这些本来是严格模式的文件,被 merge 后,这个串就到了文件的中间,不仅没有指示严格模式,反而在压缩后浪费了字节。

33.请用js去除字符串空格?

方法一:使用replace正则匹配的方法

去除所有空格: str = str.replace(/\s*/g,"");

去除两头空格: str = str.replace(/^\s|\s$/g,"");

去除左空格: str = str.replace( /^\s*/, "");

去除右空格: str = str.replace(/(\s*$)/g, "");

方法二:使用str.trim()方法

str.trim()局限性:无法去除中间的空格,同理,str.trimLeft(),str.trimRight()分别用于去除字符串左右空格。

方法三:使用jquery,$.trim(str)方法

$.trim(str)局限性:无法去除中间的空格

34.JavaScript中如何检测一个变量是一个String类型?请写出函数实现

typeof(obj) === "string"
typeof obj === "string"
obj.constructor === String

35.使用正则表达式验证邮箱格式

 var reg = /^(\w)+(\.\w+)*@(\w)+((\.\w{2,3}){1,3})$/;
 var email = "example@qq.com";
 console.log(reg.test(email));  // true

36.简述**同步和异步的区别**

同步是阻塞模式,异步是非阻塞模式。

同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;

异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发
程序员吾非同的头像-程序员知识精选

昵称

取消
昵称表情代码图片