首页 > 这段js代码的执行结果如何解释?

这段js代码的执行结果如何解释?

var arr = []
var f = function(){
  console.log('f执行');
  console.log(arguments)
}

var s = function(){
  console.log('s执行');
  arr = [1,2,3]
  return 'xxx'
}

f('1', arr, s(), arr)
//以下是执行结果
//s执行
//f执行
//["1", Array[0], "xxx", Array[3]]

其实题主想了解的应该是打印结果的执行顺序吧。这个问题其实和JavaScript中的变量解析顺序有关。之前写了篇和这个相关的博客,现在搬过来。

执行环境(或称“环境”)是 JavaScript 中非常重要的概念。执行环境决定了变量或函数有权访问其它数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。这个对象是我们的代码无法访问到的,供解析器后台使用。

当执行环境为函数时,变量对象为“活动对象”。活动对象在进入执行环境时被创建,最开始只包含 arguments 对象这一个变量。

变量对象初始化:

活动对象 = {
    arguments:  //是个对象,包含length等属性
};

同样为了方便,活动对象表示为 AO。

处理代码一般为两步:进入执行环境、执行代码。

在进入执行环境时,代码执行前,变量对象已经包含下列属性:(变量解析也是按照这个顺序的)

  1. 执行环境中的 this 和 arguments。(全局环境中无 arguments 对象)

  2. 函数的形参 - 特指函数环境,全局环境无形参

  3. 函数声明(不包括函数表达式) - 函数名+对应值(函数对象)构成,覆盖同名变量属性

  4. var声明的变量 - 变量名+对应值(undefined)构成,不影响已声明的同名形参或函数声明

在进入f()时,活动对象表现如下:

AO(f) = {
    arguments[0]: '1',
    arguments[1]: arr,    //undefined
    arguments[2]: s(),    //undefined
    arguments[3]: arr    //undefined
}

其实这个时候,除了arguments[0],其余几个参数值都是 undefined。

然后是处理代码的第二步执行代码。

按照顺序求参数的值:

AO(f) = {
    arguments[0]: '1',
    arguments[1]: Array[0],    
    arguments[2]: 'xxx',    
    arguments[3]: Array[3]   
}

然后再执行函数体,就会得出你看到的内容了。

其实想更加直观地看到 arr 的内容,可以这样调用:

f('1', arr.join(''), s(), arr.join(''));

结果是:

["1", "", "xxx", "123"]

f('1', arr, s(), arr)

f以里面4个为参数,所以要把参数一一计算出具体的,'1'值是'1',arr是arr,s()是执行函数返回的结果'xxx',这里修改了arr的引用,所以arr这次返回了一个新的数组对象
参数都计算出来了,然后就执行f函数体了。

另外需要注意下面这种情况:

var arr = []
var f = function(){
  console.log('f执行');
  console.log(arguments)
}

var s = function(arr){
  console.log('s执行');
  arr = [1,2,3]
  return 'xxx'
}

f('1', arr, s(), arr)

arr = [1,2,3]此时arr的引用也变掉了。
如果改成arr[0]=1,则打印出来的结果则为:["1", Array[1], "xxx", Array[1]]

【热门文章】
【热门文章】