JavaScript で「オブジェクト」を関数に変換するにはどうすればよいですか?
-
02-07-2019 - |
質問
JavaScript では、関数をオブジェクトとして扱うことができます。最初に変数を関数として定義すると、後でその関数にプロパティを追加できます。逆に、「オブジェクト」に機能を追加するにはどうすればよいでしょうか?
これは機能します:
var foo = function() { return 1; };
foo.baz = "qqqq";
この時点で、 foo()
関数を呼び出し、そして foo.baz
値は「qqqq」です。
ただし、最初にプロパティ割り当て部分を実行した場合、その後、変数に関数をどのように割り当てますか?
var bar = { baz: "qqqq" };
手配するには今何をすればよいですか bar.baz
値が「qqqq」になるようにする そして bar()
関数を呼び出すには?
解決
ここで混乱しがちですが、やりたいことを(簡単に、または明確に、または私の知る限り)行うことはできません。これが問題を解決するのに役立つことを願っています。
まず、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(){};
変数を「Object」として宣言すると、それを Function オブジェクトに変換することは (簡単に、または明確に、または私の知る限りでは) できません。Function 型の新しいオブジェクトを宣言し (関数コンストラクターを使用し、変数に匿名関数を割り当てるなど)、メソッドのプロパティを古いオブジェクトからコピーする必要があります。
最後に、起こり得る質問を予想して、関数として宣言した後でも、(私の知る限り) functionBody/source を変更することはできません。
他のヒント
これを行う標準的な方法はないようですが、これは機能します。
しかし、なぜなのかが問題です。
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 は整数です。整数には配列メソッドがありません。あなたにはそれができません。
オブジェクトタイプは関数であり、オブジェクト自体は関数のインスタンス化です。
javascript: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 です。観察する、
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 の「規約」に従って正しく解釈および実行されます。
もちろん、しわは常に存在し、次のようにして現れます。 =
. 。オブジェクトは、変数に代入されるときに、本格的なエンティティではなく、その値に「短絡」されることがよくあります。これは、ブール オブジェクトとブール値に関する問題です。
明示的なオブジェクトの識別により、この問題は解決されます。
javascript: x=new Number(1); x[50]=5; alert(x[50]);
「オーバーロード」は非常に正当な Javascript の実行であり、次のようなメカニズムで明示的に承認されています。 prototyping
ただし、コードの難読化は危険になる可能性があります。
最後のメモ:
javascript: alert( 123 . x = "not" );
javascript: alert( (123). x = "Yes!" ); /* ()'s elevate to full object status */
一時変数を使用します。
var xxx = function()...
次に、元のオブジェクトからすべてのプロパティをコピーします。
for (var p in bar) { xxx[p] = bar[p]; }
最後に、古いプロパティを持つ新しい関数を元の変数に再割り当てします。
bar = xxx;
var A = function(foo) {
var B = function() {
return A.prototype.constructor.apply(B, arguments);
};
B.prototype = A.prototype;
return B;
};
JavaScriptを使用すると、関数をオブジェクトとして扱うことができます - 関数にプロパティを追加できます。どのように逆を行い、オブジェクトに関数を追加しますか?
少し混乱しているようですね。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";
注意:私が問題をどのように解決したかというスタイルで書かれた投稿。OPの場合に使用できるかどうかは100%わかりません。
サーバー上で作成されたオブジェクトを変換し、JSON / ajax によってクライアントに配信する方法を探していたときに、この投稿を見つけました。
これにより、事実上、OP と同じ状況になりました。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
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