Web前端基础知识整理
1. typeof返回的数据类型
typeof返回的数据类型包括undefined、string、number、boolean、symbol、Object、Function类型。
2. 检查数组的方式
isArray()方法、toString.call()、instanceof Array


3. js中的call、apply、bind方法的区别
js中的call apply bind都是用来改变方法上下文(context),就是可以使函数可以被其他对象调用。
let hxy = {
name: 'hxy',
age: 22,
say(x, y) {
console.log(this.name + ':' + this.age + x + y);
}
}
let yyw = {
name: 'yyw',
age: 18
}
hxy.say(1, 2); // 实际上是调用的this.say() this指的是hxy
hxy.say.apply(yyw, [1, 2]);// 调用apply后this改变指向,this指向yyw,相当于yyw.say()
hxy.say.call(yyw, 1, 2);
hxy.say.bind(yyw, 1, 2)();
运行结果:
)
上面的代码就改变了this指向,使得hxy对象的say方法可以被yyw调用
apply与call、bind的区别
apply与call的作用完全相同,只是传参方式不一样,如有下面的函数:
let func = function(arg1, arg2) {
};
就可以通过如下方式来调用:
func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])
func.bind(this, arg1, arg2)()
call把参数按照顺序传进去,而apply存放在一个数组中
bind()也是用来改变上下文,但是他返回一个方法,不会像call或者apply那样立即调用,
Javascript中存在一种名为伪数组的对象结构。比较特别的是 arguments 对象,还有像调用 getElementsByTagName , document.childNodes 之类的,它们返回NodeList对象都属于伪数组。不能应用 Array下的 push , pop 等方法。
但是我们能通过 Array.prototype.slice.call 转换为真正的数组的带有 length 属性的对象,这样 domNodes 就可以应用 Array 下的所有方法了。
let arguments = Array.prototype.slice.call(arguments);
定义一个 log 方法,让它可以代理 console.log 方法
function log(){
console.log.apply(console, arguments);
};
log(1); //1
log(1,2); //1 2
4.闭包
简单来说,闭包就是指能读取其他函数内部变量的函数
闭包的简单应用:
function f1() {
var n = 99;
function f2() {
return n;
}
return f2;
}
var result = f1();
console.log(result());
运行结果返回了f1中的变量n

闭包的一个作用就是可以读取函数内部的变量,另一个作用就是让闭包中的变量始终保存在内存中,闭包中的变量在函数被调用完后不会被自动清除。(这样也容易引发内存泄漏,因此在用闭包的时候要注意即时清除不需要的变量)
5. js事件机制
DOM事件流分为三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段
事件捕获(event capturing):通俗的理解就是,当鼠标点击或者触发dom事件时,浏览器会从根节点开始由外到内进行事件传播,即点击了子元素,如果父元素通过事件捕获方式注册了对应的事件的话,会先触发父元素绑定的事件。
事件冒泡(dubbed bubbling):与事件捕获恰恰相反,事件冒泡顺序是由内到外进行事件传播,直到根节点。
dom标准事件流的处理顺序为先捕获、再冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#parent {
width: 200px;
height: 200px;
text-align: center;
background: green;
line-height: 3;
}
#child {
width: 100px;
height: 100px;
margin: 0 auto;
background: orange;
}
</style>
</head>
<body>
<div id="parent">
父元素
<div id="child">
子元素
</div>
</div>
<script type="text/javascript">
let parent = document.getElementById("parent");
let child = document.getElementById("child");
document.body.addEventListener("click", function (e) {
console.log("click body");
}, false);
parent.addEventListener("click", function (e) {
console.log("click parent");
}, false);
child.addEventListener("click", function (e) {
console.log("click clild");
// e.stopPropagation();
}, false);
</script>
</body>
</html>
UI界面如下:

点击子元素会发生什么呢?

点击子元素会发生事件冒泡,先调用子元素的事件,再调用父元素的事件。
addEventListener()的第三个参数为是否采用事件捕获。这里选择false,事件不会进行捕获。
如果想阻止事件冒泡,只需调用e.stopPropagation()即可。在child的回调方法中加入该方法的时候:

可以看到事件没有继续向上传递。
为了测试事件冒泡,我们加入事件冒泡函数:
parent.addEventListener("click", function (e) {
console.log("事件捕获");
}, true);
文章链接:https://www.lilianhua.com/sorting-out-the-basic-knowledge-of-web-front-end.html
English (US)
Español (ES)
Português (PT)
Français (CA)
Español (MX)
Español (VE)
Español (CO)
Español (AR)
Português (BR)
Quechua (PE)
Guaraní (PY)
简体中文 (ZH)
繁體中文 (HK)
日本語 (JP)
한국어 (KR)
हिन्दी (HI)
Pilipino (PH)
ไทย (TH)
Tiếng Việt (VN)
Bahasa Melayu (MY)
Bahasa Indonesia (ID)
বাংলা (BD)
اردو (PK)
සිංහල (LK)
ភាសាខ្មែរ (KH)
English (UK)
Français (FR)
Deutsch (DE)
Italiano (IT)
Русский (RU)
Nederlands (NL)
Türkçe (TR)
Polski (PL)
Svenska (SE)
Norsk (NO)
Dansk (DK)
Suomi (FI)
Ελληνικά (GR)
Čeština (CZ)
Magyar (HU)
Română (RO)
Български (BG)
Српски (RS)
Українська (UA)


