2015-04-16 5 views
1

В JavaScript функции могут быть вызваны.Выполнение объекта без вызова

Можно ли удалить этот атрибут из функции, оставив только обычный объект?

var foo = function() {}; 
foo.[[callable]] = false; // pseudocode 
foo(); // "foo is not a function" 
+8

Из любопытства, что вы хотите сделать, что не может быть сделаны с простым старым объектом? –

+3

С какой целью? –

+1

@ user3749178 Любопытство. – Ben

ответ

4

Могу ли я удалить этот атрибут из функции , оставив только обычный объект?

№ Функции (поведение оценки, а не их свойства объекта) в значительной степени неизменяемы.

Объекты callability определяются путем определения того, имеется ли у них слот [[call]]. spec says about those:

Внутренние слоты выделяются как часть процесса создания объекта и не могут быть динамически добавлены к объекту.

(и подразумевается, что они не могут быть удалены динамически). Кроме того, «Эти внутренние методы не являются частью языка ECMAScript» и «не являются объектами» », что означает, что они не могут быть доступны, установлены, удалены или обработаны каким-либо возможным способом с помощью языка.

[[call]] слоты являются частью различных объектов, где они всегда содержат внутренний метод, но они никогда не мутируются, за исключением их инициализации (один раз).Они бывают различных видов:

  • [[call]], определяемых пользователем функциональных объектов, инициализированных на этапе 8 FunctionAllocate
  • [[call]] из встроенных функциональных объектов, инициализированных неявно среды
  • [[call]] связанных функциональных объектов, инициализируются на шаге 6 BoundFunctionCreate
  • [[call]] некоторых объектов прокси, инициированную условно на этапе 7а ProxyCreate тогда и только тогда целевой прокси является вызываемая, а

Как вы можете видеть, нет способа изменить или даже удалить слот [[call]] объекта, даже не на прокси. Лучше всего

  • сделать функцию throw при вызове в неурочное состоянии
  • создать новый uncallable объект из функции с помощью

    var obj = Object.assign(Object.create(Object.getPrototypeOf(fn)), fn); 
    
+1

Вау, эти 125 представителей пришли быстро :-) – Bergi

+1

Вы ответили на вопрос! В отличие от 100 других людей, которые его рассматривали, и трех downvoters. – Ben

0

Насколько я знаю, вы не можете.

Функции имеют свойство, называемое call(), которое вызывает тело функции (извините за избыточность).

Вы можете установить это свойство для любого выражения, как, например,

foo.call = console.log('foo not a function'); 

, но это не помешает тело функции будет называться.

И поскольку вы не можете установить его в функцию, вы не можете использовать функцию event.preventDefault().

-1

это не элегантное решение, идея состоит в том, чтобы создать «включен» атрибут как флаг, чтобы знать, если эта функция включена:

var foo = function() { 
    if(!arguments.callee.enabled){ 
    throw "function disabled"; 
    } 
    console.log("Hello"); 
} 

foo.enabled = true; 
foo(); 
foo.enabled = false; 
foo(); 
+0

Это решение мне не по душе, поэтому я предлагаю награду –

0

Мне нравится обеспечивая дополнительная точка зрения на то, что Bergi уже did mention, также поощряется этим ответом в вопросе ОП.

С какой целью? - user3749178 16 апреля в 16:18

.

@ user3749178 Любопытство. - Бен Aston 16 апреля 16:19

кроме var obj = Object.assign(Object.create(Object.getPrototypeOf(fn)), fn);, что зависит от ES6, есть ES3 совместимый подход, который делает завернуть функции объектов в ГОО объектов. Таким образом, эти объекты больше не вызываются вызывающим оператором (), но такие объекты все еще выставляют два метода вызова call и apply. Поскольку этот подход не позволяет, с одной стороны, вызывать функции, вызываемые () (методы/функции) или оператором (экземпляром) new, но он по-прежнему поддерживает делегирование (основанные на функциях mixins/traits).

суть состоялась код Function.toApplicator

Смежные вопросы