简体   繁体   English

函数与对象构造函数

[英]Function versus Object constructor

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? 还是我坚持做第一件事?

As demonstrated by your first example, functions in JavaScript are objects and can have properties. 如您的第一个示例所示,JavaScript中的函数是对象,并且可以具有属性。

ECMAScript defines " internal properties " (and internal methods) for objects. ECMAScript为对象定义“ 内部属性 ”(和内部方法)。 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]] . 我们用双方括号表示内部属性名称,例如[[Foo]]

When you call a function like foo() , you run the object's [[Call]] internal method. 当您调用foo()类的函数时,您将运行对象的[[Call]]内部方法。 However, only function objects have a [[Call]] internal method. 但是,仅功能对象具有[[Call]]内部方法。 It is not possible to set or change a non-host object's [[Call]] method; 不能设置或更改非宿主对象的[[Call]]方法。 it is set when the object is defined and there is no mechanism defined by ECMAScript to change it. 它是在定义对象时设置的,并且ECMAScript没有定义更改它的机制。 ("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 . 该函数(已分配给变量foo )具有一个永久的[[Call]]方法(根据13.2节中的函数创建规则),该方法运行doStuff并返回5

If you have a non-function object 如果您有非功能性物件

foo = { };

that object is lacking a [[Call]] property. 该对象缺少[[Call]]属性。 There is no way to give it a [[Call]] property, because non-host objects can only set [[Call]] at definition-time. 无法给它提供[[Call]]属性,因为非宿主对象只能在定义时设置[[Call]] The logical internal property [[Call]] does not correspond to any object property accessible in actual code. 逻辑内部属性[[Call]]与实际代码中可访问的任何对象属性都不对应。

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. 如果希望对象是可调用的,则像在第一个示例中一样,首先将其定义为函数。

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. 因为两个对象的类型不同,所以第一个对象是Function Object ,第二个Function 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. 这里唯一的可能性是,如果您可以将对象强制转换为函数,并且JavaScript本身没有此类功能。 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

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: 您可以用另一种方法来实现,因为在JavaScript中,函数是对象:

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

function x() {
    return true;
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM