nunnly / everycode

Javascript 每日一练
116 stars 26 forks source link

2015年3月6日 作用域 #42

Open nunnly opened 9 years ago

nunnly commented 9 years ago
function a(x,y){
    y = function(){x=2;};
    return function(){
        var x = 3;
        y();
        console.log(x);
    }.apply(this,arguments);
}
a();
//求最后的输出
//题目来自
//https://gist.github.com/ruanyf/cae49b92b0bd43c4d57d
XadillaX commented 9 years ago

个明显是 3 啊,怎么会是难度 5,有什么解释的,var 都写在上面了还有什么好解释的。

think2011 commented 9 years ago

求解释,求解释! @XadillaX

think2011 commented 9 years ago
function foo() {
    console.log( a ); // 2
}

function bar() {
    var a = 3;
    foo();
}

var a = 2;

bar(); //2

看了这个就明白了。

XadillaX commented 9 years ago

foo 和 bar 不在一个作用域好么,foo 能找到的 a 是最外层的,又找不到 bar 里面的。@think2011

明明是很简单的问题,为什么一定要搞复杂了 -。 -

think2011 commented 9 years ago
function a(x, y) {
    y = function() {
        x = 2;
    };
    return function() {
        x = 3;
        y();
        console.log(x);
    }.apply(this, arguments);
}
a(); // 2

@XadillaX 因为作为菜鸟容易把事情复杂化..

VaJoy commented 9 years ago

-。- 好简单的都懒得回答了,话说大神@XadillaX 终于舍得回来了

XadillaX commented 9 years ago

@think2011

x 始终都是传进来的——一开始是 undefined,然后 x = 3,然后在 y 里面被等于 2,最后输出就是 2 了。

XadillaX commented 9 years ago

@VaJoy

最近忙成狗了 -。 -

看到前两天传得比较火的阮老师的问题,实际上有点小时候做应用题的混淆法,根本就是那么点东西,加了一堆没用的混淆条件。

VaJoy commented 9 years ago

@XadillaX 辛苦啦,有时间去做大保健,别累坏了 →。→

think2011 commented 9 years ago

@XadillaX 恩。明白了。

XadillaX commented 9 years ago

@think2011 就是从本作用域下冒泡往上找,找到的第一个就是了。

VaJoy commented 9 years ago

其实这题稍微改一下可以继续混一点变量提升的概念,23333

function a(x,y){
    y = function(){x=2;};
    return function(){
        y();
        console.log(x);
        var x = 3;     //move it here
    }.apply(this,arguments);
}
a();
XadillaX commented 9 years ago

@VaJoy 这个倒是比之前的有意思些,其实主要是变量声明会被提前。

XadillaX commented 9 years ago
(function() { x = 2; console.log(x); var x = 1; console.log(x); })();

var 写前面后面都没关系,只要有就会在一开始被声明。

上面的结果输出的就是 2 1。

VaJoy commented 9 years ago

@XadillaX 但是我修改后的那段代码运行后是undefined...

XadillaX commented 9 years ago

@VaJoy 你那段代码实际上是:

function a(x,y){
    y = function(){x=2;};
    return function(){
        var x;
        y();
        console.log(x);
        x = 3;     //move it here
    }.apply(this,arguments);
}
a();

这一点在我

(function() { x = 2; console.log(x); var x = 1; console.log(x); })();

这段代码里面就有体现。

VaJoy commented 9 years ago

@XadillaX 嗯嗯是滴,提前声明了但没提前赋值

VaJoy commented 9 years ago

玩一玩ES6吧,这算不算bug呢?@XadillaX

"use strict";
function a(x,y){
    y = function(){x=2;};
    return function(){
        y();
        console.log(x);
        let x = 3;     //use let
    }.apply(this,arguments);
}
a();

iojs运行后报错说x没定义过不能执行console.log(x), 但注释掉 let x = 3 后就成功打印“2”

XadillaX commented 9 years ago

@VaJoy 对 ES6 没了解。