对象名称是一个函数名称?

Hai*_*ood 7 javascript

如果我们有

var randomname = {};
randomname.attribute = 'something';

function randomname(){
  alert(randomname.attribute);
}
randomname();
Run Code Online (Sandbox Code Playgroud)

javascript会抛出任何错误吗?


更新
所以,我们知道我们不能让一个对象与一个函数同名.

为什么是这样?

javascript是否应该通过您调用它的方式告诉您的内容?

CMS*_*CMS 19

它应该给你一个TypeError例外 - 试图调用一个对象 - 在Firebug的控制台中观察到的行为是不正确的......

FunctionDeclaration将它们提升到其封闭范围的顶部,您的代码实际上按以下顺序执行:

// FunctionDeclaration is hoisted
function randomname(){
  alert(randomname.attribute);
}

// the var has no observable effect, because
// the randonmane identifier is already defined
randomname = {};
randomname.attribute = 'something';

randomname(); // TypeError, randomname is not callable.
Run Code Online (Sandbox Code Playgroud)

当进入执行上下文时,变量实例化过程(也就是ES5中的声明绑定实例化)定义了激活对象上的属性(AO,这是一个不可到达的对象,它在本地保存变量,函数声明和函数参数的标识符.范围)按以下顺序:

  1. FormalParameterList标识符(用于功能代码)
  2. FunctionDeclaration 身份标识
  3. VariableDeclaration 身份标识

A VariableDeclaration不会覆盖标识符已经在AO中定义(例如,通过前两个步骤之一),但是赋值将在运行时完成.

例如:

(function (foo) {
  var foo; // doesn't affect the existing `foo` identifier
  return typeof foo;
  function foo () {}
})('string'); // yields "function"
Run Code Online (Sandbox Code Playgroud)

但是,如果进行了赋值,则将替换标识符的值,例如:

(function (foo) {
  var foo = {};
  return typeof foo;
  function foo () {}
})('string'); // yields "object"!!
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,当调用函数时, - 但在代码执行之前 - 在foo激活对象(也称为变量对象)上设置标识符.

首先为它分配形式参数的值'string',值,然后FunctionDeclaration检查函数体上的所有函数,foo找到一个名为的函数,然后foo标识符将指向该函数.

之后,检查所有变量声明,我们有一个带有标识符的变量声明foo,但是在这个时间内它的值被认为是 - 该函数尚未执行 - .

此时,该函数已准备好执行,其词法和可变环境已设置.

将在函数中执行的第一件事是赋值foo = {};,它取代了我们之前使用的函数的引用.

为什么它在其他浏览器和Firefox上表现不同?

因为:

  1. 在评估代码之前,Firebug的控制台会包装您的代码.
  2. Mozilla实现定义了一个Function语句

由于Firebug通过在with语句中包装来评估代码,因此这将导致FunctionDeclaration语句上下文中评估-a Mozilla的函数语句.

要显示Function语句在Mozilla实现上的行为,请考虑以下示例:

if (true) {
  function foo () { return 'true!';}
} else {
  function foo () { return 'false??!';}
}

foo();
Run Code Online (Sandbox Code Playgroud)

在Mozilla中你会得到'true!',而在其他实现中你会得到'false??!'- 甚至在IE-上.

这是因为函数定义是在运行时,在Statement上下文中(在真正的分支中if),而在其他实现中,函数声明是在分析时计算的.

上面的例子实际上应该SyntaxError在任何实现上产生异常,但是它们中的任何一个都不会发生......

FunctionDeclaration应该只允许在全局代码中或直接在函数的FunctionBody中使用A.

一个很多 交替使用条款函数声明和函数的声明,但是这是完全错误的,ECMAScript中没有定义函数语句,是一个非标准的功能.

该规范简要说明了这个问题:

注意:已知几种广泛使用的ECMAScript实现支持将FunctionDeclaration用作Statement.然而,在应用于此类FunctionDeclarations的语义中的实现之间存在显着且不可调和的变化.由于这些不可调和的差异,使用FunctionDeclaration作为Statement会导致代码在实现中无法可靠地移植.建议ECMAScript实现不允许使用FunctionDeclaration,或在遇到此类用法时发出警告.ECMAScript的未来版本可以定义用于在Statement上下文中声明函数的替代可移植方法.

尝试在全局执行上下文中运行代码 - 在一个简单的<script>元素中 - 你会看到它在Firefox上崩溃:

<script type="text/javascript"> 
  var randomname = {};
  randomname.attribute = 'something';

  function randomname(){
    alert(randomname.attribute);
  }
  randomname();
</script>
Run Code Online (Sandbox Code Playgroud)

你可以在这里找到上面的例子,确保打开Firebug的控制台,你会看到你在其他浏览器上遇到的同样的错误.


Anu*_*pta 5

函数实际上也是 JavaScript 中的一个对象(第一类对象)。

所以你可以做这样的事情。

var human = function(){
  alert("Hi");
};

// which is perfectly normal 

//but then

human.name="Anubhav";
Run Code Online (Sandbox Code Playgroud)

然后你可以执行以下操作:

human();//works
alert(human.name);//works
Run Code Online (Sandbox Code Playgroud)