Как преобразовать «объект» в функцию в JavaScript?

JavaScript позволяет рассматривать функции как объекты - если вы сначала определяете переменную как функцию, вы можете впоследствии добавить свойства к этой функции. Как сделать наоборот и добавить функцию к «объекту»?

Это работает:

var foo = function() { return 1; };
foo.baz = "qqqq";

В этот момент foo() вызывает функцию, а foo.baz имеет значение «qqqq».

Однако, если вы сначала выполняете часть присвоения свойств, как вы впоследствии назначаете функцию переменной?

var bar = { baz: "qqqq" };

Что я могу сделать сейчас, чтобы bar.baz имел значение "qqqq" иbar() для вызова функции?

Я не понимаю необходимости этого делать. Вы можете привести конкретный пример того, чего пытаетесь достичь?

Geoff 24.09.2008 02:40

Я не могу сейчас придумать, как использовать вторую форму. Первый в некоторой степени полезен для статических переменных (хотя замыкания тоже подойдут). Я в основном спрашиваю, потому что не могу придумать способ добиться этого без копирования свойств, что прискорбно, поскольку они параллельные формы.

mjs 24.09.2008 02:55

Похоже, вы надеетесь, что, поскольку вы можете назначить метод объекту Javascript, вы также можете назначить перегрузку оператора. Я не знаю Javascript, поэтому не знаю ответа, но удачи ...

Steve Jessop 24.09.2008 03:28

Это кажется разумным вопросом, и я обнаружил, что хочу сделать это несколько раз. Предположительно потребуется изменить прототип объекта с Object.prototype на Function.prototype. Возможно, было бы проще сначала создать функцию, а затем передать свойства объекта.

beldaz 05.03.2012 04:51

Я использовал это для наследования функции ko viewmodel ctr от объекта json, сгенерированного на стороне сервера.

Davi Fiamenghi 14.03.2014 01:49
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
41
5
24 464
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

JavaScript allows functions to be treated as objects--you can add a property to a function. How do you do the reverse, and add a function to an object?

Вы, кажется, немного запутались. Функции в JavaScript, объекты находятся. И переменные находятся переменная. Вы не ожидали, что это сработает:

var three = 3;
three = 4;
assert(three === 3);

... так почему вы ожидаете, что присвоение функции вашей переменной каким-то образом сохранит ее предыдущее значение? Возможно, некоторые аннотации прояснят вам ситуацию:

// assigns an anonymous function to the variable "foo"
var foo = function() { return 1; }; 
// assigns a string to the property "baz" on the object 
// referenced by "foo" (which, in this case, happens to be a function)
foo.baz = "qqqq";

Второе задание в исходном вопросе сбивало с толку; Я удалил это сейчас. Как после bar = { baz: "qqqq" } сделать так, чтобы bar() можно было вызывать как функцию?

mjs 24.09.2008 02:49

Вы этого не сделаете. Вы только что назначили ему объект, который НЕ ЯВЛЯЕТСЯ является функцией - вы можете либо начать заново (и назначить ему функцию), либо продолжить свою жизнь.

Shog9 24.09.2008 02:59

Позвольте мне сказать по-другому: вы не называете функцию «полоса» больше, чем я называю 3 «три». Вы просто назначаете литерал переменной, и эту переменную можно переназначить на что-нибудь еще в любое время. Возможно, ваше замешательство возникло из-за неправильного понимания файла. оператор?

Shog9 24.09.2008 03:03

Мне кажется, этот вопрос имеет смысл. Хотя он сказал: «Назначьте функцию переменной», он, похоже, спрашивает (я немного воспользуюсь терминологией C++), как назначить метод operator () его объекту. Мне это не кажется плохим вопросом, даже если ответ - «нет».

Steve Jessop 24.09.2008 03:19

Кажется, нет стандартного способа сделать это, но это работает.

ПОЧЕМУ, однако, вопрос.

function functionize( obj , func )
{ 
   out = func; 
   for( i in obj ){ out[i] = obj[i]; } ; 
   return out; 
}

x = { a: 1, b: 2 }; 
x = functionize( x , function(){ return "hello world"; } );
x()   ==> "hello world" 

Другого способа добиться этого просто нет, делает

x = {}
x() 

БУДЕТ возвращать "ошибку типа". потому что «x» - это «объект», и вы не можете его изменить. это примерно так же разумно, как пытаться сделать

 x = 1
 x[50] = 5
 print x[50] 

это не сработает. 1 - целое число. целые числа не имеют методов массива. ты не можешь это сделать.

Почему это работает, вообще не загадка. Вы просто заменяете x на функцию.

Stavros Korokithakis 23.08.2011 19:08

Да, но это также копирует все свойства x в функцию перед заменой x функцией. Хотя я думаю (прошло несколько лет с тех пор, как я ответил на это), что «Почему» больше «функция - это объект, это немного сбивает с толку».

Kent Fredric 01.11.2011 03:28

Используйте временную переменную:

var xxx = function()...

затем скопируйте все свойства из исходного объекта:

for (var p in bar) { xxx[p] = bar[p]; }

наконец, переназначьте новую функцию со старыми свойствами исходной переменной:

bar = xxx;
Ответ принят как подходящий

Здесь легко запутаться, но вы не можете (легко, ясно или, насколько я знаю) делать то, что хотите. Надеюсь, это поможет прояснить ситуацию.

Во-первых, каждый объект в Javascript наследуется от объекта Object.

//these do the same thing
var foo = new Object();
var bar = {};

Во-вторых, функции объектов ЯВЛЯЮТСЯ в Javascript. В частности, они являются объектами Function. Объект Function наследуется от объекта Object. Проверить Конструктор функций

var foo = new Function();
var bar = function(){};
function baz(){};

Как только вы объявляете переменную «объектом», вы не можете (легко, ясно или, насколько мне известно) преобразовать ее в объект функции. Вам нужно будет объявить новый объект типа Function (с конструктором функции, присвоив переменной анонимную функцию и т. д.) И скопировать любые свойства методов из вашего старого объекта.

Наконец, предвидя возможный вопрос, даже если что-то объявлено как функция, вы не можете (насколько я знаю) изменить functionBody / source.

просто примечание, вы не можете изменить источник, но вы МОЖЕТЕ переопределить функцию (например, перезаписать ее) в любое время.

scunliffe 24.09.2008 05:45

Все объекты наследуются от Object.prototype (если не заданы явно для другого объекта). Функциональные объекты наследуются от Function.prototype.

Peppe L-G 23.05.2016 09:57

var bar = { 
    baz: "qqqq",
    runFunc: function() {
        return 1;
    }
};

alert(bar.baz); // should produce qqqq
alert(bar.runFunc()); // should produce 1

Я думаю, ты ищешь это.

также можно записать так:

function Bar() {
    this.baz = "qqqq";
    this.runFunc = function() {
        return 1;
    }
}

nBar = new Bar(); 

alert(nBar.baz); // should produce qqqq
alert(nBar.runFunc()); // should produce 1

Это вообще не затрагивает исходный вопрос, который заключался в том, как преобразовать простой объект в работающую функцию. Ваш ответ просто назначает функцию как свойство объекта.

krb686 28.06.2014 01:02

Типы объектов - это функции, а сам объект - это реализация функции.

alert([Array, Boolean, Date, Function, Number, Object, RegExp, String].join('\n\n'))

отображает (в FireFox):

function Array() {
    [native code]
}

function Boolean() {
    [native code]
}

function Date() {
    [native code]
}

function Function() {
    [native code]
}

function Number() {
    [native code]
}

function Object() {
    [native code]
}

function RegExp() {
    [native code]
}

function String() {
    [native code]
}

В частности, обратите внимание, что объект Function function Function() { [native code] } определяется как рекуррентное отношение (рекурсивное определение, использующее самого себя).

Также обратите внимание, что ответ 124402 # 124402 является неполным в отношении 1[50]=5. Это ДЕЙСТВИТЕЛЬНО присваивает свойство объекту Number и ЯВЛЯЕТСЯ действительным Javascript. Наблюдать,

alert([
  [].prop = "a",
  true.sna = "fu",
  (new Date()).tar = "fu",
  function(){}.fu = "bar",
  123[40]=4,
  {}.forty=2,
  /(?:)/.forty2 = "life",
  "abc".def = "ghi"
].join("\t"))

отображает

a   fu  fu  bar 4   2   life    ghi

правильно интерпретировать и выполнять в соответствии с "Правилами взаимодействия" Javascript.

Конечно всегда есть морщинка и проявление =. При присвоении переменной объект часто «замыкается» на свое значение вместо полноценной сущности. Это проблема с логическими объектами и логическими значениями.

Явная идентификация объекта решает эту проблему.

x=new Number(1);  x[50]=5;  alert(x[50]);

«Перегрузка» - это вполне законное упражнение для Javascript и явно одобрено такими механизмами, как prototyping, хотя обфускация кода может представлять опасность.

Заключительное примечание:

alert(  123 . x = "not"  );

alert( (123). x = "Yes!" );  /* ()'s elevate to full object status */

var A = function(foo) {                                                                                                      
  var B = function() {                                                                                                       
    return A.prototype.constructor.apply(B, arguments);
  };
  B.prototype = A.prototype;                                                                                                 
  return B;                                                                                                                  
}; 

Что именно это делает?

netpoetica 27.10.2012 07:47

NB: Пост написан в стиле того, как я решил проблему. Я не уверен на 100%, что это можно использовать в случае OP.

Я нашел этот пост, когда искал способ конвертировать объекты, созданные на сервере и доставленные клиенту с помощью JSON / ajax.

Это фактически оставило меня в той же ситуации, что и OP, объект, который я хотел преобразовать в функцию, чтобы иметь возможность создавать его экземпляры на клиенте.

В конце концов я придумал это, которое работает (по крайней мере, пока):

var parentObj = {}

parentObj.createFunc = function (model)
{
    // allow it to be instantiated
    parentObj[model._type] = function()
    {
        return (function (model)
        {
            // jQuery used to clone the model
            var that = $.extend(true, null, model);
            return that;
        })(model);
    }
}

Что затем можно использовать как:

var data = { _type: "Example", foo: "bar" };
parentObject.createFunc(data);
var instance = new parentObject.Example();

В моем случае я действительно хотел иметь функции, связанные с результирующими экземплярами объекта, а также иметь возможность передавать параметры во время его создания.

Итак, мой код был:

var parentObj = {};
// base model contains client only stuff
parentObj.baseModel =
{
    parameter1: null,
    parameter2: null,
    parameterN: null, 
    func1: function ()
    {
        return this.parameter2;
    },
    func2: function (inParams) 
    {
        return this._variable2;
    }
}

// create a troop type
parentObj.createModel = function (data)
{
    var model = $.extend({}, parentObj.baseModel, data);
    // allow it to be instantiated
    parentObj[model._type] = function(parameter1, parameter2, parameterN)
    {
        return (function (model)
        {
            var that = $.extend(true, null, model);
            that.parameter1 = parameter1;
            that.parameter2 = parameter2;
            that.parameterN = parameterN;
            return that;
        })(model);
    }
}

И назывался так:

// models received from an AJAX call
var models = [
{ _type = "Foo", _variable1: "FooVal", _variable2: "FooVal" },
{ _type = "Bar", _variable1: "BarVal", _variable2: "BarVal" },
{ _type = "FooBar", _variable1: "FooBarVal", _variable2: "FooBarVal" }
];

for(var i = 0; i < models.length; i++)
{
    parentObj.createFunc(models[i]);
}

И тогда их можно будет использовать:

var test1 = new parentObj.Foo(1,2,3);
var test2 = new parentObj.Bar("a","b","c");
var test3 = new parentObj.FooBar("x","y","z");

// test1.parameter1 == 1
// test1._variable1 == "FooVal"
// test1.func1() == 2

// test2.parameter2 == "a"
// test2._variable2 == "BarVal"
// test2.func2() == "BarVal"

// etc

Другие вопросы по теме