文章说明:本文章为拉钩大前端训练营所做笔记和心得,若有不当之处,还望各位指出与教导,谢谢 !
一、避开闭包陷阱
闭包特点
- 外部具有指向内部的引用
- 在‘‘外’’部作用域访问“内部”作用域的数据
function foo(){
var name = 'lg'
function fn(){
console.log(name)
}
return fn
}
var a = foo()
a()
- 闭包是一种强大的语法
- 闭包使用不当很容易出现内存泄漏,一旦内存出现泄漏,如果不在意,等它不断的泄漏时,会影响整个程序的性能
- 不要为了闭包而闭包
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" charset="UTF-8" />
<title>闭包陷阱</title>
</head>
<body>
<button id="btn">
Add
</button>
<script type="text/javascript">
// function foo(){ //由于闭包语法的存在,里面有些变量是无法回收的,在这种情况下,这种操作很多的时候,内存会越来越多
// var el = document.getElementById('Btn')
// el.onclick = function(){
// console.log(el.id)
// }
// }
// foo()
function foo(){
var el = document.getElementById('Btn')
el.onclick = function(){
console.log(el.id)
}
el = null//若是将DOM中button的节点删除之后,DOM中对document的引用消失了,把el置空之后,该函数对document的引用也消失了,这样的空间就会得以释放
}
foo()
</script>
</body>
</html>
二、避免属性访问方法使用
JavaScript中的面向对象
- JS不需属性的访问方法,所有属性都是外部可见的
- 使用属性访问方法只会增加一层重定义,没有访问的控制力
function Person(){
this.name = 'icoder'
this.age = 18
this.getAge = function(){
return this.age
}
}
const p1 = new Person()
const a = p1.getAge()//定义了一个成员属性的访问函数,直接调用函数访问
function Person(){
this.name = 'icoder'
this.age = 18
}
const p2 = new Person()
const b = p2.age//直接对属性名称进行访问
三、For循环优化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" charset="UTF-8" />
<title>For循环优化</title>
</head>
<body>
<p class="btn">add</p>
<p class="btn">add</p>
<p class="btn">add</p>
<p class="btn">add</p>
<p class="btn">add</p>
<p class="btn">add</p>
<p class="btn">add</p>
<p class="btn">add</p>
<p class="btn">add</p>
<p class="btn">add</p>
<script type="text/javascript">
var aBtns = document.getElementsByClassName('btn')
for(var i = 0;i < aBtns.length;i++){
console.log(i);
}
for(var i = 0,len = aBtns.length;i < aBtns.length;i++){//不需要像上面代码一样,每次都需要重新获取长度
console.log(i)
}
</script>
</body>
</html>
四、选择最优的循环方法
对数组进行遍历时,性能最好的forEach,其次是for,最后是for in
var arrList = new Array(1,2,3,4,5)
//三种不同的方式对同一数组进行遍历
arrList.forEach(function(item){
console.log(item)
})
for(var i = arrList.length;i;i--){
console.log(arrList[i])
}
for(var i in arrList){
console.log(arrList[i])
}
//对数组进行遍历时,性能最好的forEach,其次是for,最后是for in
五、文档碎片优化节点添加
节点的添加操作必然会有回流和重绘,对性能的消耗比较大:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" charset="UTF-8" />
<title>优化节点添加</title>
</head>
<body>
<button id="btn">
Add
</button>
<script type="text/javascript">
for(var i = 0;i < 10;i++){
var oP = document.createElement('p')
oP.innerHTML = i
document.body.appendChild(oP)
}
//第二种优化的方式创建节点
const fragEle = document.createDocumentFragment()//定义一个文档碎片的容器
for(var i = 0;i < 10;i++){
var oP = document.createElement('p')
oP.innerHTML = i
fragEle.body.appendChild(oP)
}
document.body.appendChild(fragEle)
</script>
</body>
</html>
采用文档碎片创建节点,效率更高一些
六、克隆优化节点操作
代码演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" charset="UTF-8" />
<title>克隆优化节点操作</title>
</head>
<body>
<p id="box1">old</p>
<script type="text/javascript">
for(var i =0;i <3;i++){
var oP = document.createElement('p')
op.innerHTML = i
document.body.appendChild(oP)
}
//克隆节点
var oldP = document.getElementById('box1')
for(var i =0; i < 3;i++){
var newP = oldP.cloneNode(false)// 通过节点克隆的方法
newP.innderHTML = i;
document.body.appendChild(newP)
}
</script>
</body>
</html>
七、直接量替换Object操作
当我们定义对象或数组的时候,我们可以用new 的方式来获取相应数据,但是也可以直接采用字面量
var a = [1,2,3]
var a1 = new Array(3)
a1[0] = 1
a1[1] = 2
a1[2] = 3