【问题标题】:Unexpected output of typeof in the example示例中 typeof 的意外输出
【发布时间】:2018-04-18 13:23:55
【问题描述】:

在下面的示例中,我试图将一个数字添加到函数的类型中,但输出似乎不同。

<html>
<head></head>
<body>

<script>

var k = 1;
if (1) {
   eval(function foo(){});
   k += typeof foo; 
}
console.log(k); 

</script>

</body>
</html>

预期输出:

1function

实际输出:

1undefined

有人可以解释为什么输出与预期不同吗?

注意:eval(function(){}) 的类型给出函数的结果。

【问题讨论】:

  • 函数表达式的名称仅在该函数表达式内可见。
  • @Xufox:你能解释一下吗?
  • 还有什么?真的没有什么要解释的了。 function foo(){} 是一个函数表达式(在 eval 参数内的表达式上下文中)。它的名字foo 在它之外是无法访问的。

标签: javascript typeof


【解决方案1】:

对于这个 sn-p,您实际上并不需要 evaltypeof (function foo(){})typeof foo 的结果相同。您不需要eval,因为eval(function foo(){})(function foo(){}) 是相同的,因为参数不是字符串。如果要使用eval,请改用字符串:

var x = function foo(){};

console.log(eval(x) === x); // true, because they’re identical

eval("function foo(){}");
// or
eval("var foo = function foo(){}");

console.log(foo); // function foo, because one of the above `eval`s declared it

function foo(){},这里是一个函数表达式。他们的名字只能在他们自己内部访问,而不是在外部访问。函数声明或分配的函数表达式可以在外部访问。

(function foo(){}); // (…) forces expression context. `foo` is not defined outside of it.

console.log(foo); // ReferenceError

var foo = function foo(){}; // Right-hand side is an expression, thus this is a function expression, but its result is assigned to a variable.

console.log(foo); // function foo

var bar = function foo(){}; // Same thing, but with a different variable.

console.log(bar); // function foo
console.log(foo); // ReferenceError, since the name `foo` still is not visible outside.

function foo(){} // Statement context, thus this is a function declaration

console.log(foo); // function foo

所以(function foo(){ console.log(foo); }) 会很好,如果函数被调用,不一定使用相同的名称。

最后,typeof 为未声明的变量返回 "undefined"

【讨论】:

    【解决方案2】:

    typeof foo 返回 undefined 因为它没有在那个范围内定义

    k +=undefined 被强制转换为字符串并导致:

    1个功能

    【讨论】:

    • 我知道。解释为什么不投射?
    • @Deadpool 你期望什么被铸造而不被铸造......?
    • function foo(){} 只是不可见,因为它是在 eval() 中声明的
    【解决方案3】:

    eval() 需要一个 string 作为参数。 所以你必须将 function foo() 括在引号内。

    var k = 1;
    
    if (1) {
      eval('function foo(){}');
      k += typeof foo; 
    }
    
    console.log(k);
    

    文档: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval

    【讨论】:

    • 在 javascript 控制台中尝试这段代码,你会得到想要的结果。
    【解决方案4】:

    据我所知,您所做的是为该函数命名,但您没有将其“绑定”到变量,因此该函数存在,但没有指向该函数的“指针”。 typeof 需要一个指向要评估的东西的“指针”,但您没有声明任何人,您只是为该函数命名。仅当您不打算直接执行该函数时,这对调试有用。

    直接传对象也可以:

    var k = 1;
    if (1) {
       k += typeof function foo(){}; //1function
    }
    console.log(k);
    

    【讨论】:

    • 请不要更改问题或代码。仅在此解释。
    • @Deadpool 我已经向你解释过了。在我不打算用它们的名字来称呼它们的上下文中为函数命名是我通常会做的事情,以便在调试时让事情变得更容易。
    • @Deadpool 是的,经过测试,它是eval 还是任何其他函数都没有关系。尝试自己声明另一个并执行相同的操作。您会发现情况相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多