10月上旬学习笔记(ES新特性,TS,JS性能优化)

296 阅读3分钟

由于上一篇文字数量超出限制所以js代码优化部分写在这里

上一篇地址:juejin.cn/post/688341…

TS部分:juejin.cn/post/688342…

第三部分:JS性能优化

十九:代码优化介绍

  1. 如何精准测试JavaScript性能--本质上就是采用执行样本进行数学统计和分析
  2. 可以使用jsbench.me/完成

二十:慎用全局变量

  1. 为什么要慎用

  2. 全局变量定义存在全局执行上下文,是所有作用域链的顶端

  3. 全局执行上下文一直存在于上下文执行栈,直到程序退出

  4. 如果某个局部作用域出现了同名变量则会遮蔽或者污染

    //全局      
    var i,str = "";      
    for (i = 0; i < 1000; i++) {        
    str += i;      
    }
    
     //局部      
    for (let i = 0; i < 1000; i++) {        
    let str = "";        
    str += i;      
    }
    

二十一:缓存全局变量

  1. 将使用中无法避免的全局变量缓存到局部(比如查找Dom元素,必须使用到document)

//没有使用缓存      
function getBtn1() {        
let oBtn1 = document.getElementById("btn1");        
let oBtn3 = document.getElementById("btn3");        
let oBtn5 = document.getElementById("btn5");        
let oBtn7 = document.getElementById("btn7");        
let oBtn9 = document.getElementById("btn9");      
}

//使用了缓存      
function getBtn2() {        
let obj = document; //缓存        
let oBtn1 = obj.getElementById("btn1");        
let oBtn3 = obj.getElementById("btn3");        
let oBtn5 = obj.getElementById("btn5");        
let oBtn7 = obj.getElementById("btn7");        
let oBtn9 = obj.getElementById("btn9");      
}

二十二:通过原型对象添加附加方法

  1. 通过原型新增方法

  2. 在原型对象上新增实例对象需要的方法

    // 没有使用原型对象;
    var fn1 = function () {
    this.foo = function () {
    console.log(11111);
    };
    };
    let f1 = new fn1();

    //使用原型对象
    var fn2 = function () {};
    fn2.prototype.foo = function () {
    console.log(11111);
    };
    let f2 = new fn2();

二十三:避开闭包的陷阱

//闭包特点      
function foo1() {        
var name = "xjq";        
return function fn() {          
console.log(name);        
};      
}      
foo1()();      
//闭包陷阱(产生内存泄漏)      
function foo2() {        
var el = document.getElementById("btn");        
el.onclick = function () {          
console.log(el.id);        
};        

//演示        
//优化--解决内存泄漏--释放内存空间        
el = null;      
}      
foo2();

二十四:避开属性访问方法使用

  1. JavaScript中的面向对象

  2. JS属性不需要属性的访问方法,所有属性都是外部可见的

  3. 使用属性访问方法只会加一层重定义,没有访问的控制力

    //使用属性访问
    function Person1() {
    this.name = "icoder";
    this.age = 18;
    this.getAge = function () {
    return this.age;
    };
    }
    const p1 = new Person1();
    const a = p1.getAge();

    //不使用属性访问
    function Person2() {
    this.name = "icoder";
    this.age = 18;
    }
    const p2 = new Person2();
    const b = p2.age;

二十五:循环优化

 var aBtns = document.getElementsByClassName("btn");      
for (let i = 0; i < aBtns.length; i++) {        
console.log(i);      
}      

//缓存aBtns长度,就不需要向上面的for一样,每次的获取length      
for (let i = 0, len = aBtns.length; i < len; i++) {        
console.log(i);      
}

二十六:选择最优的循环方案

  1. foreach

  2. for

  3. for..in

    //三中不同的循环-foreach优于for优于for-in
    var arrlist = new Array(1, 2, 3, 4, 5, 6, 7, 8, 9);
    arrlist.forEach(function (item) {
    console.log(item);
    });

    for (let i = 0, len = arrlist.length; i < len; i++) {
    console.log(arrlist[i]);
    }
    for (let i in arrlist) {
    console.log(arrlist[i]);
    }

二十七:文档碎片化优化节点

  1. 节点添加优化

  2. 节点的添加必然会有回流和重绘

    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.appendChild(oP);
    }
    document.body.appendChild(fragEle);

二十八:克隆优化节点操作

//克隆节点优于普通的      
for (var i = 0; i < 10; i++) {        
var oP = document.createElement("p");        
oP.innerHTML = i;        
document.body.appendChild(oP);      
}      

//优化--节点克隆      
var oldP = document.getElementById("box1");      
for (var i = 0; i < 10; i++) {        
var newP = oldP.cloneNode(false);        
newP.innerHTML = i;        
document.body.appendChild(newP);      
}

二十九:直接量替换new Object

//直接字面量      
var a = [1, 2, 3];      

//new Object      
var b = new Array(3);      
b[0] = 1;      
b[1] = 2;      
b[2] = 3;

三十:减少层级判断

//减少层级判断的代码快于没减少的      
function doSomething(part, chapter) {        
const parts = ["ES2016", "工程化", "Vue", "React", "Node"];        
if (part) {          
if (parts.includes(part)) {            
console.log("没有该课程");            
if (chapter > 5) {              
console.log("你不是vip");            
}          
}        
} else {          
console.log("没有输出课程");        
}      
}      
doSomething("ES2016", 6);      

//减少判断层级      
function doSomething1(part, chapter) {        
const parts = ["ES2016", "工程化", "Vue", "React", "Node"];        
if (!parts) {          
console.log("没有输出课程"); return;        
}        
if (!parts.includes(part)) return;        
console.log("没有该课程");        
if (chapter > 5) {          
console.log("你不是vip");        
}      
}      
doSomething1("ES2016", 6);

三十一:减少作用域链查找层级

  1. 下面案例优化了但是是有空间换了时间

    var name = "xjq";
    function foo() {
    name = "xjq666"; //此处的name是属于全局的
    function bar() {
    var age = 38;
    console.log(age);
    console.log(name); //这里沿着bar向上查找,在沿着foo查找到全局作用域才找到name
    }
    bar();
    }
    foo();

    //优化
    var name = "xjq";
    function foo() {
    var name = "xjq666"; //此处的name是属于foo的
    function bar() {
    var age = 38;
    console.log(age);
    console.log(name); //这里沿着bar向上查找,在着foo查找到name
    }
    bar();
    }
    foo();

三十二:减少数据读取次数

  1. 栈区的数据访问较快
  2. 堆区的数据访问较慢,因为需要按照引用的关系找到对应的位置

    var oBox = document.getElementById("skip");
    function hasEle(ele, cls) {
    return ele.className == cls;
    }

    //优化
    function hasEle(ele, cls) {
    var clsname = ele.className;
    return clsname == cls;
    }
    console.log(hasEle(oBox, "skip"));

三十三:字面量于构造式

//引用类型--使用字面量的函数优于使用构造式的,但是差异不大      
let test = () => {        
let obj = new Object();        
obj.name = "xjq";        
obj.age = 22;        
obj.slogan = "123456";        
return obj;      
};      
let test = () => {        
let obj = {          
name: "xjq",          
age: 22,          
slogan: "123456",        
};        
return obj;      
};      
//   test();      
console.log(test());      

//基本数据类型--使用字面量的优于使用构造式的,而且差异较大      
var str1 = "xjq";      
var str2 = new String("xjq");

三十四:减少循环体中活动

  1. 可以提取不必要的代码到循环体外执行(经常使用且不变的值)

    var test = () => {
    var i;
    var arr = ["xjq", 22, "男"];
    for (i = 0; i < arr.length; i++) {
    console.log(arr[i]);
    }
    };

    //优化
    var test = () => {
    var i;
    var arr = ["xjq", 22, "男"];
    var len = arr.length;
    for (i = 0; i < len; i++) {
    console.log(arr[i]);
    }
    };

    //while循环----while优于for--因为while是从后往前
    var test = () => {
    var arr = ["xjq", 22, "男"];
    var len = arr.length;
    while (len--) {
    console.log(arr[len]);
    }
    };

三十五:减少声明及语句

<div id="box" style="width: 100px; height: 100px"></div>

var oBox = document.getElementById("box");      
var test = (ele) => {        
let w = ele.offsetWidth;        
let h = ele.offsetHeight;        
return w + h;      
};     

 //优化      
var test = (ele) => {        
return ele.offsetWidth + ele.offsetHeight;      
};      
test(oBox);     

var test = () => {        
var name = "xjq";        
var age = 22;        
var slogan = "123456";        
return name + age + slogan;      
};      

//优化      
var test = () => {        
var name = "xjq",          
age = 22,          
slogan = "123456";        
return name + age + slogan;      
};      
test();

三十六:采用事件绑定

<ul id="ul">      
<li>x</li>      
<li>j</li>      
<li>q</li>    
</ul>

var list = document.querySelectorAll("li");      
function showTxt(ev) {        
console.log(ev.target.innerHTML);      
}      
for (let item of list) {        
item.onclick = showTxt;      
}      
var oUI = document.getElementById("ul");      
oUI.addEventListener("click", showTxt, true);