关于JavaScript构造函数和匿名函数的一些问题

Jef*_*eff 2 javascript anonymous function

我有以下JavaScript函数:

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

问题1: 为什么我需要使用新的关键字?

new Console().Log("hello world");
Run Code Online (Sandbox Code Playgroud)

为什么我不能这样做?

Console().Log("hello world without using new");
Run Code Online (Sandbox Code Playgroud)

问题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
Run Code Online (Sandbox Code Playgroud)

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

new logger().log("hello world");
Run Code Online (Sandbox Code Playgroud)

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

Jam*_*are 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/