JavaScript позволяет рассматривать функции как объекты - если вы сначала определяете переменную как функцию, вы можете впоследствии добавить свойства к этой функции. Как сделать наоборот и добавить функцию к «объекту»?
Это работает:
var foo = function() { return 1; };
foo.baz = "qqqq";
В этот момент foo() вызывает функцию, а foo.baz имеет значение «qqqq».
Однако, если вы сначала выполняете часть присвоения свойств, как вы впоследствии назначаете функцию переменной?
var bar = { baz: "qqqq" };
Что я могу сделать сейчас, чтобы bar.baz имел значение "qqqq" иbar() для вызова функции?
Я не могу сейчас придумать, как использовать вторую форму. Первый в некоторой степени полезен для статических переменных (хотя замыкания тоже подойдут). Я в основном спрашиваю, потому что не могу придумать способ добиться этого без копирования свойств, что прискорбно, поскольку они параллельные формы.
Похоже, вы надеетесь, что, поскольку вы можете назначить метод объекту Javascript, вы также можете назначить перегрузку оператора. Я не знаю Javascript, поэтому не знаю ответа, но удачи ...
Это кажется разумным вопросом, и я обнаружил, что хочу сделать это несколько раз. Предположительно потребуется изменить прототип объекта с Object.prototype на Function.prototype. Возможно, было бы проще сначала создать функцию, а затем передать свойства объекта.
Я использовал это для наследования функции ko viewmodel ctr от объекта json, сгенерированного на стороне сервера.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


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() можно было вызывать как функцию?
Вы этого не сделаете. Вы только что назначили ему объект, который НЕ ЯВЛЯЕТСЯ является функцией - вы можете либо начать заново (и назначить ему функцию), либо продолжить свою жизнь.
Позвольте мне сказать по-другому: вы не называете функцию «полоса» больше, чем я называю 3 «три». Вы просто назначаете литерал переменной, и эту переменную можно переназначить на что-нибудь еще в любое время. Возможно, ваше замешательство возникло из-за неправильного понимания файла. оператор?
Мне кажется, этот вопрос имеет смысл. Хотя он сказал: «Назначьте функцию переменной», он, похоже, спрашивает (я немного воспользуюсь терминологией C++), как назначить метод operator () его объекту. Мне это не кажется плохим вопросом, даже если ответ - «нет».
Кажется, нет стандартного способа сделать это, но это работает.
ПОЧЕМУ, однако, вопрос.
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 на функцию.
Да, но это также копирует все свойства x в функцию перед заменой x функцией. Хотя я думаю (прошло несколько лет с тех пор, как я ответил на это), что «Почему» больше «функция - это объект, это немного сбивает с толку».
Используйте временную переменную:
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.
просто примечание, вы не можете изменить источник, но вы МОЖЕТЕ переопределить функцию (например, перезаписать ее) в любое время.
Все объекты наследуются от Object.prototype (если не заданы явно для другого объекта). Функциональные объекты наследуются от Function.prototype.
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
Это вообще не затрагивает исходный вопрос, который заключался в том, как преобразовать простой объект в работающую функцию. Ваш ответ просто назначает функцию как свойство объекта.
Типы объектов - это функции, а сам объект - это реализация функции.
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;
};
Что именно это делает?
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
Я не понимаю необходимости этого делать. Вы можете привести конкретный пример того, чего пытаетесь достичь?