我正在尝试理解CoffeeScript生成的这个JavaScript代码。
我习惯于将功能定义为:
function Animal(name) {...}
var Animal = function(name){...};
但CoffeeScript产生以下内容:
var Animal = (function() {
function Animal(name) {
this.name = name;
}
return Animal;
})();
问题:
奖金问题 这些是等价的吗?
//Methodology #1
function Animal(name) {...}
//Methodology #2
var Animal = function Animal(name) {...};
答案 0 :(得分:1)
定义像这样的动物功能有什么好处? 两种项目符号之一?
关于你的奖金问题:
http://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/
答案 1 :(得分:1)
在匿名函数中创建“命名”函数有什么作用?
<强>更新强>
这只是true for IE8 because of the JScript Bug,在现代(和理智)浏览器中使用命名函数表达式时,Animal未在上下文命名空间中注册。
它阻止函数声明在上下文中注册函数名称(可能是全局名称空间)。这意味着,如果你这样做:
var Tiger = function Animal() {};
Tiger
和Animal
都在全局命名空间中注册,而这个:
var Tiger = function() { function Animal() {}; return Animal; };
仅在全局命名空间中注册Animal
。
定义像这样的动物功能与两种项目符号之一有什么好处?
<强>更新强>
同样,如果适用于比IE8更现代的浏览器,则无效。在这些情况下,您可以使用命名函数表达式而无需担心上下文。
优点是,在保持上下文(同样可能是全局)命名空间的同时,您仍然可以为对象创建命名构造函数。这意味着:
var Tiger = function() {};
var t = new Tiger();
t.constructor // is an anonymous function() {}
的声明性低于
var Tiger = function() { function Animal() {}; return Animal };
var t = new Tiger();
t.constructor // is a function Animal()
Animal //=> is not defined
这会污染全局命名空间或上下文命名空间,可能不需要注册Animal
var Tiger = function Animal() {};
var t = new Tiger();
t.constructor // is a function Animal()
Animal //=> returns function Animal();
这些是等价的吗?
<强>更新强>
所有浏览器都适用。
没有。在第一个中,您通过名称Animal
声明一个函数,而在第二个中,您将一个名为Animal
的函数指定给名为Animal
的变量,这被称为命名函数表达式。在第一个中,查找通过函数名称工作,在第二个中,查找通过变量名称工作。这是因为function declarations can not overwrite function expressions:函数声明在脚本加载的上下文中加载,而表达式赋值在脚本执行时执行:
function a() {
var b = function() { return 3; };
return b();
function b() { return 9; }
}
a() //=> returns 3;
答案 2 :(得分:0)
“在匿名函数中创建”命名“函数有什么作用?”
它只是创建一个新函数,该函数是嵌套函数内变量作用域的本地函数。
“定义像这样的动物功能与两种项目符号之一有什么好处?”
鉴于显示的代码,没有特别的优势,但如果外部函数中有其他变量,那么内部函数可以引用它们提供对它们的受控访问(因为变量将无法从外部访问外部功能)。
这是可能的,因为JavaScript函数形成了所谓的闭包,这意味着即使从该变量范围中删除它们,它们也会带有它们的原始变量作用域。
“奖金问题这些是等效的吗?”
原始代码?是的,它们基本上是等价的。
主要是彼此。主要区别在于函数声明(方法1)是“悬挂的”,这意味着它们在其作用域的顶部可用,因此您可以在定义它们之前实际使用它们。
只有在评估表达式后,才能使用函数表达式。
请注意,所有函数都有名称,因此它们都会显示在调试控制台中。此外,所有函数在同一变量范围内结束。
答案 3 :(得分:0)
您熟悉OOP(面向对象的编程)吗?
因为您在这里看到的是尝试在JavaScript中定义对象,即使JavaScript中没有class
关键字。
如果您对Java(与JavaScript无关)知之甚少,那么这应该看起来很熟悉:
public class Animal { // creating a class
private String name; // declaring its attributes
public Animal(String name) { // declaring constructor
this.name = name; // assigning value to the attribute
}
}
您提供的JavaScript代码基本上是相同的,例如创建一个类(某种增强类型),它具有属性(分配给它的变量)和方法(分配给它的功能)。
所以这段代码
function Animal(name) {
this.name = name;
}
创建Animal
类。
事实上,在JavaScript中,实际上并没有 class 的概念,只有对象的概念。所以在这里你创建一个变量,然后你分配以下函数的结果:
var Animal = (function() {
// some code here
})
(); // note the parenthesis here that means the function is called
然后,定义constructor,并返回包含此函数的对象。
所以在执行结束时,var Animal
包含一个构造函数,因此任何对象都可以这样初始化:̀var myAnimal = new Animal('Panther');
。
希望有所帮助。