2

我有以下 JavaScript 函数:

function Console() {
    this.Log = function(msg) {
        if (document.getElementById("console")) {
            var console = document.getElementById("console");
            console.innerHTML += msg + "<br/>";
        }
    }
}

问题一: 为什么要使用新的关键词?

new Console().Log("hello world");

为什么我不能这样做?

Console().Log("hello world without using new");

问题2:

var logger = function() {
    this.log = function(msg) {
        new Console().Log(msg);
        new Console().Log("log initialized");
    }

    this.log2 = function(msg) {
        new Console().Log(msg);
        new Console().Log("log2 initialized");
    }
}(); //notice the brackets

由于记录器末尾的 () ,这不会运行。

new logger().log("hello world");

我知道尾随 () 意味着该函数被立即调用,但为什么它不起作用?是不是因为 function() {} (); 不能赋值给其他变量?

4

3 回答 3

5
  1. new关键字创建您的对象的一个​​实例,然后Console您可以调用该Log方法。如果您只是Console()直接调用,您将获得该函数的任何返回值。在你的情况下没有,所以undefined. 此外,如果您不使用new关键字,那么您在该“类函数”中分配的任何内容this都会污染全局范围。因此this,您不必将方法分配给 ,而是必须使用您将返回的代理对象。

  2. 在您的示例中,您将logger变量分配给调用匿名函数的返回值。同样,它不会返回任何内容,因此调用new logger()将不起作用,因为您无法实例化undefined. 因此,从匿名函数中删除尾随()会将函数分配logger不是返回值,然后您可以使用new. (您也可以再次使用代理对象)。

在上述两个示例中,我强烈建议使用new关键字而不是创建和返回代理对象。这利用了 Javascript 内置的实例化机制和函数原型链,比创建对象快得多

John Resig 的这篇博文值得一读,以了解有关“类”实例化如何在 Javascript 中工作的更多信息:http: //ejohn.org/blog/simple-class-instantiation/

于 2009-08-28T00:43:34.993 回答
2

function(){}()正如您所指出的,当您这样做时,您将立即定义和调用一个函数。因此,当你有这个时:

var logger = function(){}();

您分配logger的是该函数的返回值,而不是函数本身。在您的示例中,该函数不返回任何内容,因此logger将是未定义的。

就风格而言,在编写立即调用的匿名函数时,将函数包装在括号中是非常标准的:

var logger = (function() { ... })();

这只是对读者的视觉提示,您将调用该函数,它可以避免很多混乱。实际上,在某些情况下这样做非常重要:请参阅下面的评论!

于 2009-08-28T00:43:40.360 回答
2

答案1:

您在“this”中添加了“Log”功能。这就是您必须先从 Console 函数创建对象才能访问它的原因。

当您执行 Console().Log() 时,您正在尝试运行 Console 函数并在返回的对象上调用“Log”方法。由于 Console 函数不返回任何内容,因此它是“未定义的”,因此您无法访问 Log 方法。

答案 2:

“记录器”不是函数,而是匿名函数输出的结果。

E.g. var logger = function() { //your code; } ();

您的匿名函数不返回任何内容,因此 logger 将是“未定义的”。对于未定义的对象,没有“日志”方法。

要解决此问题,请执行以下操作:

var logger = function() {
    var output = {};
    output.log = function(msg) {
        new Console().Log(msg);
        new Console().Log("log initialized");
    }

    output.log2 = function(msg) {
        new Console().Log(msg);
        new Console().Log("log2 initialized");
    }

    return output;
}();

To use, you can write,

logger.log('hello');

了解 JS 中的函数和对象创建

您必须了解的主要内容是,在 JavaScript 中,常规函数在使用“new”关键字调用时充当“构造函数”。

考虑以下功能。

function Console()
{
    this['name'] = 'Console'
}

当你像这样调用上面的函数时,

   Console();
   alert(window.name); //alerts 'Console';

'this' 将是'window' 对象,它将添加'name' 属性和'Console' 的值。

如果您像这样调用上述函数,

   var output = new Console();
   alert(output.name)  // alerts 'Console'

JavaScript 将创建一个新对象,可以使用“控制台”中的“this”访问该对象。现在输出将具有“名称”属性。

让我知道如果上面没有为您解决问题。您必须了解它才能利用 JS 提供的功能。

于 2009-08-28T00:44:03.573 回答