在下面的示例中,为什么'z'的声明会导致语法错误?
(function(){
function x(){return 'this is x'};
y = function(){return 'this is y'};
//z : function(){return 'this is z'};
alert(x());
alert(y());
//alert(z());
})();
答案 0 :(得分:3)
...为什么'z'的声明会导致语法错误?
因为您在对象初始化程序之外使用属性初始化程序语法。
这是一个对象初始值设定项(以{
开头并以}
结尾的位),包含属性初始值设定项(中间行):
var obj = {
propertyName: "property value"
};
因此,如果您要声明对象,则可以使用z
行(不包含;
):
var obj = {
z: function() { return 'this is z'}
};
但是如果您在代码中拥有它,那么您就不在对象初始化程序中,而是在函数体中。所以你不能使用那种语法。
值得注意的是,x
和y
是完全不同的构造。
此:
function x(){return 'this is x'};
是一个函数声明。在运行包含函数中的任何分步代码之前处理函数声明,并且函数名称在包含函数顶部的范围内。 (有时人们称之为“吊装”。)
此:
y = function(){return 'this is y'};
是一个函数表达式。它像所有表达式一样被处理,它在逐步执行包含函数中的代码时遇到。
(引用的代码属于The Horror of Implicit Globals的牺牲品,顺便说一下:由于var
上没有y
,并且由于您没有使用严格模式,因此该行会创建 global 变量名为y
。)
在自执行函数中声明函数的正确方法是什么?
两种形式(x
或y
形式)都不比另一种形式更正确(不考虑隐式全局事物)。他们每个人都有用途,这取决于你在做什么。 y
形式存在函数y
引用的问题没有名称(它是一个匿名函数 - 它分配给的变量有一个名称,但函数没有)。这可能会使调试变得更加困难(查看断点列表或调用堆栈),尽管现代调试器非常擅长在函数没有变量名时向您显示变量名称,但它们可以。
请注意,由于它们不是逐步代码的一部分,因此您无法在控件结构中使用函数声明:
function foo() {
if (condition) {
function bar() { /* ...do something... */ } // <==== WRONG
}
else {
function bar() { /* ...do something else... */ } // <==== WRONG
}
}
这是我们具有表达式功能的原因之一:
function foo() {
var bar;
if (condition) {
bar = function() { /* ...do something... */ }; // <==== Right
}
else {
bar = function() { /* ...do something else... */ }; // <==== Right
}
}
请注意,某些JavaScript引擎容忍上面的错误语法,但是它们容忍它的方式因引擎而异。有些引擎会将声明转换为表达式。其他人只是总是使用第二个声明。只是不要这样做。 : - )
最后:还有一种称为命名的函数表达式:
var x = function foo() { /* ... */ };
该函数有一个名称(foo
),引用它的变量有一个名称(x
)。这是一个表达式,因为它被用作右手值(=
的右侧,初始值设定项中的:
,如果您将其传递给可悲的是,各种各样的JavaScript引擎已经知道以各种不同的方式使NFE(因为它们被称为)错误,尽管我认为在今天的世界中,它实际上只是IE8及更早版本,{{3 }}
答案 1 :(得分:0)
作为执行的匿名函数(隐藏);
var objOuter = (function(){ // Anonymous Function
var funcPrivate = function() {
// private function contents
};
var funcPublic = function() {
// private function contents
};
return { // JavaScript Object
funcName : funcPublic // provides public access to funcPublic
};
})();
//objOuter.funcPrivate(); // Failure, private.
//objOuter.funcPublic(); // Failure, internal name for public function.
objOuter.funcName(); // Executes funcPublic in objOuter's scope.
作为JavaScript对象定义的一部分(一切都是公开的):
var objOuter = { // JavaScript Object
funcName : function() {
// function contents
}
};
objOuter.funcName(); // Executes funcName
匿名函数是执行JavaScript代码,但JavaScript对象定义的{}
内部是一种不同的语法,它将键和值组合在一起。
在JavaScript对象中,您将值function()
指定给键funcName
。当您引用该键并通过传递参数列表()
来执行它时,该函数将执行。
在匿名函数(也称为Revealing Module Pattern)中,您将在模块范围内定义私有函数,然后将这些函数的引用作为返回的JavaScript对象的一部分传递给调用代码。
答案 2 :(得分:0)
variableName : value
语法只能在对象的上下文中使用。例如:
var obj = {
z: function(){return 'this is z'};
};
在这种情况下,运行obj.z()
将返回This is an object
在您的情况下,您只是在函数的上下文中,而不是声明对象。这意味着您必须使用与x
或y
一起使用的语法。
答案 3 :(得分:0)
冒号表示法仅适用于对象语法。
例如
var theObj = {one : 'one', two : 'two'};
要添加到对象,您应该使用点表示法:
theObj.three = 'three';