2013-10-03 7 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, а второй возвращает стандартный объект. Таким образом, оба наследуются от разных предков. Единственная возможность здесь заключается в том, что вы можете наложить объект на функцию, и нет такой вещи, как novo. Однако вы можете использовать свой собственный метод литья.

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 
Смежные вопросы