JS50个基础知识总结
为大家准备了50个基础知识点,来看看你了解多少吧,学习时间不长,如果有问题,欢迎评论。
1.JS数据类型
String, Number, Boolean, undifined, null, object, symbol, bigInt
object { function, array, Date, regexp}
2.JS最大最小安全数字
console.log(Number.MAX_SAFE_INTEGER)
Number.MAX_VALUE
1.7976931348623157e+308 10 * 10 ^ 308 309已经是Inifity
console.log(Number.MIN_SAFE_INTEGER)
Number.MIN_VALUE
5e-324 5* 10 ^324
3.深层拷贝与浅拷贝的区别
1. 深拷贝层层拷贝,浅拷贝只拷贝第一层,深层只是引用
2. 在深拷贝中,新对象中的更改不会影响原始对象,而在浅拷贝中,新对象中的更改,原始对象中也会跟着改。
3. 在深拷贝中,原始对象不与新对象共享相同的属性,而在浅拷贝中,它们具有相同的属性。
4.闭包是什么
闭包是一个能够读取其他函数内部变量的函数
function a () {
let num = 0
// 这是个闭包
return function () {
return ++num
}
}
const b = a()
console.log(b()) // 1
console.log(b()) // 2
5.原型链
6.变量提升,函数提升
函数提升优先级 > 变量提升的优先级 (红宝石P297)
函数声明会在任何代码执行之前添加到上下文当中,以便于所有的地方都能够调用改方法
变量提升会将变量提升至函数作用域顶端
7.isNaN 与 Number.isNaN 区别?
isNaN:除了判断NaN为true,还会把不能转为数字的判断为true,例如'xxx'
Number.isNaN 只有判断NaN时为true,其余情况都是false
8.解决遍历对象时,将原型的属性遍历出来 例如:
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
1.valueOf偏向于运算,toString偏向于显示
2.对象转换时,优先使用toString
3.强转字符串优先使用toString,强转数字优先调用valueOf
4.正常情况下,优先使用toString
5.运算操作符情况下优先使用valueOf
10.JS变量在内存中具体存储位置
基本数据类型: 栈内存
引用数据类型: 指针存 栈,指向堆内存当中的一块地址,内容存在堆内存当中
11.JS的封箱拆箱
封箱:把基本数据类型转化为对应的引用数据类型的操作
比如: let str = 'qweqweqwe' str.indexOf('e')
str很显然是一个字符串,但是他能用数组的方式来遍历,for-of, indexOf()等
原因是JavaScript内部进行了装箱操作
1.创建一个String类型的一个实例 var temp = new String('qweqweqwe')
2.在实例上调用指定的方法 temp.indexOf('e')
3. 销毁这个实例 temp = null
拆箱:将引用数据类型转化为对应的基本数据类型的操作
通过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 的异同点
相同点:
都是空变量
都是假值
null == undefined // true
不同点:
typeof null ==> object typeof undefined = undefined
null 转为数字 ==> 0 undefined ==> NaN
null 是一个对象未初始化 undefined是初始化了,但是未定义赋值
null === undefined // false
13.判断数据类型
14.为什么 typeof null 是 object
不同的数据类型在底层都是通过二进制表示的,二进制前三位为000则会被判断为object类型,
而null底层的二进制全都是0,那前三位肯定也是000,所以被判断为object
15. == 与 === 区别
== 仅比较值,===比较值与地址
16.JavaScript的隐式转换规则
转成string类型: +(字符串连接符)
转成number类型:++/--(自增自减运算符) + - * / %(算术运算符) > < >= <= == != === !=== (关系运算符)
转成boolean类型:!(逻辑非运算符)
17.双等号左右两边的转换规则?
null == undefined 为 true
如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false转换为0,而true转换为1;
如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值
如果一个操作数是对象,另一个操作数不是,则调用对象的toString()方法,用得到的基本类型值按照前面的规则进行比较
18.undefined >= undefined 为什么是 false ?
按照隐式转换规则,可转换成NaN >= NaN,NaN 不等于 NaN,也不大于,所以是false
19.null >= null 为什么是 true?
按照隐式转换规则,可转换成0 >= 0,0 等于 0,所以是true
20.[] == ![] 为什么是 true ?
1、! 优先级高于 ==,[]不是假值,所以先转换成 [] == false
2、右边为布尔值,false先转数字0,所以可转换为[] == 0
3、左边为对象,[]调用toString转为 '',转换为'' == 0
4、左边为字符串,''转换为0,最终为 0 == 0
21. 0.1 + 0.2 === 0.3 ?// false
不对,精度丢失
0.1 + 0.2 = 0.30000000000000004
22.匿名函数 // 就是没有函数名的函数
(function(x, y){
alert(x + y);
})(2, 3);
23.添加点击事件的方式
xxx.onclick = function (){}
<xxx onclick=""></xxx>
xxx.addEventListener('click', function(){}, false)
24.addEventListener第三个参数作用
第三个参数是一个布尔值,需不需要阻止冒泡,默认 false ,不阻止冒泡
25.函数声明与函数表达式的区别
函数声明: 享受函数声明提升
函数表达式: 归类于变量,享受变量提升
函数声明优先级 > 变量提升优先级
26.JavaScript的事件流模型有哪些?
事件捕获:由最不具体的元素接收,并往下传播 外到内 称为捕获阶段
事件冒泡:由最具体的元素接收,并往上传播 内到外 称为冒泡阶段
DOM事件流:事件捕获 -> 目标阶段 -> 事件冒泡
27.Ajax、Axios、Fetch有啥区别?
Ajax:是对XMLHttpRequest对象(XHR)的封装
Axios:是基于Promise对XHR对象的封装
Fetch:是window的一个方法,也是基于Promise,但是与XHR无关,不支持IE
28.load、$(document).ready、DOMContentLoaded的区别?
DOM文档加载的步骤为:
1.解析外部脚本文件
2.加载外部脚本和样式表文件
3.解析并执行脚本文件
4.DOM树构建完成, // DOMContentLoaded触发 $(document).ready 触发
5.加载图片等外部文件
6.页面加载完毕 // 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.数组去重
1.使用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
}
2.使用Set去重
function quchong(arr){
return [...new Set(arr)]
}
33.Set 与 Array 的区别
Array是一种存储在连续空间中的数据结构
Set像是一种抽象的数据结构,他只包含不同的对象,不需要分配连续的存储空间
最大的区别就是 Set当中每一个数据是唯一的,Array则可以重复
Set当中的数据都是唯一的,我们知道 NaN === NaN // false 但是在Set当中 NaN === NaN // true
34.Map 与 Object的区别
Map 自身支持迭代,Object 不支持。
35.NaN是什么?有什么特点
NaN === NaN // false
NaN为假值,转布尔值为false
NaN本质是一个number,typeof NaN === number
36.处理异步的方法有哪些
回调函数
promise
事件监听
发布订阅
async await
37.JS继承方式有几种
// 定义一个动物类
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) 会重写父类构造函数上定义的属性和方法
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()
cat.sleep() // Tom正在睡觉
console.log(cat instanceof Animal) // false
console.log(cat instanceof Cat) // true
优点:
1.不限制调用方式,不管是new 子类() 还是 子类(),返回的对象具有相同效果
缺点:
1.实例是父类的实例,不是子类的实例
2.不支持多继承
4.拷贝继承
核心:一个一个拷贝
function Cat(name){
var animal = new Animal()
for(let 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 = new Animal()
Super.prototype = Animal.prototype
Cat.prototype = new Super()
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.创建一个对象的方法有哪几种?
1.通过new Object创建
const obj = new Object()
obj.name = 'yzx'
2.字面量创建
const obj = {name: 'yzx'}
3.工厂模式创建
function creatrObj(name){
const obj = new Object()
obj.name = name
return obj
}
const obj = new createObj('yzx')
4.构造函数创建
function Person(name = 'yyy'){
this.name = name
}
const per = new Person('yzx')
39.this 指向的四种情况
1. new 操作符创建实例
function Person(name = 'yyy'){
this.name = name
}
const per = new Person('yzx') // 此时的this指向实例对象 per
2.指向window
function f(){
console.log(this)
}
f() // window
3.对象调用方法
const obj = {
f(){
console.log(this)
}
}
obj.f() // 此时为通过对象调用 所以指向 obj
4.call apply bind改变this
const obj = {
name: 'yzx',
sayName(){
console.log(this.name)
}
}
const obj2 = { name: 'yyy' }
obj.sayName.call(obj2) // yyy
obj.sayName.apply(obj2) // yyy
const fn = obj.sayName.bind(obj2) // bind的返回值是一个函数
fn()
40.数组的常用方法
方法 作用 影响原数组
push 在数组后添加元素,返回数组长度 √
pop 删除数组的最后一项,返回被删除项 √
shift 删除数组第一项,并返回被删除项 √
unshift 数组开头添加元素,返回新数组长度 √
reserve 反转数组,返回修改后的数组 √
sort 排序数组,返回修改后的数组 √
splice 截取数组,返回被截取的区间 √
join 将一个数组所有元素连接成字符串并返回 ×
concat arr1.concat(arr1, arr2)连接数组 ×
join arr.join()将数组元素拼接并返回 ×
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, n) num的n次幂
Math.random() * num 取 0-num 的随机数
// Math.random() * (y - x) + x 返回[x-y)区间的随机数
// Math.random() * (y - x) + x+1 返回(x-y]区间的随机数
42.内存泄露,如何解决
在此之前需要了解 V8 的垃圾回收机制
详细了解V8 的垃圾回收机制
详细了解内存泄露
43.JS垃圾回收机制 参考上连接
44.JS中有哪些不同类型的弹出框?
三种:
Alert 无返回值
confirm 返回值为 true / false 确认为true 取消为false
Prompt 返回值为输入内容
45.如何将 JS 日期转换为ISO标准
toISOString() 方法用于将js日起转换为ISO标准。他使用ISO标准将js Date对象转化为字符串
let date = new Date()
date // Sun Apr 03 2022 10:55:32 GMT+0800 (GMT+08:00)
date.toISOString() // '2022-04-03T02:55:32.637Z'
46.如何在JS中编码和解码URL
encodeURI() 函数用于在JS中对URL进行编码。他将url字符串作为参数并返回编码的字符串
注意:
encodeURI()不会编码类似于这样的字符: / ? : @ = + $ # ,如果想编码这些字符,使用 encodeURIComponent(),
var uri = "my profile.php?name=sammer&occupation=pāntiNG";
var encoded_uri = encodeURI(uri);
encoded_uri // 'my%20profile.php?name=sammer&occupation=p%C4%81ntiNG'
decodeURI函数用于解码js中的URL。他将编码的url字符串作为参数并 返回自己解码的字符串,用法:
var uri = "my profile.php?name=sammer&occupation=pāntiNG";
var encoded_uri = encodeURI(uri);
decodeURI(encoded_uri); // 'my profile.php?name=sammer&occupation=pāntiNG'
47.什么是BOM api有哪些
BOM 就是 browser object mdoel ,浏览器对象模型
api 作用 代表方法或属性
window.history 操作浏览器的记录 history.back()
history.go(-1)
window.innerHeight 获取浏览器窗口的高度
window.innerWidth 获取浏览器窗口的宽度
window.location 操作刷新按钮和地址栏
location.host:获取域名和端口
location.hostname:获取主机名
location.port:获取端口号
location.pathname:获取url的路径
location.search:获取?开始的部分
location.href:获取整个url
location.hash:获取#开始的部分
location.origin:获取当前域名
location.navigator:获取当前浏览器信息
48.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可以操作浏览器以及浏览器读取到的文档。
49.JS中的substr()和substring()函数有什么区别
substr(x, y) 是从x开始取 y个
subString(x, y) 是从取[x, y)
50. "use strict"
“use strict”是Es5中引入的js指令。 使用“use strict”指令的目的是强制执行严格模式下的代码。 在严格模式下,咱们不能在不声明变量的情况下使用变量。 早期版本的js忽略了“use strict”。