1.2.3 - JavaScript 性能优化(堆栈-下)

146 阅读3分钟
  • 执行环境栈
  • 创建执行上下文
  • 进栈执行
    • 作用域
    • 确定this
    • 初始化arguments 形参赋值
    • 变量提升
    • 代码执行
  • 考虑是否出栈

★ 26-引用类型堆栈处理

var obj1 = { x: 100 }
var obj2 = obj1
obj1.y = obj1 = { x: 200 }
console.log(obj1.y)
console.log(obj1)
console.log(obj2)

undefined // 为什么是undefined,就是因为是新的{x:200}是新在堆内开的空间,里面没有y
{ x: 200 } // obj1的地址变了
{ x: 100, y: { x: 200 } }  // obj2的地址没有变,

具体看视频吧,懒得写了,26-引用类型堆栈处理
--------------------------------

var obj1 = { x: 100 }
var obj2 = obj1
// obj1.y = obj1 = { x: 200 }
obj1.y = obj1 
console.log(obj1.y)
console.log(obj2)


{ x: 100, y: [Circular] }
{ x: 100, y: [Circular] }


★ 27-函数堆栈处理 03-func-init

var arr = ['zce', 'alishi']

function foo(obj) {
  obj[0] = 'zoe'
  obj = ['哈哈哈']
  obj[1] = '嘿嘿嘿'
  console.log(obj)
}

foo(arr) //  [ '哈哈哈', '嘿嘿嘿' ]
console.log(arr)  //  [ 'zoe', 'alishi' ]
/**
 * 01 函数创建
 * -- 可以将函数名称看做是变量,存放在 VO 当中 ,同时它的值就是当前函数对应的内存地址
 * -- 函数本身也是一个对象,创建时会有一个内存地址,空间内存放的就是函数体代码(字符串形式的)
 * 02 函数执行
 * -- 函数执行时会形成一个全新私有上下文,它里面有一个AO 用于管理这个上下文当中的变量
 * -- 步骤:
 *  01 作用域链 <当前执行上下文, 上级作用域所在的执行上下文>
 *  02 确定 this
 *  03 初始化 arguments (对象)
 *  04 形参赋值:它就相当于是变量声明,然后将声明的变量放置于 AO
 *  05 变量提升
 *  06 代码执行
 */

★ 28闭包堆栈处理- 04-closure-init

var a = 1
function foo() {
  var b = 2
  return function (c) {
    console.log(c + b++)
  }
}

var f = foo()
f(5)   // 7  【执行完c+b之后,输出,b自增b++ = 3】
f(10)   // 13a+b = 10+3 =13   b++  b=4/**
 * 01 闭包: 是一种机制:
 *  保护:当前上下文当中的变量与其它的上下文中变量互不干扰
 *  保存:当前上下文中的数据(堆内存)被当前上下文以外的上下文中的变量所引用,这个数据就保存下来了
 * 02 闭包:
 *  函数调用形成了一个全新的私有上下文,在函数调用之后当前上下文不被释放就是闭包(临时不被释放)
 */


//当前上下文中的地址,被当前上下文以外的地址引用,导致执行完释放不掉


★ 解决var 变量问题

  • 闭包

  • 自定义属性

  • 事件委托

闭包 空间多 记得要置null

// 闭包1
for (var i = 0; i < aButtons.length; i++) {
 (function (i) {
   aButtons[i].onclick = function () {
     console.log(`当前索引值为${i}`)
   }
 })(i)
}

// 闭包2
for (var i = 0; i < aButtons.length; i++) {
 aButtons[i].onclick = (function (i) {
   return function () {
     console.log(`当前索引值为${i}`)
   }
 })(i)
}

// aButtons = null  // 闭包申请的空间更多了 ,最后要记得置为null,才会释放空间,

自定义属性 空间少

for (var i = 0; i < aButtons.length; i++) {
 aButtons[i].myIndex = i
 aButtons[i].onclick = function () {
   console.log(`当前索引值为${this.myIndex}`)
 }
}

★ 怎么样开发节省时间

JSBench :在线测试js代码执行效率的网站 jsbench.me/

35 变量局部化

36 缓存数据

37 减少访问层级

42 减少判断层级if else 1.提前return掉 、2.明确的条件用Switch case

43 减少循环体活动 for里面少计算,代码越少越好,或者用while(length--),从后往前循环

44 字面量与构造式,字面量比构造式快,因为new 的时候会调用函数也会开辟新空间