美文网首页
再学js--变量对象

再学js--变量对象

作者: Territory_Cheng | 来源:发表于2020-04-15 11:44 被阅读0次

当JavaScript代码执行一段可执行的代码时,会创建对应的执行上下文,对于每个执行上下文的创建阶段,都有三个重要动作:

  1. 生成变量对象
  2. 建立作用域链
  3. 确定this的指向

变量对象

不同的执行上下文下的变量对象稍有不同,所以我们从全局上下文的变量对象和函数上下文的变量对象

全局上下文

先来了解一下全局对象:

全局对象是预定义的对象,作为JavaScript的全局函数和全局属性的占位符。通过使用全局对象,可以访问所有其他预定义的对象、函数和属性。

在顶层的JavaScript代码中,可以用关键字this引用全局对象。因为全局对象是作用域链的头,这意味着所有非限定性的变量和函数名都会作为该对象的属性来访问。

例如:当JavaScript代码应用parseInt()函数时,它引用的是全局对象parseInt属性。全局对象是作用域链的头,还意味着顶层JavaScript代码中声明的所有变量都将成为全局对象的属性。

全局对象的详细介绍:

1、可以通过this引用,在客户端JavaScript中,全局对象就是window对象

console.log(this)  // window

2、全局对象是由Object构造函数实例化的一个对象

console.log(this instanceof Object)  // true

3、预定了很多内置属性和函数

console.log(Math.random())  // 0.31526211617004263
console.log(this.Math.random())  // 0.31526211617004263

4、作为全局变量的宿主

var a = 1
console.log(this.a)  // 1

5、客户端JavaScript中,全局对象有window属性指向自身

var a = 1
console.log(window.a)
this.window.b = 2
console.log(window.b)

总结:全局上下文中的变量对象就是全局对象

函数上下文

在函数上下文中,我们用活动对象来表示变量对象

活动对象和变量对象其实是一个东西,只是变量对象是规范上的或者说是引擎实现上的,不可在JavaScript环境中访问,只有到当进入一个执行上下文中,这个执行上下文的变量对象才会被激活,所以才叫活动对象,而只有被激活的变量对象,也就是活动对象上的各种属性才能被访问。

活动对象是在进入函数上下文时刻被创建的,它通过函数的arguments属性初始化。arguments属性值是Arguments对象。

执行过程

执行上下文的代码会被分为两个阶段执行:分析和执行

  1. 进入执行上下文
  2. 代码执行

进入执行上下文

当进入执行上下文是,这时候还没有执行代码

变量对象的创建依次经历以下几个过程:

image-20200415112433729

1、函数的所有形参(如果是函数上下文):建立arguments对象。检查当前上下文中的参数,建立该对象下的属性与属性值。

(1)由名称和对应值组成的一个变量对象的属性被创建

(2)如没有实参,属性值设为undefined

2、函数声明:检查当前上下文的函数声明,也就是使用function关键字声明的函数。在变量对象中以函数名建立一个属性,属性值为指向该函数所在内存地址的引用。如果函数名的属性已经存在,那么该属性将会被新的引用所覆盖。

(1)由名称和对应值(函数对象(function-object))组成一个变量对象的属性被创建

(2)如果变量对象已经存在相同名称的属性,则完全替换这个属性

3、变量声明:检查当前上下文中的变量声明,每找到一个变量声明,就在变量对象中以变量名建立一个属性,属性值为undefined。如果该变量名的属性已经存在,为了防止同名的函数被修改为undefined,则会直接跳过,原属性值不会被修改。

(1)由名称和对应值(undefined)组成一个变量对象的属性被创建

(2)如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性

例如:

function foo(a) {
    var b = 2
    function c() {}
    var d = function(){}
    b = 3
}
foo(1)

在进入执行上下文的时候,变量对象(活动对象AO)是:

AO = {
    arguments: {
        0: 1,
        length: 1
    },
    a: 1,
    b: undefined,
    c: reference to function c(){},
    d: undefined
}

代码执行

在代码执行阶段,会顺序执行代码,根据代码,修改变量对象的值

上面的例子,在代码执行完后,这时候变量对象是:

AO = {
    arguments: {
        0: 1,
        length: 1
    },
    a: 1,
    b: 3,
    c: reference to function c(){},
    d: reference to FunctionExpression 'd'
}

总结下上述所说:

  1. 全局上下文的变量对象初始化是全局对象
  2. 函数上下文的变量对象初始化只包括Arguments对象
  3. 在进入执行上下文时会给变量对象添加形参、函数声明、变量声明等初始的属性值
  4. 在代码执行阶段,会再次修改变量对象的值

在进入执行上下文时,首先会处理函数声明,其实会处理变量声明,如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性。

相关文章

  • 再学js--变量对象

    当JavaScript代码执行一段可执行的代码时,会创建对应的执行上下文,对于每个执行上下文的创建阶段,都有三个重...

  • 再学JS--类数组对象与arguments

    类数组对象 所谓的类数组对象:拥有一个length属性和若干索引属性的对象 我们从读写、获取长度、遍历三个方面看看...

  • 再学JS--事件节流

    节流 节流:如果你持续触发事件,每隔一段时间,只执行一次事件 关于节流的实现,有两种主流的实现方式,一种是使用时间...

  • 再学JS--闭包

    MDN对闭包的定义: 闭包是指那些能够访问自由变量的函数 那什么是自由变量? 自由变量是指在函数中使用的,但既不是...

  • JS--对象

    JS 对象JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成。JavaScript用一个{.....

  • 再学JS--事件防抖

    在前端开发中会遇到一些频繁的事件触发,例如: window的resize、scroll mousedown、mou...

  • 再学JS--数组去重

    双层循环 最原始的数组去重方式 indexOf 排序后去重 排序去去重是将数组进行sort排序,相同的值就会被排在...

  • 再学js--作用域链

    什么是作用域链? 当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面的父级)执...

  • 再学JS--创建对象的多种方式以及优缺点

    工厂模式 缺点:对象无法识别,因为所有的实例都指向一个原型 构造函数模式 优点:实例可以识别为一个特定的类型 缺点...

  • js-- date对象

    Date 日期对象,总是遇到点小问题,做个总结来个了断 js 的date对象,基本把常用的功能都封装好了,基本不需...

网友评论

      本文标题:再学js--变量对象

      本文链接:https://www.haomeiwen.com/subject/bwaqvhtx.html