2013-10-03 49 views
0

我不完全知道如何问这个问题,所以我会用例子做。说我有这样的设置:功能与对象的构造

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

如预期那样工作:

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

现在,我想知道如何设置了先用一个对象开始。我尝试使用构造函数添加函数,但这不起作用。

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"; 

我试过其他疯狂的东西,但似乎没有任何工作。

任何想法?或者我坚持这样做的第一种方式?

+0

你试图解决什么问题? – Pointy

+0

我只想知道如何从一个对象开始,并附加一个函数,所以'x()'运行该函数。 – Mottie

+2

函数是唯一可调用的本机EMCAScript类型。你不能进行非函数调用,因为ECMAScript没有公开任何方式来操作对象的[[Call]]内部属性。如果你想把一个对象变成一个函数,为什么不把它作为一个函数呢? – apsillers

回答

3

正如您的第一个示例所示,JavaScript中的函数是对象并且可以具有属性。

ECMAScript中定义的 “internal properties”(和内部方法)对象。这些内部属性有助于定义对象的状态,但并不是所有对象的内部属性都可以直接从代码中设置。我们使用双方括号表示内部属性名称,如[[Foo]]

当你调用像foo()功能,运行对象的[[Call]]内部方法。但是,只有函数对象具有[[Call]]内部方法。无法设置或更改非主机对象的[[Call]]方法;它是在定义对象时设置的,并且没有ECMAScript定义的机制来更改它。 (通过浏览器或其他执行环境提供,可以通过不同的规则行事“主机”对象的对象。除非你正在编写一个浏览器,你可能不需要考虑这个例外。)

因此,如果您定义一个函数

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

该功能(其被分配给变量foo)具有永久[[Call]]方法(每个功能创建规则中section 13.2),它运行doStuff并返回5

如果你有一个非函数对象

foo = { }; 

该对象缺乏[[Call]]属性。有没有办法给它一个[[Call]]属性,因为非主机的对象可以在定义时只设置[[Call]]。逻辑内部属性[[Call]]不对应于实际代码中可访问的任何对象属性。

总而言之,无法调用非函数对象。如果你想要一个对象被调用,那么首先将它定义为一个函数,就像你在第一个例子中做的那样。

+0

谢谢,那完全回答了我的问题:) – Mottie

0

你不能只创建一个对象,并在以后执行它,仿佛它是一个函数。

你可以围绕做的其他方式,如在JavaScript函数是一个对象:

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

function x() { 
    return true; 
} 
0

没有得到你想要什么,你要什么样的面向对象的?这可能有帮助

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"; 
1

简而言之,你不能。为什么?因为两个对象的类型都是不同的,所以首先一个Function Object,然后返回一个标准对象。所以都从不同的祖先继承。这里唯一的可能性是,如果你可以将对象转换为函数,并且原生没有可用的JavaScript。但是,您可以使用自己的投射方法。

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