0

I'm not exactly sure how to ask this question, so I'll do it by example. Say I have this set up:

var x = function() {
  console.log('YAY!');
};
x.test0 = 0;
x.test1 = 1;
x.test2 = "hello world";

that works as expected:

x(); // YAY!
x.test0 // 0
x.test2 // "hello world"

Now, I would like to know how to set this up starting with an object first. I tried adding the function using constructor, but that doesn't work.

var x = {
  test0 : 0,
  test1 : 1, 
  test2 : 'hello world',
  constructor: function() {
    console.log('YAY!');
  }
}

x(); // object is not a function
x.test0 // 0
x.test2 // "hello world";

I've tried other crazy things, but nothing seems to work.

Any ideas? Or am I stuck doing it the first way?

11
  • What is the problem you're trying to solve? Commented Oct 3, 2013 at 16:55
  • I just would like to know how to start with an object and attach a function to it so x() runs the function. Commented Oct 3, 2013 at 16:56
  • 2
    Functions are the only native EMCAScript type that is callable. You can't make a non-function callable, because ECMAScript doesn't expose any way to manipulate an object's [[Call]] internal property. If you wanted to make an object into a function, why not just make it a function in the first place? Commented Oct 3, 2013 at 16:57
  • 1
    IN JS FUNCTION IS AN OBJECT BUT VICE VERSA IS NOT CORRECT Commented Oct 3, 2013 at 16:58
  • 1
    Cleaner code. But really, I just wanted to know if it was possible. Commented Oct 3, 2013 at 17:07

4 Answers 4

3

As demonstrated by your first example, functions in JavaScript are objects and can have properties.

ECMAScript defines "internal properties" (and internal methods) for objects. These internal properties help define the state of an object, but not all of an object's internal properties are directly settable from code. We denote an internal property name with double square brackets, like [[Foo]].

When you call a function like foo(), you run the object's [[Call]] internal method. However, only function objects have a [[Call]] internal method. It is not possible to set or change a non-host object's [[Call]] method; it is set when the object is defined and there is no mechanism defined by ECMAScript to change it. ("Host" objects are objects supplied by the browser or other execution environment and can play by different rules. Unless you're writing a browser, you probably don't need to consider this exception.)

Thus, if you define a function

foo = function() { doStuff(); return 5; };

that function (which is assigned to the variable foo) has a permanent [[Call]] method (per the function-creation rules in section 13.2), which runs doStuff and returns 5.

If you have a non-function object

foo = { };

that object is lacking a [[Call]] property. There is no way to give it a [[Call]] property, because non-host objects can only set [[Call]] at definition-time. The logical internal property [[Call]] does not correspond to any object property accessible in actual code.

In sum, making a non-function object callable is not possible. If you want an object to be callable, define it initially as a function, as you do in your first example.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, that completely answered my question :)
1

To put it simply you can't. Why? because the types of both the objects are different first a Function Object and second returns a standard object. So both inherits from different ancestors. The only possibility here is if you can cast object to a function and there's no such thing available n JavaScript natively. However you can use your own cast method.

function toFunction (obj, fnProp) {
    var fn = function () {};
    if (typeof obj[fnProp] !== 'function') return fn;
    else {
        fn = obj[fnProp];
        for (prop in obj) {
            fn[prop] = obj[prop];
        }
    }
    return fn;  
}


var z = toFunction(y, 'prototype');    // with your example

Comments

0

You can't just create an object and later run it as if it were a function.

You can do it the other way around, as in JavaScript a function is an object:

x.prop=1;
console.log(x.prop);

function x() {
    return true;
}

Comments

0

Did not got exactly what you want, do you want something like object oriented? This may help

function x(){
    this.test0 = 0;
    this.test1 = 1;
    this.test2 = 'hello word';
    console.log('Wow!');
}

var y = new x(); // new object of x PRINTS WOW and set's default values
console.log(y.test0) // 0
console.log(y.test2) // "hello world";

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.