关于javascript:前端基础进阶-变量对象

50次阅读

共计 1423 个字符,预计需要花费 4 分钟才能阅读完成。

咱们曾经晓得, 在调用一个函数时, 一个新的执行上下文将会被创立, 而一个执行上下文的周期分为两个阶段

  • 创立阶段: 在这个阶段, 执行上下文将会别离创立变量对象, 建设作用域链, 确定 this 指向
  • 执行阶段: 创立实现后, 就会执行代码, 这时候会实现变量赋值, 函数援用, 以及一些其余代码

从这里咱们能够看到, 执行上下文时波及到了变量对象, 作用域链, this 指向等很多重要的概念. 这里咱们次要了解变量对象

变量对象

变量对象的创立经验以下三个过程:

  • 建设 argument 对象. 查看以后上下文中的参数, 建设该对象的属性和属性值
  • 查看以后上下文的函数申明. 也就是应用 function 关键字申明的函数. 在变量对象中, 以函数名作为一个属性, 属性值指向该函数所在内存地址的一个援用. 如果该函数名属性曾经存在, 则该属性将会被新的援用所笼罩
  • 查看以后上下文的变量申明. 每找到一个变量申明, 就在变量对象中以变量名建设一个属性, 属性值为 undefined. 如果该变量名的属性曾经存在, 则会间接跳过, 原属性值不会发生变化


依据这个规定, 了解变量晋升就变得更加简略, 能够应用变量对象的创立过程来解释变量晋升

比方上面例子

console.log(foo) // function foo (){}
function foo (){}
var foo = 20
// 上述代码的执行程序为
// 首先将所有函数申明放入变量对象中
function foo () {}
// 其次将所有变量申明放入变量对象中, 然而 foo 曾经存在同名函数, 则 foo = undefined 会跳过
// var foo = undefined 
console.log(foo)
foo = 20;

从下面的规定能够看出,function 的申明会比 var 申明的优先级更高一些.
看下上面局部例子

// demo01
function test() {console.log(a);
    console.log(foo());

    var a = 1;
    function foo() {return 2;}
}

test();

执行程序

function test() {function foo(){return 2}
    var a = undefined;
    console.log(a)
    console.log(foo())
    a = 1;
}
test();

在上述例子中, 从 test() 调用时, test 的执行上下文开始创立.

// 创立过程
testEC = {
    // 变量对象
    VO: {},
    // 作用域链
    scopeChain: {}}
// 本文只探讨变量对象 VO
VO = {argument: {...},
    foo: <foo 的援用地址 >,
    a: undefined
}

未进入执行阶段时, 变量对象中的属性都不能够被拜访. 然而进入执行阶段, 变量对象转为了流动对象, 外面的对象都能够拜访了, 而后开始进行执行阶段的操作

如果被问到变量对象和流动对象的区别, 其实他们都是一个对象, 只是出于执行上下文的不同生命周期内. 只有出于函数调用栈栈顶的执行上下文中的对象, 才会变成流动对象.

// 执行阶段
VO = {argument: {...},
    foo: <foo 的援用地址 >,
    a: 1,
    this: window
}

全局上下文的对象

以浏览器为例, 全局对象为 window
全局对象的变量对象就是 window 对象.this 也是指向 window

// 全局对象
windowEC = {
    VO: window,
    scopeChain: {},
    this: window
}

全局上下文的生命周期和程序的生命周期保持一致. 只有程序不进行运行, 比方关掉浏览器窗口, 全局上下文就会始终存在.

正文完
 0