javascript - js在函数中 创建变量 和 引用变量 实质上的执行过程是怎么样的?
PHP中文网
PHP中文网 2017-04-11 12:02:31
0
2
672

刚开始学习js 对于Js的执行过程有很大的疑虑
创建和引用 是否 是完全不同的概念 下面贴出了自己的实验代码和猜测 想请问各位 自己的猜测是否正确 如果是错的 那么到底是如何的一个过程呢?
全局变量是不是一块公共的区域 里面有着一块块的变量?


var num = 123;
function f1() {
    console.log( num );
}
function f2() {
    num = 456;
    f1();
}
f2();
console.log(num);

//首先执行f2 看见一个全局变量num 他得去全局变量的区域内找找有没有 有就覆盖修改 没有就创建 找到了 在外面 虽然他用var 但并没有fn包含他 所以也是全局变量 修改他 之后f1输出为456




var num = 123;
function f1() {
    console.log( num+"f1" );
}
function f2() {
    var num = 456;
    f1(num);
    console.log(num+"f2");
}
f2();

//猜测 运行到F2的时候 因为声明的是局部变量 首先在自己的函数域内查找 num 没找到 那么就创建在函数域内创建一个num 为 456


//所以二者的差别就在于 一个去外面找了 找到了修改他  而另外一个呢 没有去外面找自己创建了一个

//在创建的情况下 他会在根据变量的类型 在公共全局变量里寻找是否有已经定义的变量 有>修改 无>创建
// 如果是局部变量 在自己的函数域内去创建 or 修改

//但是变量的引用不一样 如果找到了>使用他 没找到>通过函数链 去上一级寻找

//所以在引用和创建的时候 他的行为是不同的
PHP中文网
PHP中文网

认证高级PHP讲师

reply all(2)
阿神
  1. 变量的查找分为LHS和RHS,当需要一个变量存储东西时使用的是LHS,当需要一个具体的值时使用的是RHS
    例如:num = 123,对num就是进行LHS查找,console.log(num),对num使用的是RHS查找

  2. 上面的所有的查找都是沿着作用域链从上往下查找,在当前作用域没有找到时,会到上层作用域查找。

var num = 123;
function f1() {
    console.log( num );
}
function f2() {
    num = 456;
    f1();
}
f2();
console.log(num);

  1. 变量提升:声明了num,f1,f2

  2. 初始化 num = 123

  3. 执行f2:创建f2的作用域链,沿作用域链查找num,在f2的作用域中没有找到,去外部作用域查找,找到了,执行num = 456

  4. 运行f1:查找f1函数,在f2的作用域中没有,到外部作用域中有,执行。在f1中需要RHS查找num,同样在全局作用域找到的

  5. 运行最后一行的console.log(num)


而你的第二个,就是在函数作用域中找到了num

Ty80

先说第一段代码,两点
执行f2不是看到一个全局变量num,而是发现执行语句是对一个变量值的修改,然后解析器通过作用域链从当前开始向上寻找这个变量,所以num不是全局变量,而是父作用域的变量,全局变量是个相对的说法,即使在页面里直接var也只不过是window下面一个属性而已。
通过变量引用修改变量的值的时候,有就覆盖只在使用varlet创建的变量才可以,const是不可以修改的。
第二段代码
运行到f2的时候 既然使用var声明变量,既然是声明,为什么要寻找?当然直接创建了。
在创建的情况下,js不会根据变量类型去寻找,javascript是弱类型语言,变量的类型可以随时更改,所以创建跟你变量类型无关,也不会去寻找是否有相同变量,只是创建而已,如果已经有了这个变量,会忽略var关键字,只做赋值操作。但是!这其实是错误的代码,只是js并没有给你错误提示,这个在你是使用ES6的时候就能发现,对一个已有的变量重新创建,编译器会给你报错的。
至于你说的引用和创建的行为不同,我不太明白你是如何理解的,其实这两者都是在内存开辟一片区域存储值,再做一个指针到这个内存区域,也就是引用,只不是对变量重新赋值的时候有一个对变量的查找过程。

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template