0

在下面的例子中,为什么 '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());

})();

http://jsfiddle.net/VXPsd/2/

4

4 回答 4

3

...为什么'z'的声明会导致语法错误?

因为您在对象初始化程序之外使用属性初始化程序语法。

这是一个包含属性初始化器(中间线)的对象初始化器(以 开头{和结尾的位):}

var obj = {
    propertyName: "property value"
};

因此,如果您要声明一个对象,则可以使用您的z行(不带;):

var obj = {
    z: function() { return 'this is z'}
};

但是在你的代码中,你不是在一个对象初始化器中,你在一个函数的主体中。所以你不能使用那种语法。

值得注意的是,您的xy是彼此完全不同的构造。

这个:

function x(){return 'this is x'}; 

是一个函数声明。在运行包含函数中的任何分步代码之前处理函数声明,并且函数名称在包含函数顶部的范围内。(有时人们称之为“吊装”。)

这个:

y = function(){return 'this is y'};

是一个函数表达式。它像所有表达式一样被处理,在包含函数中的代码的逐步执行中遇到它。

(引用的代码属于隐式全局的恐怖,顺便说一句:由于没有varon y,并且由于您没有使用严格模式,因此该行创建了一个名为 的全局变量y。)

在自执行函数中声明函数的正确方法是什么?

两种形式(xy形式)都不比另一种更正确(撇开隐含的全局事物不谈)。它们各有用途,这取决于您在做什么。该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)。它是一个表达式,因为它被用作右手边的值(an 的右手边,=初始化:器中的以各种不同的方式弄错 NFE(它们被称为),尽管我认为在当今世界,它实际上只是 IE8 和更早版本,它们在不同的时间创建了两个不同的功能

于 2013-07-02T17:58:45.270 回答
0

冒号符号仅适用于对象语法。

例如

var theObj = {one : 'one', two : 'two'};

为了添加到对象,您应该使用点表示法:

theObj.three = 'three';
于 2013-07-02T18:03:49.723 回答
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

Anonymous Function 是执行 JavaScript 代码,但{}JavaScript 对象定义的内部是一种不同的语法,将键和值配对。

在 JavaScript 对象中,您将值分配function()给 key funcName。当您引用该键并通过传递参数列表来执行它时(),该函数将执行。

在匿名函数(也称为显示模块模式)中,您在模块范围内定义私有函数,然后将对这些函数的引用作为返回的 JavaScript 对象的一部分传递给调用代码。

于 2013-07-02T18:01:47.007 回答
0

variableName : value语法只能在对象的上下文中使用。例如:

var obj = {
    z: function(){return 'this is z'};
};

在这种情况下运行obj.z()将返回This is an object
在您的情况下,您只是在函数的上下文中,而不是声明对象。这意味着您必须使用与xor一起使用的语法y

于 2013-07-02T18:02:27.370 回答