对象名称是一个函数名称? [英] object name same a function name?

查看:133
本文介绍了对象名称是一个函数名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我们有

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

function randomname(){
  alert(randomname.attribute);
}
randomname();

javascript会抛出任何错误吗?

Will javascript throw any errors?


更新

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


Update
So, We know that we cannot have a object have the same name as a function.

为什么会这样?

javascript是否应该通过你的方式告诉你什么?

Should javascript not be able to tell what you are after by the way you call it?

推荐答案

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

It should give you a TypeError exception -for trying to invoke an object-, the behavior observed in the Firebug's console is not right...

FunctionDeclaration hoisted 到顶部对于它们的封闭范围,您的代码实际上按此顺序执行:

FunctionDeclaration's are hoisted to the top of their enclosing scope, your code is actually executing in this order:

// 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.

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

When entering to an execution context, the Variable Instantiation process (aka Declaration Binding Instantiation in ES5) defines the properties on the Activation Object (AO, this is a non-reachable object that holds identifiers of variables, functions declarations and function arguments in the local scope) in the following order:


  1. FormalParameterList 标识符(功能代码

  2. FunctionDeclaration 标识符

  3. VariableDeclaration 标识符

  1. FormalParameterList identifiers (for Function Code)
  2. FunctionDeclaration identifiers
  3. VariableDeclaration identifiers

A VariableDeclaration 不会覆盖我已经在AO中定义了标识符(例如通过前两个步骤中的一个),但作业将在运行时完成。

A VariableDeclaration will not overwrite an identifier has been already defined in the AO (e.g. by one of the first two steps), but the assignment will do it at run time.

例如:

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

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

But if an assignment is made, the value of the identifier will be replaced, for example:

(function (foo) {
  var foo = {};
  return typeof foo;
  function foo () {}
})('string'); // yields "object"!!

在上面的例子中,当调用函数时, - 但在代码执行之前 - foo 在激活对象(又名变量对象)上设置标识符。

In the above example, when the function is invoked, -but before the code execution- the foo identifier is set up on the Activation Object (aka Variable Object).

首先,它被赋予正式的值参数,值'string',然后检查函数体上的所有 FunctionDeclaration ,一个名为<的函数找到code> foo ,然后 foo 标识符将指向该函数。

First it gets assigned the value of the formal parameter, the value 'string', then all FunctionDeclaration's on the Function Body are examined, a function named foo is found, then the foo identifier will point to that function.

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

After that, all Variable Declarations are examined, we have one with the identifier foo, but its value is respected in this time -remember that the function hasn't been executed-.

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

At this point, the function is ready to be executed, its lexical and variable environment is setup.

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

The first thing that will be executed in the function, is the assignment foo = {};, which replaces the reference to the function that we had before.

为什么它在其他浏览器和Firefox上的行为有所不同?

因为:


  1. Firebug的控制台在评估之前包装你的代码

  2. Mozilla实现定义了一个功能说明

  1. The Firebug's console wraps your code before evaluating it.
  2. The Mozilla implementations define a Function Statement

由于Firebug通过在中包含语句进行包装来评估代码,因此会导致 FunctionDeclaration 被评估在语句上下文 -a Mozilla的函数语句 - 。

Since Firebug evaluates code by wrapping inside a with statement, this causes the FunctionDeclaration to be evaluated in statement context -a Mozilla's Function Statement-.

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

To show the behavior of the Function statement on Mozilla implementations, consider the following example:

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

foo();

在Mozilla中,您将获得'true!',而在其他实现中,你将得到'false ??!' - 即使在IE上 - 。

In Mozilla you will get 'true!', while in other implementations you will get 'false??!' - even on IE-.

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

That's because the function definition was made at run-time, in Statement context (in side the true branch of the if), while in other implementations, the function declarations are evaluated at parse time.

以上示例实际上应该在任何实现上产生 SyntaxError 异常,但是这不会发生在任何一个......

The above example should actually produce a SyntaxError exception on any implementation, but that doesn't happen on any of them...

在全球范围内应该只允许 FunctionDeclaration 代码或直接在函数的FunctionBody中。

A FunctionDeclaration should be allowed only, in global code or directly in the FunctionBody of a function.

A 很多 互换使用条款函数声明和函数声明但完全错误,ECMAScript没有定义函数声明,是非标准功能

A lot of people use interchangeably the terms Function Declaration and Function Statement but that's totally wrong, ECMAScript doesn't define a Function Statement, is a non-standard feature.

该规范有一个简短的 note


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

NOTE: Several widely used implementations of ECMAScript are known to support the use of FunctionDeclaration as a Statement. However there are significant and irreconcilable variations among the implementations in the semantics applied to such FunctionDeclarations. Because of these irreconcilable difference, the use of a FunctionDeclaration as a Statement results in code that is not reliably portable among implementations. It is recommended that ECMAScript implementations either disallow this usage of FunctionDeclaration or issue a warning when such a usage is encountered. Future editions of ECMAScript may define alternative portable means for declaring functions in a Statement context.

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

Try to run your code in the global execution context -in a simple <script> element- and you will see it crash also on Firefox:

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

  function randomname(){
    alert(randomname.attribute);
  }
  randomname();
</script>

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

You can find the above example here, make sure to open the Firebug's console and you'll see the same error you get on other browsers.

这篇关于对象名称是一个函数名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆