最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

A few question regarding JavaScript Constructor and Anonymous functions - Stack Overflow

programmeradmin0浏览0评论

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?

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?

Share Improve this question edited Aug 28, 2009 at 1:25 Breton 15.6k3 gold badges61 silver badges77 bronze badges asked Aug 28, 2009 at 0:29 JeffJeff 13.2k24 gold badges74 silver badges103 bronze badges 2
  • might i remend splitting these up into individual questions on here? – helloandre Commented Aug 28, 2009 at 0:34
  • The second anonymous function would run if you put a "return this;" at the end of it :) – Cleiton Commented Aug 28, 2009 at 0:42
Add a ment  | 

3 Answers 3

Reset to default 5
  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/blog/simple-class-instantiation/

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.

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 ments below!

发布评论

评论列表(0)

  1. 暂无评论