Javascript 函数与对象构造函数

Javascript 函数与对象构造函数,javascript,function,object,constructor,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 = { tes

我不太确定如何问这个问题,所以我会举个例子。假设我已经设置好了:

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";
我尝试过其他疯狂的事情,但似乎没有任何效果


有什么想法吗?还是我被第一种方法卡住了?

你不能只创建一个对象,然后像运行函数一样运行它

您可以通过另一种方式来实现,因为在JavaScript中,函数是一个对象:

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

function x() {
    return true;
}

您不能只是创建一个对象,然后像运行函数一样运行它

您可以通过另一种方式来实现,因为在JavaScript中,函数是一个对象:

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

function x() {
    return true;
}

没有得到你想要的东西,你想要像面向对象的东西吗?这可能会有帮助

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

没有得到你想要的东西,你想要像面向对象的东西吗?这可能会有帮助

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

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

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

当调用类似于
foo()
的函数时,运行对象的
[[call]]
内部方法。但是,只有函数对象具有
[[Call]]
内部方法。无法设置或更改非主机对象的
[[Call]]
方法;它是在定义对象并且ECMAScript没有定义任何机制来更改它时设置的。(“宿主”对象是浏览器或其他执行环境提供的对象,可以按不同的规则播放。除非你正在编写一个浏览器,否则你可能不需要考虑这个异常。) 因此,如果您定义一个函数

foo = function() { doStuff(); return 5; };
该函数(分配给变量
foo
)有一个永久的
[[Call]]]
方法(根据中的函数创建规则),该方法运行
doStuff
并返回
5

如果你有一个非函数对象

foo = { };
该对象缺少
[[Call]]
属性。无法给它一个
[[Call]]
属性,因为非主机对象只能在定义时设置
[[Call]]]
。逻辑内部属性
[[Call]]
与实际代码中可访问的任何对象属性都不对应


总之,使非函数对象可调用是不可能的。如果您希望对象是可调用的,请首先将其定义为函数,就像您在第一个示例中所做的那样。

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

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

当调用类似于
foo()
的函数时,运行对象的
[[call]]
内部方法。但是,只有函数对象具有
[[Call]]
内部方法。无法设置或更改非主机对象的
[[Call]]
方法;它是在定义对象并且ECMAScript没有定义任何机制来更改它时设置的。(“宿主”对象是浏览器或其他执行环境提供的对象,可以按不同的规则播放。除非你正在编写一个浏览器,否则你可能不需要考虑这个异常。) 因此,如果您定义一个函数

foo = function() { doStuff(); return 5; };
该函数(分配给变量
foo
)有一个永久的
[[Call]]]
方法(根据中的函数创建规则),该方法运行
doStuff
并返回
5

如果你有一个非函数对象

foo = { };
该对象缺少
[[Call]]
属性。无法给它一个
[[Call]]
属性,因为非主机对象只能在定义时设置
[[Call]]]
。逻辑内部属性
[[Call]]
与实际代码中可访问的任何对象属性都不对应


总之,使非函数对象可调用是不可能的。如果您希望对象是可调用的,请首先将其定义为函数,就像您在第一个示例中所做的那样。

简单地说,您不能。为什么?因为两个对象的类型不同,第一个是
函数对象
,第二个是返回标准对象。所以两者都是从不同的祖先那里继承的。这里唯一的可能性是,如果您可以将对象强制转换为函数,而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

简单地说,你不能。为什么?因为两个对象的类型不同,第一个是
函数对象
,第二个是返回标准对象。所以两者都是从不同的祖先那里继承的。这里唯一的可能性是,如果您可以将对象强制转换为函数,而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

您试图解决的问题是什么?我只是想知道如何从一个对象开始,并将一个函数附加到该对象,以便
x()
运行该函数。函数是唯一可调用的本机EMCAScript类型。不能使非函数可调用,因为ECMAScript不公开任何操作对象的
[[Call]]
内部属性的方法。如果你想把一个对象变成一个函数,为什么不首先把它变成一个函数呢?在JS中,函数是一个对象,反之亦然,它不是一个代码。但实际上,我只是想知道这是否可能。你想解决的问题是什么?我只是想知道如何从一个对象开始