Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第 41 题:考察作用域的一道代码题 #61

Open
gto999 opened this issue Mar 26, 2019 · 32 comments
Open

第 41 题:考察作用域的一道代码题 #61

gto999 opened this issue Mar 26, 2019 · 32 comments
Labels

Comments

@gto999
Copy link

gto999 commented Mar 26, 2019

分别为undefined 10 20,原因是作用域问题,在内部声名var a = 20;相当于先声明var a;然后再执行赋值操作,这是在IIFE内形成的独立作用域,如果把var a=20注释掉,那么a只有在外部有声明,显示的就是外部的A变量的值了。结果A会是10 5 5

@HankXu
Copy link

HankXu commented Mar 26, 2019

依次输出:undefined -> 10 -> 20

解析:

在立即执行函数中,var a = 20; 语句定义了一个局部变量 a,由于js的变量声明提升机制,局部变量a的声明会被提升至立即执行函数的函数体最上方,且由于这样的提升并不包括赋值,因此第一条打印语句会打印undefined,最后一条语句会打印20

由于变量声明提升,a = 5; 这条语句执行时,局部的变量a已经声明,因此它产生的效果是对局部的变量a赋值,此时window.a 依旧是最开始赋值的10

@dingLeiOnly
Copy link

undefined,10,20。用var生命的变量存在变量提升,a在作用域里提前声明,但是没有定义,第一个输出undefined,a = 5,定义a的值,局部作用域修改为5,但是window全局对象下的a变量没有改变,输出10,最后var a = 20,给局部作用域赋值,输出20.

@wokerH
Copy link

wokerH commented Mar 26, 2019

执行解析步骤:
var a = undefined;
a = 10;
(function () {
// 变量提升(预解析)
var a = undefined;
console.log(a); // 输出undefined
a = 5;
console.log(window.a); // 找window(全局)对象的a, 输出10
a = 20;
console.log(a); // 输出20
})()

@gorphensu
Copy link

var a = 10;
(function () {
	console.log(a)
	a = 5
	console.log(window.a)
	var a = 20
	console.log(a)
})()

// undefined
// 10
// 20

执行代码步骤

  1. 变量提升
  2. 形参赋值

@dorseysen
Copy link

var a = 10;
(function () {
    console.log(a); 
    a = 5;
    console.log(window.a);
    var a = 20;
    console.log(a); 
})();
//  ===
var a = 10;
(function () {
    var a;
    console.log(a); // undefined
    a = 5;
    console.log(window.a);  //  此时是window.a => 10
    a = 20;
    console.log(a); //  20
});

@LFmadongsheng
Copy link

LFmadongsheng commented Mar 26, 2019

var a = 10;
(function () {
console.log(a) //undefined 变量提升 这之前 var a
a = 5 //全局变量
console.log(window.a) // 5 这里我有问题 10
var a = 20; // a =20
console.log(a) //20
})()

@zeroone001
Copy link

1,变量提升;2,window.a 为 10

@Yana5417
Copy link

Yana5417 commented Mar 27, 2019

undefined 10 20
代码执行过程:
var a; // undefined
a = 10;
(function () {
var a; // undefined
console.log(a)
a = 5
console.log(window.a)
a = 20;
console.log(a)
})()

首先这段代码有两个作用域,window和function。在function作用域内,同样存在变量提升,当第一次console时,这时变量a只定义未赋值,所以打印undefined。在window作用域中,a的值为10,所以window.a的值为10。最后一次打印之前,a被赋值为20,所以打印结果为20。

问题:
其实在这里,我不是很理解window和function这两个作用域之间的关系,希望能看到详细的解说~~~

@xineur
Copy link

xineur commented Mar 27, 2019

undefined 10 20
代码执行过程:
var a; // undefined
a = 10;
(function () {
var a; // undefined
console.log(a)
a = 5
console.log(window.a)
a = 20;
console.log(a)
})()

首先这段代码有两个作用域,窗口和功能。在功能作用域内,同样存在变量提升,当第一次控制台时,这时变量一个只定义未赋值,所以打印未定义。在窗口作用域中,一个的值为10,所以window.a的值为10最后一次打印之前,一个被赋值为20,所以打印结果为20。

问题:
其实在这里,我不是很理解窗口和功能这两个作用域之间的关系,希望能看到详细的解说~~~

(function(){
  var window = this
  var a = '123'
  (function(){
    var a = '234'
    console.log(window.a)
    console.log(this.a)
  }())
}())

如果看的懂的话我就不解释了,如果还看不懂的话我在解释

@Sobcat
Copy link

Sobcat commented Mar 28, 2019

懂的

@Yana5417
Copy link

undefined 10 20
代码执行过程:
var a; // undefined
a = 10;
(function () {
var a; // undefined
console.log(a)
a = 5
console.log(window.a)
a = 20;
console.log(a)
})()
首先这段代码有两个作用域,窗口和功能。在功能作用域内,同样存在变量提升,当第一次控制台时,这时变量一个只定义未赋值,所以打印未定义。在窗口作用域中,一个的值为10,所以window.a的值为10最后一次打印之前,一个被赋值为20,所以打印结果为20。
问题:
其实在这里,我不是很理解窗口和功能这两个作用域之间的关系,希望能看到详细的解说~~~

(function(){
  var window = this
  var a = '123'
  (function(){
    var a = '234'
    console.log(window.a)
    console.log(this.a)
  }())
}())

如果看的懂的话我就不解释了,如果还看不懂的话我在解释

运行了一下,打印结果报错:Uncaught TypeError: "123" is not a function。

还是没有很理解,求详细解释~

@superleexpert
Copy link

undefined undefined 20, try it!

@aeolusheath
Copy link

(function(){
  b = 5
})()

这一段是否可以理解为

var b;
(function(){
 b =5
})

因为没有加var 所以为global作用域声明提升,而不是函数作用域声明提升。

@xineur
Copy link

xineur commented Mar 29, 2019

(function(){ // ①
  var window = this
  var a = '123'
  (function(){ // ②
    var a = '234'
    console.log(window.a)
    console.log(this.a)
  }())
}())

@Yana5417 可能并没有说清楚吧。

作用域

我们都知道window是一个全局对象,在我的例子中①是假象出来的,为的是让你看到window的作用域,及全局作用域,然后下来是②,它是一个函数作用域

关系

1、函数作用域可以访问全局作用域

var a = 123;
(function(){
  console.log(a) // 123
  a = 456
}());
console.log(a) // 456

步骤解析:

var a = undefined;
a = 123;
(function(){
  console.log(a) // 函数作用域寻找变量a
  console.log(window.a) // 结果没找到,那么他会向上寻找,直到找到该变量,若最后没有找到,那么就会报该变量未定义
  window.a = 456 // 因为找到的是window的变量`a`所以此处会修改window的变量`a`
}());
console.log(a) // 456
在这里实际还涉及到隐式声明,所以我在下面会说明

2、全局作用域中无法访问局部作用域的变量

(function(){
  var a = 456
}());
console.log(a) // Error: a is not defined

步骤解析:

(function(){
  var a = 456
}());
console.log(a) // window已经是全局作用域了,在这里并没有发现变量`a`所以不会继续向上寻找,直接输出 a is not defined

3、当局部作用域中进行隐式声明时,默认会在全局作用域中声明该变量

(function(){
  a = 456
}());
console.log(a) // 456
// 局部变量捡到十块钱,然后找不到失主,然后全局变量说,那算了,找不到我就先拿着把。然后局部变量说,好吧,那就给你吧!

最后我们开始看你解析完后这道题

var window = this; // 再次声明此处可忽略,只是为了让你看到window是全局this的别名
var a; // undefined
a = 10; 
(function () {
var a; // undefined
console.log(a) //  此处因为是显式声明所以你在函数作用域中访问到的,一定是他内部声明变量`a`
a = 5 // 显式声明的变量`a` = 5
console.log(window.a) // 直接找的是`window`的`a`则不在函数作用域中寻找 有趣的是,`function`中不通过`call`或`apply`修改`this`指针,此处输出 `this.a` 的效果是一致的
a = 20;// 显式声明的变量`a` 由 5 变成 20
console.log(a)
})()

这次应该可以看明白了吧!

@Yana5417
Copy link

Yana5417 commented Apr 3, 2019

明白了,非常感谢🙏

@yygmind yygmind changed the title 第41题 第41题 考察作用域代码题 Apr 26, 2019
@yygmind yygmind changed the title 第41题 考察作用域代码题 第41题 考察作用域的一道代码题 Apr 26, 2019
@yygmind yygmind changed the title 第41题 考察作用域的一道代码题 第 41 题 考察作用域的一道代码题 Apr 26, 2019
@songjunchao-cn
Copy link

分别为undefined 10 20,原因是作用域问题,在内部声名var a = 20;相当于先声明var a;然后再执行赋值操作,这是在IIFE内形成的独立作用域,如果把var a=20注释掉,那么a只有在外部有声明,显示的就是外部的A变量的值了。结果A会是10 5 5

为什么window.a的值不是10而是5了

@songjunchao-cn
Copy link

var a = 10;
(function () {
console.log(a) //undefined 变量提升 这之前 var a
a = 5 //全局变量
console.log(window.a) // 5 这里我有问题 10
var a = 20; // a =20
console.log(a) //20
})()

a=5是局部变量吧

@songjunchao-cn
Copy link

songjunchao-cn commented May 13, 2019

分别为undefined 10 20,原因是作用域问题,在内部声名var a = 20;相当于先声明var a;然后再执行赋值操作,这是在IIFE内形成的独立作用域,如果把var a=20注释掉,那么a只有在外部有声明,显示的就是外部的A变量的值了。结果A会是10 5 5

为什么window.a的值不是10而是5了

明白了a快速执行函数内没有声明,所以赋值到全局变量了

@chaijinsong
Copy link

var a = 10;
(function () {
    console.log(a)
    a = 5
    console.log(window.a)
    var a = 20;
    console.log(a)
})();
// 前提浏览器中执行,node中window.a会报错 window is not defined

// undefined  函数中的a,先会找函数中是否存在该变量,因为存在声明前置,所以这里的第一个a为undefined
// 10  指定了是window上的a变量,说明是函数外部的a
// 20  此时函数内的a已经赋值为20了,所以输出为20。可以转为如下代码

window.a = 10;
(function() {
  var a;
  console.log(a);
  a = 5;
  console.log(window.a);
  a = 20;
  console.log(a);
})();

@ragnar-document
Copy link

(function(){
  a = 456
}());
console.log(a) // 456

a 不是全局变量吗??
局部变量你应该是使用let声明
同样使用var也能在外面打印
因为var存在变量提升什么的所以出了let
如果不声明变量那么他就会作为全局变量
个人理解~

@glwz2017
Copy link

undefined undefined 20 中间的自定义属性,未赋值 (个人理解 )

@zhishaofei3
Copy link

window.a是个坑

@tianjiachengde
Copy link

在js使用了模块导入的方式下,输出的结果是undefined,undefined,20。有大佬知道是为什么吗

@yujie0716006
Copy link

我感觉这得非情况讨论吧:
1.如果在浏览器中执行这个就是undefined, 10, 20
2.如果直接在编辑器直接执行这段js,window.a就会报错。因为在node.js的环境中没有dom,和dom操作。

@lvzhiyi
Copy link

lvzhiyi commented Aug 19, 2019

undefined 10 20
涉及知识点有:
1、自执行函数会形成块级作用域
2、作用域链是自内向外查找
3、作用域形成与js引擎编译阶段,并不会做负值操作
4、var声明的全局变量会赋值给window对象

第一 undefined

因为函数内部声明过a, 导致变量提升,但不负值,返回undefined。如果内部没有声明a 则作用域继续向外查找,找到a= 10:

var a = 10;
(function () {
    console.log(a) // 10
})()

第二 10

参照第四点直接读取全局变量 a=10

第三 20

常规作用域查找,a=20

@Ray0401
Copy link

Ray0401 commented Sep 11, 2019

在js使用了模块导入的方式下,输出的结果是undefined,undefined,20。有大佬知道是为什么吗

是因为第一句var a=10;中的a 不是挂载在window上的 ,所以立即执行函数中的 window.a的值是 undefined

@aeolusheath
Copy link

 var a = 10;
    (function () {
        console.log(a) // undefined
        a = 5
        console.log(window.a) // 10
        var a = 20; 
        console.log(a) // 20
    })()

@yygmind yygmind changed the title 第 41 题 考察作用域的一道代码题 第 41 题:考察作用域的一道代码题 Dec 16, 2019
@yygmind
Copy link
Contributor

yygmind commented Dec 16, 2019

var a = 10;
(function () {
    console.log(a)
    a = 5
    console.log(window.a)
    var a = 20;
    console.log(a)
})()

@soraly
Copy link

soraly commented Jun 22, 2020

var a = 10;
(function () {
    console.log(a)
    a = 5
    console.log(window.a)
    var a = 20;
    console.log(a)
})()
  1. 由于var会进行变量提升,但不赋值,返回undefined,类似于 var a = undefined,所以第一个会输出 undefined;
  2. a = 5,只是把函数内的局部变量a赋值成了5,所以输出window.a的时候还是10;
  3. 局部变量变成20,所以输出了20;

@alan1111
Copy link

alan1111 commented Jun 25, 2020

undefined 10 20
代码执行过程:
var a; // undefined
a = 10;
(function () {
var a; // undefined
console.log(a)
a = 5
console.log(window.a)
a = 20;
console.log(a)
})()
首先这段代码有两个作用域,窗口和功能。在功能作用域内,同样存在变量提升,当第一次控制台时,这时变量一个只定义未赋值,所以打印未定义。在窗口作用域中,一个的值为10,所以window.a的值为10最后一次打印之前,一个被赋值为20,所以打印结果为20。
问题:
其实在这里,我不是很理解窗口和功能这两个作用域之间的关系,希望能看到详细的解说~~~

(function(){
  var window = this
  var a = '123'
  (function(){
    var a = '234'
    console.log(window.a)
    console.log(this.a)
  }())
}())

如果看的懂的话我就不解释了,如果还看不懂的话我在解释

运行了一下,打印结果报错:Uncaught TypeError: "123" is not a function。

还是没有很理解,求详细解释~

如果在浏览器console执行的话, 第三行末尾没有分号"; " 认为执行的是 var a = '123'(自执行函数), 把'123' 当function了,所以会报错.

@decSunshineHe
Copy link

这里关键点是变量提升,代码等价于

    var a = 10;
    (function() {
        var a;  //变量声明会提到作用域最前面
        console.log(a)  //undefined
        a = 5
        console.log(window.a)  //全局变量a-10
        a = 20;
        console.log(a)         //作用域内a-20
    })()

@fkcode2046
Copy link

这样的提升并不包括赋值

借用楼上解释:如果把var a=20注释掉,那么a只有在外部有声明,显示的就是外部的A变量的值了。结果A会是10 5 5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests