javascript変数リファレンス/エイリアス


89

JavaScriptでエイリアス/参照をローカル変数に割り当てることは可能ですか?

私はCのようなものを意味します:

function foo() {
  var x = 1;
  var y = &x;
  y++;
  alert(x); // prints 2 
}

=編集=

このコードでarguments.calleeにエイリアスを付けることは可能ですか?:

function foo() {
  arguments.callee.myStaticVar = arguments.callee.myStaticVar || 0;
  arguments.callee.myStaticVar++;
  return arguments.callee.myStaticVar;
}

5
単純な答えはノーです。しかし、私はSOの誰かがこれを行うためのハックを付けてくるだろうと感じています:)
Amarghosh 2009年

回答:


173

JavaScriptでは、整数や文字列などのプリミティブ型は値で渡されますが、オブジェクトは参照で渡されます。したがって、これを実現するには、オブジェクトを使用する必要があります。

// declare an object with property x
var obj = { x: 1 };
var aliasToObj = obj;
aliasToObj.x ++;
alert( obj.x ); // displays 2

それは高速でした=)私は関数の内部でarguments.calleeのエイリアスを作成したいと思っています(arguments.calleeを毎回入力しないようにするためだけです)。この方法でこれは可能ですか?理解できれば、「引数」の別名を付けることもできますが、それでも「呼び出し先」を書かなければなりませんね。
gpilotino 2009年

9
@ダーリン:これは少し単純化しすぎています。プリミティブ型とオブジェクトではなく、不変型と可変型です。JavaScriptでは、すべてが何らかの形のオブジェクトです。
クレセントフレッシュ

7
JSでは、参照は値で渡されます。「参照渡し」と「値渡し参照」には違いがあります。JavaScriptでは、参照によるパラメーターの受け渡しはサポートされていません。
Corneliu

15

これはある程度可能ですが、クロージャーを使用して変数のエイリアスを作成できます。

Function.prototype.toString = function() {
    return this();
}

var x = 1;
var y = function() { return x }
x++;
alert(y); // prints 2, no need for () because of toString redefinition 

1
"alert(y); // prints 2"は次のようになるはずです: "alert(y()); // prints 2"結果を取得するには、実際に関数を呼び出す必要があります。提案された構文は特定の状況で役立つため、残念です。
Nathan Labenz 2013

3
そのtoString再定義は理由があるのでalert(y)、実際には正しいです。Functionプロトタイプメソッドの再定義は非常に悪いスタイルですが。しかし、ちょっと、それはうまくいきます!
メタリム2016

8

エイリアスを設定できるかどうかは、データ型によって異なります。オブジェクト、配列、および関数は参照によって処理され、エイリアスが可能です。他のタイプは基本的にアトミックであり、変数は値への参照ではなく値を格納します。

arguments.calleeは関数なので、それを参照して、その共有オブジェクトを変更できます。

function foo() {
  var self = arguments.callee;
  self.myStaticVar = self.myStaticVar || 0;
  self.myStaticVar++;
  return self.myStaticVar;
}

上記のコードでは、あなたが言っていた場合、その注self = function() {return 42;};そしてself、その後に参照することになり、別のオブジェクトよりもarguments.callee参照まま、foo。複合オブジェクトがある場合、代入演算子は参照を置き換えますが、参照されるオブジェクトは変更しません。アトミック値の場合、のようなケースy++はと同等でy = y + 1、変数に「新しい」整数を割り当てます。


arguments.callee関数の名前であるエイリアスが既にあることは言うまでもありません。この例では、単に使用できますfoo.myStaticVar(多分これは2009年には
当てはまり

1

私の以前の答えを編集してください:関数の呼び出しを数えたいなら、あなたは試してみたいかもしれません:

var countMe = ( function() {
  var c = 0;

  return function() {
    c++;
    return c;
  }
})();

alert(countMe()); // Alerts "1"
alert(countMe()); // Alerts "2"

ここでは、cがカウンターとして機能し、arguments.calleeを使用する必要はありません。


または、静的変数を使用することもできます countMe = function f(){ return ++f.c || (f.c = 1); }
aljgom

1

user187291の投稿を拡張すると、関数の使用を回避するためにゲッター/セッターを使用することもできます。

var x = 1;
var ref = {
    get x()  { return x; },
    set x(v) { x = v; }
};
(ref.x)++;
console.log(x); // prints '2'
x--;
console.log(ref.x); // prints '1'

0

2019では、縮小されたjqueryプラグインを作成する必要があるため、このエイリアスも必要なので、他のソースからこれらの例やその他をテストし、オブジェクト全体のメモリにコピーせずに参照のみを作成する方法を見つけました。私はこれをすでにFirefoxでテストしていて、Firefoxでタスクマネージャーのタブメモリを見ていたことがあります。コードは次のとおりです。

var {p: d} ={p: document};
console.log(d.body);

これは参照で何も渡さず、直接ドキュメントを渡すことができます(すでにオブジェクトへの参照であり、値で渡されます)。解体によってエイリアスが作成されることはありません。
モニカを思い出す
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.