目录

一、前言

二、问题

1,JS数据类型

2,== 与 === 的区别?

3,JS的宏任务和微任务?

4,实现Jsonp

5,JS作用域

6,JS作用域+this指向+原型笔试题(高频)

7, JS判断变量是不是数组,有哪些方法?

8, slice是干嘛的,splice是否会改变原数组,二者区别?

9,JS数组去重?

10,找出多维数组的最大值?

12,找出一个字符串出现次数最多的字符,出现了多少次?

13,字符串的方法?

14,new操作符具体做了什么?

15,闭包是什么?

16,原型链是什么?

17,js的继承有哪些方式?

18,call、apply、bind的区别?

19,sort原理了解吗?

20,深浅拷贝的理解?(高频)

21,本地存储方式的区别?

22,find和filter区别?

23,some和every区别?

24,合并多个对象?


一、前言

一般比较大一点的公司面试或笔试问题的重点都侧重于js这块,考验你js的功底扎不扎实。所以在准备面试的时候,js一定要复习好,而且要过好几遍,直至熟练回答为止,有的甚至需要手写几遍。毕竟机会都是给有准备的人的。下面给大家整理了一下面试中常问的js问题。大家可以查缺补漏。

二、问题

1,JS数据类型

基本数据类型 Number、String、Boolean、Null、Undefined、Symbol

引用数据类型 Object、Array、Date、Function、RegExp

这里面可以拓展的问题很多,一定要多去思考,比如:

  • null和undefined的区别?(基本的大家都知道,但怎么回答的让面试官耳目一新呢?)

(1)设计历史:
之前看过相关文献,作者在设计js的时候,先有null后有undefined,因为借鉴了java的语言,null的数据类型时object,会被隐式转换成0,不容易发现错误;所以就设计了undefined,它是一个基本数据类型,转成数值为NaN;
(2)数据:
null已经声明赋值为空;引用数据类型;数值转换为0;
undefined已经声明未赋值;基本数据类型;数值转换为NaN(数值类型,不表示数字);

  • symbol数据类型的特点?

symbol 是ES6引入了一种新的基本数据类型(原始数据类型),表示独一无二的值。

(1)Symbol的值是唯一的,用来解决命名冲突的问题;
(2)Symbol值不能与其他数据类型进行运算;
(3)Symbol定义得的对象的属性不能使用for…in 循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名;

  • 两种数据类型的存放机制?

基本数据类型体积小,存放在栈里面;
引用数据类型体积大,存放在堆里面;
引用数据类型会有个指针放在栈里面,定位堆里面存放的引用数据;

  • 如何判断这两种数据类型?

(1)typeof:查找基本数据类型,引用数据类型除了function,其他都为object;
(2)instanceof:查找引用数据类型;

原理:instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype, 返回true,不是返回false;
(3)Object.prototype.toString().call():所有数据类型;

原理:原型链和原型有关,首先toString()这个方法本来应该返回string的字符串形式,但是大多数情况会返回[object,xxxx]形式;因为js重写了某些数据类型的toString()方法;所以这时候我们找到原型上最原始的toSting()方法;call的作用就是转变this的指向;

  • 数据类型如何转换?

(1)转为字符串:toString() / String() 不能用于null和undefined

(2)转为数值:Number() / parseInt() 转为整数,parseFloat 转为浮点数

(3)隐式转换:js是一门弱语言,运行期间,变量会根据运行环境自动类型转换;

举例:字符串数据+0/*1可以转换成数值;字符串+数值=字符串

(4)转为布尔值:false(0,null,undefined,'',NaN)

2,== 与 === 的区别?

==比较值
string == number || boolean || number都会隐式转换,通过valueOf()方法通常由js在后台自动转换
===比较值和数据类型,除了比较值,还比较类型

3,JS的宏任务和微任务?

(1)首先得解释一下JS的单线程:

js是单线程的语言,用途(浏览器的脚本语言,主要负责交互,动画,效果)决定了它必须是单线程的语言。单线程是指同一时间只能做一件事。如果能做多件事情的话,假如用户同时有两个操作,一个是删除节点,一个是新增节点,那到底应该选择是新增还是删除呢?所以js在设计的时候就必须是单线程的。

(2)其次解释一下JS代码的执行流程:

同步执行完==》事件循环;同步的任务都执行完了,才会执行事件循环的内容,进入事件循环有哪些:请求、定时器、事件。

(3)然后解释一下事件循环:

进入事件循环也得分哪个先哪个后呀?所以事件循环里面又分微任务和宏任务。
微任务:promise.then();
宏任务:setTimeOut;
执行顺序为:先执行微任务,在执行宏任务,宏任务里面还有微任务,先执行微任务,以此循环下去;记住关键,要执行宏任务的前提是清空了所有的微任务。

(4)最后总结一下代码的执行流程:

同步=》事件循环【微任务,宏任务】=》微任务=》宏任务=》微任务......;

4,实现Jsonp

srcipt标签引入
iframe
后端
配置请求头

可能会有拓展问题:

同源策略:域名,协议,端口号相同。

为什么限制:为了防止恶意ajax请求,修改DOM页面,随意获取cookie隐私数据等;

域名:www.baidu.com

端口:8080,3000

协议:https/http

5,JS作用域

全局作用域:代码在程序的任何地方都能被访问,window对象的内置属性都拥有全局作用域;
函数作用域:只有在固定的代码片段才能被访问;
好处:隔离变量,不同作用域下同名变量不会有冲突。
作用域链:一般情况下,变量取值会在创建这个变量的函数作用域中取值,如果没找到,就会像上级作用域查找,知道查到全局作用域,这个过程就叫作用域链;

除了函数外,js没有块级作用域;
比如:在函数里定义一个变量,在函数外打印这个变量,即使函数调用了,也没办法打印;

如果有笔试题,或者现场出题的话,这个就是高频题了,就需要重点理解了。

注意:
(1)声明的变量是用var还是没有写(就是window);
(2)js变量提升的机制【变量悬挂声明】;
(3)注意本层作用域有没有变量提升;

6,JS作用域+this指向+原型笔试题(高频)

构造函数:this指向的是实例对象,
全局函数:this指向window;
use strict:指向的是undefined;
绑定事件:this指的是被绑定事件的元素;
箭头函数:this和父级this指向相同;

考题一:

function foo(){getName = function(){console.log(1)};return this;
}
Foo.getName = function(){console.log(2)
}
Foo.prototype.getName = function(){console.log(3)
}
var getName = function(){console.log(4)
}
function getName(){console.log(5)
}
Foo.getName() //2
getName() //4
Foo().getName() //1
getName() //1
new Foo().getName() //3

考题二:

var o = {a:10,b:{fn:function(){console.log(this.a)console.log(this)}    }
}
o.b.fn() //undefined b函数

考题三:

window.name = 'ByteDance'
function A(){this.name = 123;
}
A.prototype.getA = function(){console.log(this);return this.name+1;
}
let a = new A()
let funcA = function(){console.log(this)return this.name+1
}
funcA() //this指的是window; 'ByteDance1'

7, JS判断变量是不是数组,有哪些方法?

(1) Array.isArray(arr)
(2) arr instanceof Array【可写可不写,因为有bug】
(3) Object.prototype.toString.call(arr)
(4) Array.prototype.isPrototype(arr)
(5) arr.constructor.toString()

8, slice是干嘛的,splice是否会改变原数组,二者区别?

slice:选择截取部分内容,参数可以一个,两个,也可以是负数,返回新数组;
splice:会改变原数组;插入、删除、替换;返回删除的元素;

9,JS数组去重?

扩展运算符 + new set
循环
sort排序
代码演示:

(1) new Set
//Array.from(new set(arr))
//...new Set(arr)
var arr1 = [1,2,3,2,4,1];
function unique(arr){return [...new Set(arr)]
}
console.log(unique(arr1))(2) 循环
function unique3(arr){var brr = []for(var i=0; i<arr.length; i++){if(brr.indexOf(arr[i]) == -1){brr.push(arr[i])}}return brr}console.log(unique3(arr));(3) sort
function unique4(arr){arr = arr.sort()var brr = []for(var i=0;i<arr.length;i++){if(arr[1] !== arr[i-1]){brr.push(arr[i])}}return brr}console.log(unique4(arr));

10,找出多维数组的最大值?

Math.max(..item)
代码演示:

var arr = [[1,3,7,9],[22,77,90,78],[123,567,890,345],[1002,3004,3009,2890]]function fn(arr){var brr = []arr.forEach((item,index)=>{brr.push(Math.max(...item))})return brr}console.log(fn(arr));

11,给字符串新增方法实现功能?

addPrefix() 添加前缀
代码演示:

 String.prototype.addPrefix = function (str){return str + this}console.log('Bryan'.addPrefix('Kobe'));

12,找出一个字符串出现次数最多的字符,出现了多少次?

var str = 'aaaabbbbssssxcccddddsdfscxxasa'var obj = {};for(var i=0; i<str.length; i++){var char = str.charAt(i)if(obj[char]){obj[char]++;}else{obj[char] = 1;}}console.log(obj);//统计出来最大值var max = 0;for(var key in obj){if(max < obj[key]){max = obj[key]}}//拿最大值去对比for(var key in obj){if(obj[key] == max){console.log('最多的字符是'+key);console.log('出现的次数是'+max);}}

13,字符串的方法?

字符串方法总结
方法 功能
charAt() 返回指定索引位置的字符
indexOf() 返回字符串中检索指定字符第一次出现的位置
replace() 替换与正则表达式匹配的字串
slice() 提取字符串的片段,返回新的字符串
split() 把字符串分隔为子字符串数组
substr() 从起始索引号提取字符串中指定数目的字符
subString() 提取字符串中两个指定的索引号之间的字符
toLowerCase() 变小写
toUpperCase() 变大写
toString() 返回字符串对象值
trim() 移除字符串首尾空白
valueOf() 返回某个字符串对象的原始值

14,new操作符具体做了什么?

(1)创建了一个空对象;

(2)将空对象的原型,指向于构造函数的原型;

(3)将构造函数里的this指向空对象;

(4)将构造函数的属性和方法赋值给空对象;

(5)返回这个对象;

代码演示:

function Fun( name, age ){this.name = name;this.age = age;}function create( fn,...args ){//创建一个新对象var obj = {}//把对象的原型指向构造函数的原型Object.setPrototypeOf(obj,fn.prototype)//改变this的指向var result = fn.apply(obj.args)//对构造函数有返回值的处理判断return result instanceof Object ? result : obj;}console.log(create(Fun,18,'张三'));

15,闭包是什么?

(1)是什么:

闭包是一个函数内返回一个函数,外部函数能读取内部函数的变量;

(2)优点:

内部可以读取外部函数的变量,可以封装独有的方法和属性,保持内部的独立性;

(3)可以解决问题:

  • 比如说要点击ul下面的每一项li,点击每项弹出每项的内容;

代码演示:

var lis = document.querySelectorAll('li');for(var i=0; i<lis.length; i++){(function(i){lis[i].onclick = function(){alert(i)}lis[i]=null})(i)}
  • 防抖,柯里化,定时器等

(4)缺点:

变量会驻留在内存中,造成内存损耗问题;内存泄漏(IE)
解决:把闭包的函数设置为null;

16,原型链是什么?

这个问题经常会问,但千篇一律肯定没办法加分,所以需要说清楚,为什么会有原型,为什么会有原型链,在什么场景会用,方法是什么,原理是什么,按照这样的思路去说基本没问题。

我们知道创建对象的方式有三种,字面量,new,构造函数。前两个只能创建单个的对象,但构造函数可以把不同对象的共同属性和方法抽离出来,通过new实例化创建拥有共同属性和方法的不同对象。但是想一想,会出现什么问题呢?

由于js存储数据的方式是引用数据类型存储在堆里面,我们new出来的不同对象都拥有这一个相同的方法,但是都要在堆里面去申请不同的空间去存储,这样就会极大的浪费我们的内容空间。

所以这个时候我们就有了原型prototype。这样不同的对象可以通过原型去查找,节省内存空间,how nice!

也就是说原型可以解决:对象共享属性和共享方法。

总结简洁版(思路如下,自己整理能说明白即可):

(1)原型可以解决什么问题:对象共享属性和共享方法;
(2)谁有原型?函数拥有prototype,对象拥有:`__proto__`
(3)对象查找属性或者方法的顺序:

先在对象本身查找-->构造函数中查找-->对象的原型-->构造函数的原型中-->当前原型的原型;
(4)原型链的最顶端是Null;

17,js的继承有哪些方式?

不需要每个都讲,只需要讲到重点常用的几个即可;

(1)es6

class father{constructor(){this.age = 18}
}
class child extends father{constructor(){super()this.name = '张三'}
}
let Child = new child()
console.log(Child,Child.name,Child.age)

(2)原型链继承

child.prototype = new parent()
let Child = new child()
console.log(Child, Child.name, Child.age)
//继承的属性和方法在原型上

(3)构造函数继承:

function Father(){this.name = '张三'}function Son(){this.age = 20Father.call(this)}let o3 = new Son()console.log(o3);

(4)组合继承

function Father(name,age){this.name = namethis.age = age}function Son(name,age){Father.call(this,name,age)}const son = new Son('刘德华', 20)console.log(son);

18,call、apply、bind的区别?

(1)相同点:功能一致,都可以改变this指向;

(2)语法:函数.call(fn,name),函数.apply(fn,[...args]),函数.bind();

(3)区别:

  • call,apply可以立即指向,bind不会立即指向,因为bind返回的是一个函数需要加入()执行;
  • 参数不同,apply第二个参数是数组,call和bind有多个参数需要挨个写;

(4)使用场景:

  • 找出最大值:
var arr = [1,2,4,5,78,21]
console.log(Math.max.apply(null,arr1))
  • 用bind的情况
var btn = document.querySelector('btn')
var h1s = document.querySelector('h1s')
btn.onclick = function(){console.log(this.id)
}.bind(h1s) //h1s

19,sort原理了解吗?

之前的版本是插入和快排,现在是冒泡;

使用场景:

(1)升序:

var arr = [1,2,23,21,222,778]
let res = arr.sort(function(a,b){return a-b
})
console.log(res)

(2)降序:

var arr = [1,2,23,21,222,778]
let res = arr.sort(function(a,b){return b-a
})
console.log(res)

(3)排序对象中某属性值的顺序:

var obj = [{name:'张三',age:2},{name:'李四',age:29},{name:'王五',age:70}
]
function compare(age){return function (a,b){var val1 = a[age]var val2 = b[age]return val1-val2}
}
var arr = obj.sort(compare('age'))
console.log(arr)

20,深浅拷贝的理解?(高频)

首先什么情况会出现深浅拷贝呢?

假设我们有一个已经定义了属性和方法的对象,我们再创建一个新对象,然后用=号把已定义的对象赋值给新创建的空对象;

如果我们修改新对象里的某个属性值,打印原来已定义的对象时,你会发现它的值也发生变化了;

这种情况就是发生了浅拷贝。为什么呢?

这是因为js的数据存储方式是基本数据类型再栈里面,引用数据类型在堆里面,但引用数据的指针,也就是房间号在栈里面存着。如果我们用=号去赋值,就相当于把指针赋值给了另一个对象,也就是说这两个对象的指针都是一样的,所以你修改了任意一个对象的值另一个也会发生变化。

那如果不想出现上面的情况,我们就需要进行深拷贝了,也就是说要在堆里面重新申请一个新空间,指针也是不同的,这样就不会发生连锁反应了。

简洁版思路:

共同点:复制

(1)浅拷贝:只复制引用地址,而未复制真正的值;object.assign()

(2)深拷贝:是复制真正的值(不同的引用)

(3)方式:JSON.parse(JSON.Stringify) 递归形式;

21,本地存储方式的区别?

(1)数据存放有效期:

localStorage:始终有效,持久存储;

sessionStorage:浏览器关闭就没了;

cookie:只在设置的cookie过期时间之前有效,即使窗口或者浏览器关闭也有效,其他不可以设置时间;

(2)存储大小的限制:

cookie存储量不能超过4k;
localStorage、sessionStorage不能超过5M;

22,find和filter区别?

(1)区别一:filter返回新数组,find返回具体的内容;

(2)区别二:find匹配到第一个即返回,filter只要满足条件push到新数组里,返回新数组;

23,some和every区别?

some是只要满足一个条件就返回true;

every是都满足返回为true;

24,合并多个对象?

(1)方法一:Object.assign(a,b)

(2)方法二:obj = {...a,...b}

(3)方法三:循环

function extend(target,source){for(var obj in source){target[obj] = source[obj]}return target
}
console.log(extend(a,b))

2023前端面试(JS专题)相关推荐

  1. js 点击闭包_【新年跳槽必备】2020最新(前端原生JS专题)面试题 速领!

    最近我把每周更新的面试题 发在我们的学习群里 大家似乎都很高冷哇 难道是默默的做题去了没说话 每期面试题都是Richard老师认真准备的 真的希望能帮到大家哦 本期是前端原生JS专题 A前端原生JS专 ...

  2. 2023前端面试整理合集

    2023前端面试自我整理 1.讲讲cookies和localstorage,sessionstroage的区别? 区别:cookie它的大小只有4kb,而localstorage和sessionstr ...

  3. 前端面试 - JS总结(1) - 基础 (数据类型, 事件与函数, 原型链)

    你不走出舒适圈,又怎么知道自己多坚强?! 前端面试 - JS总结(1) - 基础 (数据类型, 事件与函数, 原型链) 前端面试 - JS总结(2) - ES6 (let, 箭头函数, this) 前 ...

  4. 前端面试JS必备基础之深浅拷贝和this指向问题@莫成尘

    一:js深拷贝 在JS中,数据类型分为基本数据类型和引用数据类型两种,对于基本数据类型来说,它的值直接存储在栈内存中,而对于引用类型来说,它在栈内存中仅仅存储了一个引用,而真正的数据存储在堆内存中.深 ...

  5. web前端面试 js部分

    1/如何用原生js给一个按钮绑定过两个click事件 var obtn = document.getElementById('btn'); obtn.addEventListener('click', ...

  6. 2023前端面试总结含参考答案

    文章目录 1. 父子组件生命周期的执行顺序: 2. 原型链: 3. promise的理解: 4. 数组循环,foreach,filter,map,reduce 5. 数组去重,set 6. 组件通信方 ...

  7. 前端面试——JS去除首尾空格代码

    关于 JavaScript 里的 trim()/strip() 方法 在其他语言中常常用 trim()/strip() 方法脱去不必要的空格等元素. JavaScript 本身并不提供 trim() ...

  8. 前端面试日记(7)网易有道

    没有什么能阻挡你成功,只要你稳稳当当,每一步都好好走下去. 注:在牛客平台投递简历处理很快.约的时间比较靠后.面试时常15min(不知道为啥如此迅速) 1. 自我介绍 2. 项目有哪些难点,如何解决? ...

  9. 前端面试:你应该了解的JS算法相关的知识

    前端面试:你应该了解的JS算法相关的知识 时间复杂度 通常使用最差的时间复杂度来衡量一个算法的好坏. 常数时间 O(1) 代表这个操作和数据量没关系,是一个固定时间的操作,比如说四则运算. 对于一个算 ...

最新文章

  1. Spring之AOP由浅入深
  2. Python中单个下划线“ _”变量的用途是什么?
  3. JS 面向对象与原型
  4. SQL SERVER – Beginning of SQL Server Architecture – Terminology – Guest Post
  5. 【HDU 1276】士兵队列训练问题(两个队列模拟)
  6. WampServer修改端口及菜单Localhost
  7. 2016经典微小说:《轮回》
  8. linux内核 panic,linux 内核 panic
  9. 数学分析闭区间套定理_不能精确找到背驰点?利用区间套解决这难题
  10. springboot报错Table 'wechat.hibernate_sequence' doesn't exist
  11. malloc 初始化_glibc: malloc、calloc、realloc amp; free
  12. Solaris 10 的基本操作
  13. 小夜曲dsd使用foobar2000测试dsd输出
  14. WPS打不出英文引号
  15. 什么电子邮箱正式?企业工作邮箱大全,一般白领用什么邮箱账号?
  16. 优炫数据库携手兆芯发布数据库解决方案
  17. 手机有时触摸失灵解决方法
  18. VR插件:VR Interaction Framework 1.7(VRIF)(一)
  19. 【纯净版windows系统】U盘启动制作图文教程
  20. 小编推荐这款,超实用的SpringBoot 开源商城系统,挣钱不是太轻松!

热门文章

  1. 注意九宫格系统中文键盘输入特殊字符问题
  2. R语言 数据清洗(缺失值处理、异常值处理)
  3. MakeFile中ifeq语法报错
  4. Cocos-2d 游戏进度条加载CCProgressTimer实现
  5. 计算机毕设代做的那些坑
  6. matlab车轮滚动动画,flash制作车轮往前滚动的动画效果
  7. linux如何安装惠普指纹识别,如何在Lenovo ThinkPad上安装指纹识别器?
  8. 东南大学课表查询系统
  9. 电子元器件产品安规基本要求
  10. ACE:高级CIP评估