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

发布于 2024-08-02 23:22:35 字数 989 浏览 6 评论 0原文

我有以下 JavaScript 函数:

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

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

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() {} ();不能分配给其他变量吗?

I have the following JavaScript function:

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

Question 1:
Why do I need to use new key word?

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

Why couldn't I just do this?

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

Question 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

This wouldn't run because of the () at the end of logger.

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

I know with the trailing () it means the function is called immediately but why wouldn’t it work? Is it because function() {} (); can't be assigned to other variables?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

樱花落人离去 2024-08-09 23:22:35
  1. new 关键字创建 Console 对象的实例,然后您可以在其上调用 Log 方法。如果您直接调用 Console(),您将获得该函数的返回值。在您的情况下,没有,因此未定义。此外,如果您不使用 new 关键字,则在该“类函数”内分配给 this 的任何内容都会污染全局范围。因此,您不必将方法分配给 this,而是必须使用要返回的代理对象

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

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

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

  1. The new keyword creates an instance of your Console object which you can then call the Log method on. If you just call Console() directly, you'll get whatever the return value is for that function. In your case there is none, so undefined. Additionally, if you don't use the new keyword, anything you assign to this within that "class function" will pollute the global scope. So instead of assigning your methods to this, you'd have to use a proxy object which you would return instead.

  2. In your example you're assigning the logger variable to the return value of calling your anonymous function. Again, it doesn't return anything so calling new logger() won't work because you can't instantiate undefined. So, removing the trailing () from the anonymous function will assign the function to logger rather than its return value, which you can then instantiate with new. (You could also use a proxy object again).

In both the above examples, I'd strongly advise using the new keyword rather than creating and returning a proxy object. This takes advantage of Javascript's built in instantiation mechanism and the function prototype chain, and is much faster than object creation.

This blog post by John Resig is worth a read for more information on how "class" instantiation works in Javascript: http://ejohn.org/blog/simple-class-instantiation/

椵侞 2024-08-09 23:22:35

答案1:

您将“日志”功能添加到“this”中。这就是您必须先从控制台函数创建对象才能访问它的原因。

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

答案2:

“logger”不是一个函数,而是匿名函数输出的结果。

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

您的匿名函数不会返回任何内容,因此记录器将是“未定义”。对于未定义的对象,没有“log”方法。

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

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”对象,并且它将添加值为“Console”的“name”属性。

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

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

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

如果以上内容还不能帮助您解决问题,请告诉我。您必须了解它才能利用 JS 提供的功能。

Answer 1:

You added the 'Log' function to the 'this'. That's the reason you have to create object from Console function before you can access it.

When you do Console().Log(), you are trying to run Console function and call 'Log' method on the returned object. Because Console function doesn't return anything, it is 'undefined' and hence you can't access the Log method.

Answer 2:

The 'logger' is not a function but result of the anonymous function output.

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

Your anonymous function doesn't return anything so logger will be 'undefined'. And for an undefined object, there is no 'log' method.

To solve this problem, do this:

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');

Understanding function and Object creation in JS

The main thing you have to understand is that in JavaScript, a regular function acts as a 'constructor' when called with 'new' keyword.

Consider following function.

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

When you call above function like this,

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

'this' will be the 'window' object and it will add 'name' property with the value of 'Console'.

If you call the above function like,

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

JavaScript will create a new object which is accessible using 'this' inside 'Console'. Now output will have 'name' property.

Let me know if above doesn't clear up things for you. It's essential that you understand it to be able to take advantage of what JS has to offer.

一桥轻雨一伞开 2024-08-09 23:22:35

正如您所指出的,当您执行 function(){}() 时,您将立即定义并调用函数。因此,当您遇到以下情况时:

var logger = function(){}();

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

正如风格问题, 在编写立即调用的匿名函数时,将函数括在括号中是相当标准的:

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

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

When you do function(){}() you are defining and calling a function immediately, as you pointed out. Therefore when you have this:

var logger = function(){}();

You are assigning logger to be the return value of that function, not the function itself. In your example, the function returns nothing, therefore logger will be undefined.

Just as a matter of style, when writing anonymous functions which are called immediately, it's pretty standard to wrap the function in parentheses:

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

It's just a visual hint to the reader that you are going to be calling that function, and it can save a lot of confusion. Actually, it's rather important to do that in some situations: see the comments below!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文