1、JavaScript有几种数据类型?
number:数字类型
string:字符串类型
boolean:布尔值类型
undefined:未定义类型
null:空类型
object:对象类型
symbol:symbol类型
bigint:大数字类型
2、JavaScript最大平安数字与最小平安数字?
console.log(Number.MAX_SAFE_INTEGER)
// 9007199254740991
console.log(Number.MIN_SAFE_INTEGER)
// -9007199254740991
3、深拷贝与浅拷贝的区别?
浅拷贝:只拷贝第一层,深层的仍然是援用,扭转深层会影响原对象
深拷贝:每一层都拷贝了,扭转数据不会影响原对象
4、闭包是什么?
闭包是一个函数,是一个能让内部拜访到函数外部的函数
长处:使内部能拜访外部,缩短外部变量寿命
毛病:滥用闭包造成内存透露
例子:
function a () {
let num = 0
// 这是个闭包
return function () {
return ++num
}
}
const b = a()
console.log(b()) // 1
console.log(b()) // 2
5、原型链是什么
原型链是一条援用的链,实例的隐式原型指向构造函数的显式原型,能够应用A instanceof B来判断B是否在A的原型链上。
6、什么是变量晋升?函数晋升?
变量晋升
console.log(name) // undefined
var 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 = 23
const person = new Person('Sunshine_lin')
for (const key in person) { console.log(key) } // name age
// 应用 hasOwnProperty
for (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 = null
console.log(index) // 8
拆箱:将援用数据类型转化为对应的根本数据类型的操作
通过valueOf或者toString办法实现拆箱操作
var objNum = new Number(123);
var objStr =new String("123");
console.log( typeof objNum ); //object
console.log( typeof objStr ); //object
console.log( typeof objNum.valueOf() ); //number
console.log( typeof objStr.valueOf() ); //string
console.log( typeof objNum.toString() ); // string
console.log( typeof objStr.toString() ); // string
12、null和undefined的异同点有哪些?
相同点
1、都是空类型
2、转布尔值都是false,都是假值
3、null == undefined 为 true
不同点
1、typeof,前者为object,后者为undefined
2、null转数字为0,undefined转数字为NaN
3、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 为 true
2、如果有一个操作数是布尔值,则在比拟相等性之前先将其转换为数值——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、unshift
Set长度为size,数组为length
Set会主动把同样的根底数据类型去重,数组不能
Set删除元素用delete,数组用splice、pop、shift
Set能够应用clear清空,数组须要从新赋值[]
数组能够传入new Set(array),实现数组转Set
Set能够应用keys、value办法,转数组
Set自带forEach办法进行遍历
34、Map与Object的区别是什么?
Map应用set设置属性,对象应用obj[key] = value
Map应用get获取属性值,对象应用obj[key]
Map应用has判断属性存在与否,对象只能obj[key]
Map删除元素应用delete办法,对象应用delete关键字
Map应用clear进行情空,对象须要从新赋值{}
Map和对象都能够应用entries办法转数组键值对
Map自带forEach办法进行遍历
35、NaN是什么?有什么特点?
typeof NaN 为 number
NaN不等于本身,不大于本身,不小于本身
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); // cat
cat.eat('fish') // cat正在吃:fish
cat.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); // Tom
cat.sleep() // Tom正在睡觉!
console.log(cat instanceof Animal); // false
console.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) // Tom
cat.sleep() // Tom正在睡觉!
console.log(cat instanceof Animal); // true
console.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); // Tom
cat.sleep() // Tom正在睡觉!
console.log(cat instanceof Animal); // false
console.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); // Tom
cat.sleep() // Tom正在睡觉!
console.log(cat instanceof Animal); // true
console.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 Code
var cat = new Cat();
console.log(cat.name); // Tom
cat.sleep() // Tom正在睡觉!
console.log(cat instanceof Animal); // true
console.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.fn
fn() // 浏览器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指向obj2
obj1.sayName.call(obj2) // Sunshin_Lin
// 扭转sayName的this指向obj2
obj1.sayName.apply(obj2) // Sunshin_Lin
// 扭转sayName的this指向obj2
const 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”。
发表回复