referensi / alias variabel javascript

89

Apakah mungkin dalam javascript untuk menetapkan alias / referensi ke var lokal bagaimanapun juga?

Maksud saya sesuatu seperti C:

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

= EDIT =

Apakah mungkin untuk alias arguments.callee dalam kode ini ?:

function foo() {
  arguments.callee.myStaticVar = arguments.callee.myStaticVar || 0;
  arguments.callee.myStaticVar++;
  return arguments.callee.myStaticVar;
}
gpilotino.dll
sumber
5
Jawaban sederhananya adalah tidak. Tapi saya merasa seseorang di SO akan datang dengan hack untuk melakukan ini :)
Amarghosh

Jawaban:

173

Dalam JavaScript, tipe primitif seperti integer dan string diteruskan oleh nilai sedangkan objek diteruskan oleh referensi. Jadi untuk mencapai ini, Anda perlu menggunakan objek:

// declare an object with property x
var obj = { x: 1 };
var aliasToObj = obj;
aliasToObj.x ++;
alert( obj.x ); // displays 2
Darin Dimitrov
sumber
itu cepat =) saya ingin membuat alias ke arguments.callee di dalam fungsi saya (hanya untuk menghindari mengetik arguments.callee setiap saat). apakah ini mungkin dengan metode ini? Kalau saya mengerti, saya bisa alias "argumen" tapi saya tetap harus menulis "callee", bukan?
gpilotino
9
@Darin: ini agak terlalu menyederhanakan. Ini adalah tipe yang tidak berubah vs bisa berubah, daripada tipe primitif vs objek. Dalam JavaScript semuanya merupakan objek dalam beberapa bentuk.
Crescent Fresh
7
Dalam JS, referensi diteruskan dengan nilai. Ada perbedaan antara "passing-by-reference" dan "passing-a-reference-by-value". Dalam Javascript, melewatkan parameter dengan referensi tidak didukung.
Corneliu
15

Sampai tingkat tertentu hal ini dimungkinkan, Anda dapat membuat alias ke variabel menggunakan closures:

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 
pengguna187291
sumber
1
Saya percaya "alert (y); // prints 2" seharusnya: "alert (y ()); // prints 2" Anda harus benar-benar memanggil fungsi tersebut untuk mendapatkan hasilnya. Sayang sekali, karena sintaks yang disarankan akan membantu dalam situasi tertentu.
Nathan Labenz
3
Definisi ulang toString itu ada karena suatu alasan, jadi alert(y)sebenarnya benar. Meskipun mendefinisikan ulang metode prototipe Fungsi adalah gaya yang sangat buruk. Tapi, hei, itu berhasil!
metalim
8

Apakah Anda dapat membuat alias atau tidak tergantung pada tipe datanya. Objek, array, dan fungsi akan ditangani dengan referensi dan aliasing dimungkinkan. Tipe lain pada dasarnya atom, dan variabel menyimpan nilai daripada referensi ke nilai.

arguments.callee adalah sebuah fungsi, dan oleh karena itu Anda dapat memiliki referensi dan memodifikasi objek bersama tersebut.

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

Perhatikan bahwa jika dalam kode di atas yang Anda katakan self = function() {return 42;};maka selfakan merujuk ke objek yang berbeda dari arguments.callee, yang tetap menjadi referensi foo. Saat Anda memiliki objek gabungan, operator penugasan menggantikan referensi, tidak mengubah objek yang dirujuk. Dengan nilai atom, kasus serupa y++setara dengan y = y + 1, yang menetapkan bilangan bulat 'baru' ke variabel.

Justin Love
sumber
Belum lagi yang arguments.calleesudah memiliki alias, yaitu nama fungsinya. Dalam contoh ini Anda bisa menggunakan foo.myStaticVar(mungkin ini bukan kasus di tahun 2009?)
aljgom
1

edit ke jawaban saya sebelumnya: jika Anda ingin menghitung pemanggilan suatu fungsi, Anda mungkin ingin mencoba:

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

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

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

Di sini, c berfungsi sebagai penghitung, dan Anda tidak harus menggunakan arguments.callee.

Tom Bartel
sumber
atau Anda dapat menggunakan variabel statis countMe = function f(){ return ++f.c || (f.c = 1); }
aljgom
1

Memperluas posting user187291 , Anda juga bisa menggunakan getter / setter untuk berkeliling harus menggunakan fungsi.

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'
Steven Jimenez
sumber
0

pada tahun 2019 saya perlu menulis plugin jquery minified jadi saya membutuhkannya juga alias ini dan menguji contoh-contoh ini dan lainnya, dari sumber lain, saya menemukan cara tanpa menyalin di memori seluruh objek, tetapi hanya membuat referensi. Saya sudah menguji ini dengan firefox dan menonton memori tab pengelola tugas di firefox sebelumnya. Kodenya adalah:

var {p: d} ={p: document};
console.log(d.body);
Constantin
sumber
Ini tidak melewatkan apa pun dengan referensi, Anda bisa meneruskan dokumen secara langsung (yang sudah menjadi referensi ke suatu objek, dan diteruskan oleh nilai). Perusakan tidak menciptakan alias.
Ingat Monica