我不确定如何提出这个问题,所以我会举例说明。说我有这个设置:
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 :(得分: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]]
与实际代码中可访问的任何对象属性都不对应。
总而言之,不可能使非功能对象可调用。如果希望对象可以调用,最初将其定义为函数,就像在第一个示例中那样。
答案 1 :(得分:1)
简单地说,你不能。为什么?因为两个对象的类型不同,首先是Function Object
,第二个返回标准对象。所以两者都来自不同的祖先。这里唯一的可能性是,如果你可以将对象强制转换为函数,并且本机上没有这样的东西可用。但是,您可以使用自己的强制转换方法。
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
答案 2 :(得分:0)
你不能只是创建一个对象,然后就像它是一个函数一样运行它。
你可以反过来做,就像在JavaScript中一个函数是一个对象:
x.prop=1;
console.log(x.prop);
function x() {
return true;
}
答案 3 :(得分: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";