JavaScript作用域与函数进阶

js高级day01

2. 执行环境和其关联的变量对象 (了解: 能和别人聊这个)

执行环境: js运行的环境叫执行环境

所有js运行都有一个默认的全局执行环境, 在浏览器中, 这个执行环境是 window 对象

变量对象: 隐藏的 (开发的人,看不到, 只有js引擎才能看得到), 存着当前执行环境的标识符

什么是标识符?

变量名,函数名, 对象key , 形参

2.1 执行环境有哪些?
  1. 全局执行环境
  2. 函数执行环境(局部执行环境)
2.2 执行环境-栈

栈: 栈是一种数据结构(类似圆柱体), 栈的规则是先入后出

入栈: 在函数 调用 的时候, 会把当前函数执行环境 放入 执行栈中 , 这个叫入栈

出栈: 在一个js中, 所有的函数全部进入 栈 后, 没有新的函数入栈, 继续执行 就会出栈, 函数出栈会被销毁

3 作用域链(掌握: 你除了能和别人说之外,还需要会用)

3.1 作用域

概念: 作用域可以理解为 标识符 以及 标识符所能访问的范围

什么是标识符?

变量名,函数名, 对象key , 形参

3.2 作用域链

概念: 标识符 所查找的规则, 从里往外, 一层一层向上找, 找到全局作用域截止, 如果没找到, 就会报错

作用: 确保对执行环境中的变量和函数的有序访问

3.3 作用域的分类
  • es5
    • 全局作用域
    • 函数作用域(局部作用域)
    • 没有块级作用域
  • es6
    • 新增了块级作用域( es6中, 使用 let 和 const 新增了块级作用域 )

什么块级作用域? 一个花括号 { 开始, 另一个 } 结束, 两个花括号之间的内容叫做代码块, 在es6中, 代码块也叫块级作用域

块级作用域作用: 主要是为了解决变量的全局污染问题

4 函数进阶(精通: 可以和比人聊, 可以使用,并且使用的是滚瓜乱熟)

4.1 箭头函数

语法:

// 使用函数表达式才能创建
const add = (num1, num2) => {
	return num1 + num 2
}

// 1. 简化写法, 如果只有一行代码  可以省略 花括号, 有return的话也可省略return
const add1 = (num1, num2) => num1 + num2

// 2. 简化写法, 如果只有一个形参的话, 可以省略小括号
const add2 = num => num + 2

注意(箭头函数特别需要注意的事项):

  1. 箭头函数内, 没有自己this (后面的课程中会讲, 先记住这句话)
  2. 箭头函数不可以当作构造函数使用 , 箭头函数 不能 new 调用 (后面的课程也会将)
  3. 箭头函数没有 arguments (马上会讲)
4.2 函数的参数

形参: 定义函数时的列举的变量

实参: 调用函数时所传的值

4.3 函数的默认值

语法:

// es5 的写法,  函数可以不传参调用, 但是不传参  就要写一个默认值
function add(num) {
     num = num || 5  // || 前面是true就用前面的, 是false就用后面的
     return num + 1
}

// es6 默认值
function add(num = 5) {
  return num + 1
}
4.4 arguments
  1. arguments 是伪数组, 获取函数所传入的所有参数
  2. arguments 只有es5的写法才有, es6的箭头函数没有
4.5 rest 剩余参数

语法:

// 剩余参数需要注意的点是:  剩余参数一定要放到最后面
const add = (num1, num2, ...nums) => {
  console.log(nums)  // 会是真正的数组
  // 拿到的剩余参数
  // 1. 去做循环计算
  // 2. 去做判断
  // 3. 防止改需求, 要加参数的情况
  // ...
}
add(1, 2, 3)  // 一三五传 1,2,3
4.6 函数的返回值

return 是函数返回的核心, 如果一个函数, 没有return, 那么肯定没有返回值, 就是 undefined, 有了retrun 那么renturn什么 ,返回值就是什么

4.7 函数对的调用
  1. 作为一般函数调用

    function add() {}
    add()
    

  2. 作为对象函数调用

    const obj = {
      show: function() {}
    }
    obj.show()
    

  3. 回调函数调用

    setTimeout(() => {}, 1000) // 第一个函数的实参是回调函数,  1s之后调用
    

  4. 构造函数调用

  5. bind(),call(),apply()调用

  6. 作为立即执行函数调用

4.8 立即执行函数表达式

语法:

;(function() {
  console.log('修仙之调用')
})()

作用: 实现模块化

// 1. 在js中使用立即执行函数
// 2. 出口放在window上

5 闭包

概念: 函数跨作用域访问变量, 那么这个函数以及它所访问的变量就形成了闭包

闭包的作用: 变量私有化

5.1 闭包常见的使用场景
  1. 在嵌套函数中使用

    // 一个函数,嵌套着一个函数  叫做嵌套函数
    function mom() {
      var money = 500
    
      function spendMoney() {
        console.log(money)
        money -= 100
      }
    
      return spendMoney
    }
    
    var spend = mom()
    spend()
    

  2. 闭包解决计数器的问题

    function add() {
      var num = 100
      return function () {
        return num++
      }
    }
    
    var nums = add()
    console.log(nums())
    console.log(nums())
    console.log(nums())
    

  3. 闭包解决定时器的问题

    for (var i = 0; i < 5; i++) {
    
      ; (function (k) {
        setTimeout(() => {  
          console.log(k)  // 0.1.2.3.4
        }, 0)
      })(i)
    }
    

  4. 闭包解决事件绑定的问题

    for (var i = 0; i < lis.length; i++) {
    
      ; (function (k) {
        lis[k].addEventListener('click', function () {  // 事件绑定是异步的, 放到最后执行, 输出就是全局的i
          alert(k)
        })
      })(i)
    }
    

  5. 闭包结合IIFE实现模块化(非常经典 --> 现在不用)

作业: 滴滴真题

var b = 'B'

function fun(a, b) {
  console.log(b)  

  return {
    fun: function(c) {
    	return fun(c, a)
    }
  }
}

var a = fun(0); 
a.fun(1); 
a.fun(2); 
a.fun(3); // 输出什么?

var b = fun(0).fun(1).fun(2).fun(3); // 输出什么? // 

var c = fun(0).fun(1); 
c.fun(2); 
c.fun(3); // 输出什么?

提示:

  1. 核心输出的是b
  2. 链式调用, 有返回值才能链式调用
  3. 最里面return 是函数的调用, 调用就会返回新的返回值
  4. 最后调用 a 哪里形成了闭包, a就不会被销毁
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值