3

少し調べてみたところ、この質問に対する答えは見つかりませんでしたが、以前に尋ねられたことがあると思います。私が見つけることができる最も近いのは、オブジェクト内のこの関数ポインターですが、私が求めているものはまったく得られません。

次のようなコードがあるとします。

var foo = function () { /* some code */ };

ここで、評価時に foo という名前がその環境で関数の内部表現にバインドされ、アプリケーション時に検索されると想定しています。

ここで、プログラムの少し後で、オブジェクトがあるとします。

var obj = {};
obj.func = foo;

この時点で、同じ関数オブジェクトの 2 つのコピーが環境内にあるはずです。1 つは foo にバインドされ、もう 1 つは obj.func にバインドされています。しかし、その関数の 2 つのコピーが必要ではなく、obj.func が foo を指すようにしたいとしましょう。これを行う方法はありますか? これは私が思いついたものです:

var obj = {};
obj.func = function () { foo(); };

これは機能しますか?より良い方法はありますか?

どうもありがとう

明確化のために編集

申し訳ありません--私は十分に明確ではなかったと思います。これが役立つことを願っています。

Javascript の評価プロセスがどのように機能するかはわかりませんが、内部的に表された環境を追跡しているとしましょう。ここでは、キーと値のペアのセットとして抽象的に表します。

さて、評価者が次のようなコードを見ると、

var foo = function () { /* some code  */ };

これは、その環境で構築されます: ['foo' : [関数オブジェクト]]。そして、後で、次のようなものが表示されます。

var bar = foo;

環境内で foo を検索して、その値である関数オブジェクトを取得し、そのように環境を拡張します。['foo' : [関数オブジェクト], 'bar' : [関数オブジェクト]]. これで、環境内に同じ機能が実際に 2 回存在します。これはjavascriptが環境をセットアップする方法ですか? そうでない場合、どのようにそうするのですか?

質問の動機は以下の通りです。いくつかの関数を定義し、後でその関数をそれらの関数へのインターフェイスとしてエクスポートするオブジェクトを定義し、何度もインスタンス化することがわかっているとしましょう。関数自体ではなく、関数へのポインターがオブジェクトに含まれていると、より効率的になります。

4

5 に答える 5

6

JS変数、オブジェクトプロパティなどは、オブジェクトを直接保持しません。それらはオブジェクトへの参照を保持します。と言うとvar foo = function() { };foo定義したばかりの関数への参照が割り当てられます。(ちなみに、ポインターではありません。違いは微妙ですが重要です。JSにはユーザーに表示されるポインターがないため、それほど問題にはなりません。しかし、そうする言語では、ポインターの使い方が異なります。自分で作成しないでください。後で学習を取り消す必要があります。)

そして、プログラムの後半で、と言うと、参照をにobj.func = foo;コピーしています。関数ではありません。関数オブジェクトは1つだけで、2つの参照があります。obj.func

だからobj.func = foo;、あなたが言っていたことはすでにやっています。を呼び出すとobj.func()、実際には。で参照されているのとまったく同じ関数が呼び出されfooます。ただし、大きな違いが1つあり、これが問題の原因である可能性があります。それ obj.funcは「メソッド呼び出し」であり、JSは関数内に設定thisobjれます。foo何かに使っていたらthis、それが他のオブジェクトだったとしたら、がっかりするでしょう。

それが問題なら、あなたは次のようなことをするかもしれません

var that = this;
var foo = function() { /* use `that` instead of `this` here */ };

次に、関数をとして呼び出すか、を呼び出すかに関係fooなくobj.func、変更されたの影響を受けませんthis

これで問題が解決しない場合は、質問を明確にする必要があります。

于 2012-08-07T03:58:59.263 に答える
0

少し詳しく説明します。

関数は、JavaScriptの第一級市民またはオブジェクトです。他のオブジェクトと同じように使用されます。

var foo = func() {
//some code
};

に類似しています

var foo = {
//some code
};

Javascriptでは、すべてのオブジェクトが参照によって渡されます。私の知る限り、javascriptオブジェクトのポインターや値渡しの概念はありません。

したがって、同じ関数に2つの参照を割り当てると、関数オブジェクトはコピーされません。ただし、関数の内部状態は両方の参照で同じままです。あなたの場合、fooとobj.func()

于 2012-08-07T07:09:16.567 に答える
0

これは真実ではありません:

この時点で、環境内に同じ関数オブジェクトの2つのコピーが存在するはずです。1つはfooにバインドされ、もう1つはobj.funcにバインドされています。しかし、その関数のコピーを2つ必要とせず、obj.funcをfooに向けて戻すとしましょう。

そのように物事を割り当てる場合、obj.funcとfooは同じ物を指します。関数をコピーすることさえできないと思います。

于 2012-08-07T03:58:27.923 に答える
0

サンプルを実行してみましたか?

fooはい、動作しますが、変数を変更すると の機能も変更されることに注意してくださいobjc.func()。これを行う他の方法を知りません。

于 2012-08-07T03:57:59.213 に答える
-1

この時点で、環境内に同じ関数オブジェクトの2つのコピーが存在するはずです。1つはfooにバインドされ、もう1つはobj.funcにバインドされています。

あなたはそう思う?コードに次のように書かれている場合は、好奇心からです。

var obj = {};
obj.func = 5;

何枚のコピー5が浮かんでいますか?

いいえ。すべてのコードは、本質的に定数である関数に変換されます。同じ定数に複数の変数を問題なく割り当てることができます。

「バインディング」に関しては、関数が呼び出されたときにバインディングが発生します。つまり、thisパラメータはに設定されobj、whooosh ...

于 2012-08-07T03:58:09.617 に答える