javascript değişken referansı / takma adı


89

Javascript'te yerel bir değişkene bir takma ad / referans atamak mümkün müdür?

C benzeri bir şey demek istiyorum:

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

= DÜZENLE =

Bu kodda arguments.callee için takma ad vermek mümkün mü?

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

5
Basit cevap hayır. Ama
SO'daki birinin

Yanıtlar:


173

JavaScript'te, tamsayılar ve dizeler gibi ilkel türler değere göre aktarılırken, nesneler başvuruya göre iletilir. Yani bunu başarmak için bir nesne kullanmanız gerekir:

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

bu hızlıydı =) işlevimin içinde arguments.callee için bir takma ad yapmak istiyorum (sadece her seferinde arguments.callee yazmaktan kaçınmak için). bu, bu yöntemle mümkün müdür? Anlarsam, "argümanların" takma adını verebilirim ama yine de "aranmak" yazmam gerekiyor, değil mi?
gpilotino

9
@Darin: Bu onu biraz fazla basitleştiriyor. İlkel türler ve nesneler yerine değişmez ve değiştirilebilir türler. JavaScript'te her şey bir biçimde bir nesnedir.
Crescent Fresh

7
JS'de referans değere göre aktarılır. "Referansla geçme" ile "referansa göre geçiş" arasında bir fark vardır. Javascript'te parametrelerin referansa göre geçirilmesi desteklenmez.
Corneliu

15

Bir dereceye kadar bu mümkündür, kapanışları kullanarak bir değişken için bir takma ad oluşturabilirsiniz:

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); // 2 yazdırır" olması gerektiğine inanıyorum: "alert (y ()); // 2 yazdırır" Sonucu elde etmek için fonksiyonu gerçekten çağırmanız gerekir. Önerilen sözdizimi belirli durumlarda yardımcı olacağından çok kötü.
Nathan Labenz

3
ToString'in yeniden tanımlanmasının bir nedeni var, bu yüzden alert(y)aslında doğru. İşlev prototip yöntemlerini yeniden tanımlamak çok kötü bir stil olsa da. Ama hey, işe yarıyor!
metalim

8

Bir şeyi değiştirip değiştiremeyeceğiniz veri türüne bağlıdır. Nesneler, diziler ve işlevler referansla ele alınacaktır ve takma ad mümkündür. Diğer türler esasen atomiktir ve değişken, bir değere başvuru yerine değeri depolar.

arguments.callee bir işlevdir ve bu nedenle ona bir başvurunuz olabilir ve paylaşılan nesneyi değiştirebilirsiniz.

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

Yukarıdaki kodda Söyleyecek olsaydı o Not self = function() {return 42;};sonra selfsonra başvurmak istiyorum farklı nesnenin daha arguments.calleebir referans kalır foo. Bileşik bir nesneye sahip olduğunuzda, atama operatörü referansın yerini alır, başvurulan nesneyi değiştirmez. Atomik değerlerle, değişkene 'yeni' bir tamsayı atayan benzer bir durum y++eşdeğerdir y = y + 1.


arguments.calleeişlevin adı olan bir takma ada sahip olduğundan bahsetmeye gerek yok . Bu örnekte sadece kullanabilirsiniz foo.myStaticVar(belki de 2009'daki durum bu değildi?)
aljgom

2

User187291'in gönderisini genişleterek, işlevleri kullanmak zorunda kalmamak için alıcıları / ayarlayıcıları da kullanabilirsiniz.

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'

1

önceki cevabımı düzenle: Bir işlevin çağrılarını saymak istiyorsanız, şunu deneyebilirsiniz:

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

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

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

Burada c, sayaç görevi görür ve arguments.callee'yi kullanmanız gerekmez.


ya da statik bir değişken kullanabilirsiniz countMe = function f(){ return ++f.c || (f.c = 1); }
aljgom

1

2019'da küçültülmüş jquery eklentileri yazmam gerekiyor, bu yüzden ona da bu takma ada ihtiyacım var ve bu nedenle bu örnekleri ve diğerlerini, diğer kaynaklardan test ederek, tüm nesnenin belleğinde kopyasız bir yol buldum, ancak yalnızca bir referans oluşturdum. Bunu daha önce firefox ile test ettim ve daha önce firefox'ta görev yöneticisinin sekme belleğini izledim. Kod:

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

Bu, referansla hiçbir şeyi iletmez, yalnızca belgeyi doğrudan iletebilirsiniz (bu zaten bir nesneye referanstır ve değerle iletilir). Yok etme, takma adlar yaratmaz.
Monica'yı
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.