JavaScript作用域与执行上下文

在说作用域和执行上下文中先来讨论一下很多人函数传参是对象的到底是按值传递还是按引用传递的疑问?

函数传参

ECMAScript 中所有函数的参数都是按值传递的,变量有按值和按引用访问,而传参则只有按值传递

看下列代码:

person变量指向一个对象的引用(或者是指针值、内存地址),执行setName函数时person的引用按值传递给了参数obj,obj和person的值都是相同的引用,obj也会通过引用访问对象,在改变了name的值后也就修改了该引用指向的对象,所以外部person引用指向的对象也会反映这个变化。

let person = {
    
    name:'haha'}
function setName(obj){
    
    
    obj.name = 'kaka'
}
setName(person)
console.log(person.name)//kaka

错误认识:有的人认为在setName中修改这个对象反映到了全局,意味着是按引用传递的。

纠正代码如下:如果是按引用传递的话,那么obj指向的对象将会被赋值为一个空对象后且设置name为lala,同理person也因如此。事实相反,obj的重新赋值并不会影响person,证明不管是函数参数是原始值还是引用值都是按值传递的

let person = {
    
    name:'haha'}
function setName(obj){
    
    
    obj.name = 'kaka'
    obj = new Object()
    obj.name = 'lala'
}
setName(person)
console.log(person.name)//kaka

执行上下文与作用域

我觉得执行上下文咋理解,这是个抽象的概念,然后它在什么时候出现?就是在代码执行的时候,代码执行的时候,无非就是访问变量,调用函数,在当前执行代码环境下(可全局可函数可块级),都会去查找执行代码的时可访问的所有变量和函数按照访问顺序排好拿出来做一个变量对象,就是这段代码的执行上下文。

执行上下文也成为作用域,分为全局上下文、函数上下文和块级上下文。

上下文在其所有的代码都执行完毕之后会被销毁,包括定义在它上面的所有的变量和函数(全局上下文在应用程序退出前才会被销毁,比如关闭网页或者退出浏览器)。

每个函数调用都有自己的上下文。当代码执行流进入函数时,函数的上下文被推到一个上下文栈上。在函数执行完之后,上下文栈会弹出该函数的上下文,将控制权返还给之前的执行上下文。ECMAScript程序的执行流就是通过这个上下文栈进行控制的。

针对执行上下文举个例子:

let color = 'red'
function changeColor(){
    
    
    let anotherColor = 'yellow'
    function swapColor(){
    
    
        let tempColor = 'black'
        //这里可以访问color、anotherColor、tempColor
        [color,anotherColor] = [anotherColor,color]
    }
    //这里可以访问color、anotherColor
    swapColor()
}
//这里可以访问color
changeColor()

下面是代码展示作用域链,矩形展示的是不同的上下文:
在这里插入图片描述

参考链接

JavaScript高级程序设计(第四版)

猜你喜欢

转载自blog.csdn.net/weixin_42060560/article/details/110312665
今日推荐