1.数据类型
- number:数字类型
- string:字符串类型
- boolean:布尔值类型
- undefined:未定义类型
- null:空值类型
- object:对象类型
- symbol:symbol类型
- bigint:大数字类型
2.闭包
可以读取其他函数内部变量的函数。
缺点:容易内存泄漏
优点:外部可以访问局部
3. 原型 原型链
- prototype: 显式原型
- __ proto__: 隐式原型
//首先两个类并实例化
class Person{
constructor(value) {
this.value = value
}
teach(a){
console.log('你好,调用了Person类teach方法',a)
}
}
//继承类Person
class PersonF extends Person{
constructor(value) {
super(value)
}
son(a){
console.log('你好,调用了PersonF类son方法',a)
}
}
let Person0 = new Person('小明')
let PersonF1 = new PersonF('小红')
//此时分配了四块内存如图所示
我们接下来看看什么是原型 什么是原型链
PersonF1.teach(‘调用成功’)
这个是继承类的实例对象调用被继承类中的方法 在这个原型链上进行调用多个过程
console.log(typeof Person,typeof Person0)
// 这是使用了了四个内存
console.log(Person === PersonF)
console.log(Person === Person0)
console.log(Person0 === PersonF1)
// 下面我们要通过 实例PersonF1调用teach方法 //prototype __proto__
PersonF1.teach('调用成功') //调用成功
console.log('对象PersonF1的隐性原型是否和PersonF的显性原型指向同一块地址',PersonF1.__proto__ === PersonF.prototype)
console.log('类PersonF的隐性原型是否和Person是同一块内存地址',PersonF.__proto__ === Person)
console.log('从Person上找到方法teach',Person.prototype.teach)
console.log('继承之后的方法是否又分配新的内存?(true标识没有)',Person.prototype.teach === PersonF.prototype.teach)
//所以看图
4.作用域 作用域链
5.变量提升 函数提升
通常JS引擎会在正式执行之前先进行一次预编译,在这个过程中,首先将变量声明及函数声明提升至当前作用域的顶端,然后进行接下来的处理
引擎是把函数声明整个地提升到了当前作用域的顶部
/*
变量提升
*/
console.log(namea) // undefined
var namea = '找不到'
if (false) {
var age = 23
}
console.log(age) // undefined
/*
函数提升
*/
console.log(fun) // function fun() {}
function fun() {}
if (false) {
function fun2(){}
}
console.log(fun2) // undefined
6.isNaN 和 Number.isNaN
- isNaN:除了判断NaN为true,还会把不能转成数字的判断为true,例如’xxx’
- Number.isNaN:只有判断NaN时为true,其余情况都为false
7.遍历原型的属性(const key in object)
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
8.valueOf 与 toString
1、valueOf
偏向于运算,toString
偏向于显示
2、对象转换时,优先调用toString
3、强转字符串优先调用toString
,强转数字优先调用valueOf
4、正常情况下,优先调用toString
5、运算操作符情况下优先调用valueOf
9.变量在内存中存在形式
- 基本数据类型:存在
栈内存
里 - 引用数据类型:指针存
栈内存
,指向堆内存
中一块地址,内容存在堆内存中 - 也有说法说其实JavaScript所有数据都存
堆内存
中,我也比较赞同这种说法
10. null undefined
相同点
- 都是空变量
- 都是假值,转布尔值都是false
- null == undefined 为 true
不同点
- typeof判断null为object,判断undefined为undefined
- null转数字为0,undefined转数字为NaN
- null是一个对象未初始化,undefined是初始化了,但未定义赋值
- null === undefined 为 false
11. 0.1 + 0.2 === 0.3,对吗?
不对,JavaScript的计算存在精度丢失问题
console.log(0.1 + 0.2 === 0.3) // false
复制代码
- 原因:JavaScript中小数是浮点数,需转二进制进行运算,有些小数无法用二进制表示,所以只能取近似值,所以造成误差
- 解决方法:
- 先变成整数运算,然后再变回小数
- toFixed() 性能不好,不推荐
12. 绑定点击的方式
xxx.onclick = function (){}
<xxx onclick=""></xxx>
xxx.addEventListener('click', function(){}, false)
13.函数声明 和 函数表达式
- 函数声明:享受函数提升
- 函数表达式:归类于变量声明,享受变量提升
- 函数提升优先级 > 变量提升优先级
console.log(fun) // fun () {}
// 函数表达式
var fun = function(name) {}
// 函数声明
function fun () {}
console.log(fun) // fun (name) {}
14. JavaScript的事件流模型有哪些?
- 事件冒泡:由最具体的元素接收,并往上传播
- 事件捕获:由最不具体的元素接收,并往下传播
- DOM事件流:事件捕获 -> 目标阶段 -> 事件冒泡
//代码描写事件冒泡
点击儿子 父亲也会运行他自己的onclick() 阻止冒泡避免发生
<script type="text/javascript">
var div1 = document.querySelector(".div0");
var div2 = document.querySelector(".div1");
div2.onclick = function(){console.log('儿子')};
div1.onclick = function(){console.log('父亲')};//父亲
//阻止冒泡
function stopBubble(e) {
if (e.stopPropagation) {
e.stopPropagation()
} else {
window.event.cancelBubble = true;
}
}
</script>
<style type="text/css">
.div0{
width: 200px;
height: 200px;
background-color: antiquewhite;
}
.div1{
width: 100px;
height: 100px;
background-color: aqua;
}
</style>
15.Ajax、Axios、Fetch
- Ajax:是对XMLHttpRequest对象(XHR)的封装
- Axios:是基于Promise对XHR对象的封装
- Fetch:是window的一个方法,也是基于Promise,但是与XHR无关,不支持IE
16.load、$(document).ready、DOMContentLoaded的区别?
DOM文档加载的步骤为:
- 1、解析HTML结构。
- 2、加载外部脚本和样式表文件。
- 3、解析并执行脚本代码。
- 4、DOM树构建完成。//
DOMContentLoaded
触发、$(document).ready
触发 - 5、加载图片等外部文件。
- 6、页面加载完毕。//
load
触发
17.事件委托(性能大幅度优化)
当所有子元素都需要绑定相同的事件的时候,可以把事件绑定在父元素上,这就是事件委托
。
- 绑定在父元素上只需要绑定一次,节省性能
- 子元素不需要每个都去绑定同一事件
- 如果后续又有新的子元素添加,会由于事件委托的原因,自动接收到父元素的事件监听
//代码展示
当前有四(或者n)个选项 点击将触发事件 如果传统写法
window.onload = function(){
var oUl = document.getElementById("ul1");
var aLi = oUl.getElementsByTagName('li');
for(var i=0;i<aLi.length;i++){
aLi[i].onclick = function(){
alert(123);
}
}
}
//加上冒泡 性能损耗巨大
//采用事件委托
//点击父节点触发获取鼠标点击元素 来触发函数 逻辑 性能 提高代码更加简洁
<div class="oBox">
<li id="s1" class="s0">这是1</li>
<li id="s2" class="s0">这是2</li>
<li id="s3" class="s0">这是3</li>
</div>
<script type="text/javascript">
let bb = document.querySelector('.oBox')
bb.onclick = function (ev) {
ev = ev || window.event //点击事件 获取元素
let nowClickDom = ev.target //获取到 dom节点 点击的
console.log(nowClickDom)
}
</script>
18.数组去重
// 使用 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)]
}
19. …用法
let a = { b : 1}
let c = a
let a = {b:1}
let c = a
//现在c和a指向相同
//使用 ...
let d = {...a}
console.log(d)
a.b = 2
console.log(a,d)
//同理 数组[...arr]
20. set 数据结构
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
(查看阮一峰老师详解)https://es6.ruanyifeng.com/#docs/set-map
遍历:
Set.prototype.keys()
:返回键名的遍历器Set.prototype.values()
:返回键值的遍历器Set.prototype.entries()
:返回键值对的遍历器Set.prototype.forEach()
:使用回调函数遍历每个成员
21.map数据结构
JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。为了解决这个问题,ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。
const m = new Map();
const o = {p: 'Hello World'};
m.set(o, 'content')
m.get(o) // "content"
m.has(o) // true
m.delete(o) // true
m.has(o) // false
(查看阮一峰老师详解)https://es6.ruanyifeng.com/#docs/set-map
22.继承
1.原型链继承
2.构造继承
3.实例继承
4.拷贝继承
5.组合继承
6.寄生组合继承
23. this指向
24.数组常用方法
25.Math的常用方法
26.内存泄漏
27.垃圾回收
28.BOM操作
本文内容参考文章(
作者:Sunshine_Lin
链接:https://juejin.cn/post/7020940475133591566
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
)