函数与Object构造函数

时间:2013-10-03 16:51:53

标签: javascript function object constructor

我不确定如何提出这个问题,所以我会举例说明。说我有这个设置:

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

我尝试过其他疯狂的东西,但似乎没什么用。

有什么想法吗?还是我第一次坚持这样做?

4 个答案:

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