1、JavaScript有几种数据类型?

number:数字类型string:字符串类型boolean:布尔值类型undefined:未定义类型null:空类型object:对象类型symbol:symbol类型bigint:大数字类型

2、JavaScript最大平安数字与最小平安数字?

console.log(Number.MAX_SAFE_INTEGER)// 9007199254740991console.log(Number.MIN_SAFE_INTEGER)// -9007199254740991

3、深拷贝与浅拷贝的区别?

浅拷贝:只拷贝第一层,深层的仍然是援用,扭转深层会影响原对象深拷贝:每一层都拷贝了,扭转数据不会影响原对象

4、闭包是什么?

闭包是一个函数,是一个能让内部拜访到函数外部的函数长处:使内部能拜访外部,缩短外部变量寿命毛病:滥用闭包造成内存透露

例子:

function a () {  let num = 0    // 这是个闭包  return function () {     return ++num  }}const b = a()console.log(b()) // 1console.log(b()) // 2

5、原型链是什么

原型链是一条援用的链,实例的隐式原型指向构造函数的显式原型,能够应用A instanceof B来判断B是否在A的原型链上。

6、什么是变量晋升?函数晋升?

变量晋升

console.log(name) // undefinedvar name = 'Sunshine_Lin'if (false) {  var age = 23}console.log(age) // undefined 不会报错

函数晋升

console.log(fun) // function fun() {}function fun() {}if (false) {  function fun2(){}}console.log(fun2) // undefined 不会报错

函数晋升优先级 > 变量晋升优先级

console.log(fun) // function fun() {}var fun = 'Sunshie_Lin'function fun() {}console.log(fun) // 'Sunshie_Lin'

7、isNaN 与 Number.isNaN的区别?

isNaN:除了判断NaN为true外,还会把不能转成数字判断为true,例如'dasd'Number.isNaN:只会判断NaN为true

8、解决遍历对象时,把原型上的属性遍历进去了咋办?

应用hasOwnProperty判断

function Person(name) {  this.name = name}Person.prototype.age = 23const person = new Person('Sunshine_lin')for (const key in person) { console.log(key) } // name age// 应用 hasOwnPropertyfor (const key in person) {  person.hasOwnProperty(key) && console.log(key)} // name

9、valueOf 与 toString?

valueOf比拟偏差于计算,toString偏差于显示对象转换时,优先调用toString强转字符串时优先调用toString,强转数字时优先调用valueOf失常状况下,优先调用toString运算操作符状况下优先调用valueOf

10、JavaScript变量在内存中具体存储模式?

根本数据类型:存在栈内存里援用数据类型:指针存栈内存,指向堆内存中一块地址,内容存在堆内存中

11、讲一讲JavaScript的装箱和拆箱?

装箱:把根本数据类型转化为对应的援用数据类型的操作

看以下代码,s1只是一个根本数据类型,他是怎么能调用indexOf的呢?

const s1 = 'Sunshine_Lin'const index = s1.indexOf('_')console.log(index) // 8

原来是JavaScript外部进行了装箱操作

1、创立String类型的一个实例;
2、在实例上调用指定的办法;
3、销毁这个实例;

var temp = new String('Sunshine_Lin')const index = temp.indexOf('_')temp = nullconsole.log(index) // 8

拆箱:将援用数据类型转化为对应的根本数据类型的操作

通过valueOf或者toString办法实现拆箱操作

var objNum = new Number(123);  var objStr =new String("123");   console.log( typeof objNum ); //objectconsole.log( typeof objStr ); //object console.log( typeof objNum.valueOf() ); //numberconsole.log( typeof objStr.valueOf() ); //stringconsole.log( typeof objNum.toString() ); // string console.log( typeof objStr.toString() ); // string

12、null和undefined的异同点有哪些?

相同点1、都是空类型2、转布尔值都是false,都是假值3、null == undefined 为 true不同点1、typeof,前者为object,后者为undefined2、null转数字为0,undefined转数字为NaN3、null === undefined 为 false

13、如何判断数据类型?

typeof:能判断string、number、undefined、boolean、function、object(null是object)Object.prototype.toString.call():能判断大部分数据类型instanceOf

14、为什么typeof null 是object?

不同数据类型底层都是用二进制来示意的,二进制前三位为000则会被判断为object,而null二进制全是0,所以被判断成object

15、== 与 === 的区别?

==:比拟过程会进行隐式转换===:值雷同,类型雷同才会为true

16、JavaScript的隐式转换规则?

转string类型:+(字符串连接符)转number类型:++/--(自增自减运算符) + - * / %(算术运算符) > < >= <= == != === !== (关系运算符)转boolean:!(逻辑非运算符)

17、双等号左右两边的转换规则?

1、null == undefined 为 true2、如果有一个操作数是布尔值,则在比拟相等性之前先将其转换为数值——false转换为0,而true转换为1;3、如果一个操作数是字符串,另一个操作数是数值,在比拟相等性之前先将字符串转换为数值4、如果一个操作数是对象,另一个操作数不是,则调用对象的toString()办法,用失去的根本类型值依照后面的规定进行比拟

18、undefined >= undefined 为什么是 false ?

隐式转换,变成NaN >= NaN,NaN不等于本身也不大于本身

19、null >= null 为什么是 true?

隐式转换,变成0 >= 0,为true

20、[] == ![] 为什么是 true ?

第一步:转为[] == false第二步:转为[] == 0第三步:转为'' == 0第四步:转为0 == 0

21、0.1 + 0.2 === 0.3,对吗?

不对,JavaScript存在精度失落问题,因为有些小数无奈用二进制示意,所以只能取近似值,解决办法有:先转大数,再变小数应用toFixed

22、什么是匿名函数?
匿名函数,就是没有名字的函数,比方:

(function(x, y){    alert(x + y);  })(2, 3)

23、绑定点击事件有几种形式?

三种xxx.onclick = function (){}<xxx onclick=""></xxx>xxx.addEventListener('click', function(){}, false)

24、addEventListener的第三个参数是干嘛的?

决定事件是捕捉阶段执行还是冒泡阶段执行true:捕捉false:默认,冒泡

25、函数申明和函数表达式的区别?

函数申明:享受函数晋升
函数表达式:归类于变量申明,享受变量晋升
函数晋升优先级 > 变量晋升优先级

console.log(fun) // fun () {}// 函数表达式var fun = function(name) {}// 函数申明function fun () {}console.log(fun) // fun (name) {}

26、JavaScript的事件流模型有哪些?

事件冒泡:由最具体的元素接管,并往上流传事件捕捉:由最不具体的元素接管,并往下流传DOM事件流:事件捕捉 -> 指标阶段 -> 事件冒泡

27、Ajax、Axios、Fetch有啥区别?

Ajax:是对XMLHttpRequest(XHR)的封装Axios:是基于Promise对XHR对象的封装Fetch:是window的一个办法,基于Promise,与XHR无关,不兼容IE

28、load、$(document).ready、DOMContentLoaded的区别?

$(document).ready、DOMContentLoaded:DOM树构建结束,但还没有申请动态资源load:动态资源申请结束

29、如何阻止事件冒泡?

function stopBubble(e) {  if (e.stopPropagation) {    e.stopPropagation()  } else {    window.event.cancelBubble = true;  }}

30、如何阻止事件默认行为?

function stopDefault(e) {  if (e.preventDefault) {    e.preventDefault();  } else {    window.event.returnValue = false;  }}

31、什么是事件委托?

当子元素都须要绑定雷同事件时,能够将事件绑在父元素上,长处有:绑定在父元素,则只需绑定一次,节俭性能后续新增的子元素也能够触发父元素绑定的事件

32、如何实现数组去重?

// 应用 Map 去重function quchong1(arr) {  const newArr = []  arr.reduce((pre, next) => {    if (!pre.get(next)) {      pre.set(next, 1)      newArr.push(next)    }    return pre  }, new Map())  return newArr}// 应用 Set 去重function quchong (arr) {    return [...new Set(arr)]}

33、Set与Array的区别是什么?

Set应用has判断有无元素,数组应用索引Set增加元素应用办法add,数组用push、unshiftSet长度为size,数组为lengthSet会主动把同样的根底数据类型去重,数组不能Set删除元素用delete,数组用splice、pop、shiftSet能够应用clear清空,数组须要从新赋值[]数组能够传入new Set(array),实现数组转SetSet能够应用keys、value办法,转数组Set自带forEach办法进行遍历

34、Map与Object的区别是什么?

Map应用set设置属性,对象应用obj[key] = valueMap应用get获取属性值,对象应用obj[key]Map应用has判断属性存在与否,对象只能obj[key]Map删除元素应用delete办法,对象应用delete关键字Map应用clear进行情空,对象须要从新赋值{}Map和对象都能够应用entries办法转数组键值对Map自带forEach办法进行遍历

35、NaN是什么?有什么特点?

typeof NaN 为 numberNaN不等于本身,不大于本身,不小于本身NaN能够应用Number.isNaN判断NaN是假值,转布尔值为false

36、解决异步的办法有哪些?

回调函数Promise事件监听公布订阅async/await

37、JavaScript继承形式有几种?

前置工作

// 定义一个动物类function Animal (name) {  // 属性  this.name = name || 'Animal';  // 实例办法  this.sleep = function(){    console.log(this.name + '正在睡觉!');  }}// 原型办法Animal.prototype.eat = function(food) {  console.log(this.name + '正在吃:' + food);};

1、原型链继承
外围:将父类的实例作为子类的原型

function Cat(){ }Cat.prototype = new Animal();Cat.prototype.name = 'cat';var cat = new Cat();console.log(cat.name); // catcat.eat('fish') // cat正在吃:fishcat.sleep() // cat正在睡觉!console.log(cat instanceof Animal); //true console.log(cat instanceof Cat); //true

长处:

1、十分纯正的继承关系,实例是子类的实例,也是父类的实例
2、父类新增原型办法/属性,子类都能拜访到
3、简略,易于实现

毛病:

1、要想为子类新增属性和办法,必须要在new Animal()这样的语句之后执行,不能放结构器中
2、来自原型对象的所有属性被所有实例共享
3、创立子实例时,无奈向父类构造函数传参
4、不反对多继承

2、结构继承
外围:应用父类的结构器来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)

function Cat(name) {  Animal.call(this);  this.name = name || 'Tom';}var cat = new Cat();console.log(cat.name); // Tomcat.sleep() // Tom正在睡觉!console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true

长处:

1、解决了原型链继承中,子类实例共享父类援用属性的问题
2、创立子类实例时,能够向父类传递参数
3、能够实现多继承(call多个父类对象)

毛病:

1、实例并不是父类的实例,常识子类的实例
2、是能继承父类的实例属性和办法,不能继承原型属性/办法
3、无奈实现函数复用,每个子类都有父类实例函数的正本,影响性能

3、实例继承
外围:为父类实例增加新个性,作为子类实例返回

function Cat(name){  var instance = new Animal();  instance.name = name || 'Tom';  return instance;}var cat = new Cat();console.log(cat.name) // Tomcat.sleep() // Tom正在睡觉!console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // false

长处:

1、不限度调用形式,不论是new 子类()还是子类(),返回的对象具备雷同成果

毛病:

1、实例是父类的实例,不是子类的实例
2、不反对多继承

4、拷贝继承
外围:就一个一个拷贝

function Cat(name){  var animal = new Animal();  for(var p in animal){    Cat.prototype[p] = animal[p];  }  this.name = name || 'Tom';}var cat = new Cat();console.log(cat.name); // Tomcat.sleep() // Tom正在睡觉!console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true

长处:

1、反对多继承

毛病:

1、效率低,内存占用高(因为要拷贝父类的属性)
2、无奈获取父类不可枚举办法(不可枚举办法,不能应用for in拜访到)

5、组合继承
外围:通过父类结构,继承父类的属性并保留传参的长处,而后通过将父类实例作为子类原型,实现函数复用

function Cat(name){  Animal.call(this);  this.name = name || 'Tom';}Cat.prototype = new Animal();Cat.prototype.constructor = Cat;var cat = new Cat();console.log(cat.name); // Tomcat.sleep() // Tom正在睡觉!console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // true

长处:

1、补救了结构继承的缺点,能够继承实例属性/办法,也可继承原型属性/办法
2、既是子类的实例,也是父类的实例
3、不存在援用属性共享问题
4、可传参
5、函数可复用

毛病:

1、调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

6、寄生组合继承
外围:通过寄生形式,砍掉父类的实例属性,这样,在调用两次父类的结构时,就不会初始化两次实例办法/属性,防止继承组合的毛病

function Cat(name) {  Animal.call(this);  this.name = name || 'Tom';}// 创立一个没有实例办法的类var Super = function () { };Super.prototype = Animal.prototype;//将实例作为子类的原型Cat.prototype = new Super();// Test Codevar cat = new Cat();console.log(cat.name); // Tomcat.sleep() // Tom正在睡觉!console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); //true

长处:

1、堪称完满

毛病:

1、实现简单

38、创立一个对象的形式有哪几种?

new Object

const obj = new Object()obj.name = 'Sunshine_Lin'

字面量

const obj = { name: 'Sunshin_Lin' }

工厂模式

function createObj(name) {  const obj = new Object()  obj.name = name  return obj}const obj = createObj('Sunshine_Lin')

构造函数

function Person(name) {  this.name = name}const person = new Person('Sunshine_Lin')

39、this指向的四种状况?

new操作符

function Person(name) {  this.name = name  console.log(this)}// this指向以后person实例对象const person = new Person('Sunshine_Lin')

指向window

function fn() {  console.log(this)}fn() // 浏览器window,node里global

对象调用办法

const target = {  fn: function () { console.log(this) }}target.fn() // target// 这种就是扭转了this了const fn = target.fnfn() // 浏览器window,node里global

箭头函数

const obj = {  name: '林三心',  fn: () => {    console.log(this.name)  }}console.log(obj.fn()) // undefined

call、apply、bind扭转this

const obj1 = {  name: '林三心',  sayName: function() {    console.log(this.name)  }}const obj2 = {  name: 'Sunshin_Lin'}// 扭转sayName的this指向obj2obj1.sayName.call(obj2) // Sunshin_Lin// 扭转sayName的this指向obj2obj1.sayName.apply(obj2) // Sunshin_Lin// 扭转sayName的this指向obj2const fn = obj1.sayName.bind(obj2)fn() // Sunshin_Lin

40、数组的罕用办法有哪些?

办法作用是否影响原数组
push在数组后增加元素,返回长度
pop删除数组最初一项,返回被删项
shift删除数组第一项,返回被删项
unshift数组结尾增加元素,返回长度
reserve反转数组,返回数组
sort排序数组,返回数组
splice截取数组,返回被截取局部
join将数组变字符串,返回字符串
concat连贯数组
map雷同规定解决数组项,返回新数组
forEach遍历数组
filter过滤数组项,返回符合条件的数组
every每一项合乎规定才返回true
some只有有一项合乎规定就返回true
reduce承受上一个return和数组下一项
flat数组扁平化
slice截取数组,返回被截取区间

41、Math的罕用办法有哪些?

办法作用
Math.max(...arr)取arr中的最大值
Math.min(...arr)取arr中的最小值
Math.ceil(小数)小数向上取整
Math.floor(小数)小数向下取整
Math.round(小数)小数四舍五入
Math.sqrt(num)对num进行开方
Math.pow(num, m)对num取m次幂
Math.random() * num取0-num的随机数

42、JS中有哪些不同类型的弹出框?

在JS中有三种类型的弹出框可用,别离是:Alert、Confirm、Prompt

43、如何将 JS 日期转换为ISO规范

var date = new Date();var n = date.toISOString();console.log(n);// YYYY-MM-DDTHH:mm:ss.sssZ

44、如何在JS中编码和解码 URL

编码:encodeURI()解码:decodeURI()

45、什么是BOM?有哪些api?
BOM就是browser object model,浏览器对象模型

api作用代表办法或属性
window.history操纵浏览器的记录history.back() 、history.go(-1)
window.innerHeight获取浏览器窗口的高度
window.innerWidth获取浏览器窗口的宽度
window.location操作刷新按钮和地址栏location.host:获取域名和端口
window.location操作刷新按钮和地址栏location.hostname:获取主机名
window.location操作刷新按钮和地址栏location.port:获取端口号
window.location操作刷新按钮和地址栏location.pathname:获取url的门路
window.location操作刷新按钮和地址栏location.search:获取?开始的局部
window.location操作刷新按钮和地址栏location.href:获取整个url
window.location操作刷新按钮和地址栏location.hash:获取#开始的局部
window.location操作刷新按钮和地址栏location.origin:获取以后域名
window.location操作刷新按钮和地址栏location.navigator:获取以后浏览器信息

46、BOM 和 DOM 的关系

BOM全称Browser Object Model,即浏览器对象模型,次要解决浏览器窗口和框架。DOM全称Document Object Model,即文档对象模型,是 HTML 和XML 的利用程序接口(API),遵循W3C 的规范,所有浏览器公共恪守的规范。JS是通过拜访BOM(Browser Object Model)对象来拜访、管制、批改客户端(浏览器),因为BOM的window蕴含了document,window对象的属性和办法是间接能够应用而且被感知的,因而能够间接应用window对象的document属性,通过document属性就能够拜访、检索、批改XHTML文档内容与构造。因为document对象又是DOM的根节点。能够说,BOM蕴含了DOM(对象),浏览器提供进去给予拜访的是BOM对象,从BOM对象再拜访到DOM对象,从而js能够操作浏览器以及浏览器读取到的文档。

47、JS中的substr()和substring()函数有什么区别
substr() 函数的模式为substr(startIndex,length)。它从startIndex返回子字符串并返回'length'个字符数。

var s = "hello";( s.substr(1,4) == "ello" ) // true

substring() 函数的模式为substring(startIndex,endIndex)。它返回从startIndex到endIndex - 1的子字符串。

var s = "hello";( s.substring(1,4) == "ell" ) // true

48、解释一下 "use strict" ?

“use strict”是Es5中引入的js指令。应用“use strict”指令的目标是强制执行严格模式下的代码。在严格模式下,咱们不能在不申明变量的状况下应用变量。晚期版本的js疏忽了“use strict”。