посилання / псевдонім на змінну javascript


89

Чи можливо в javascript якось призначити псевдонім / посилання на локальний var?

Я маю на увазі щось подібне до С:

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

= РЕДАКТУВАТИ =

Чи можна в цьому коді встановити псевдонім argument.callee ?:

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

5
Проста відповідь - ні. Але я відчуваю, що хтось із СО прийде з
хаклом,

Відповіді:


173

У JavaScript примітивні типи, такі як цілі числа та рядки, передаються за значенням, тоді як об'єкти передаються за посиланням. Отже, для досягнення цього вам потрібно використовувати об’єкт:

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

це було швидко =) я хочу створити псевдонім для argument.callee всередині моєї функції (лише для того, щоб не вводити svaki раз аргументи. callee). чи можливо це за допомогою цього методу? Якщо я розумію, я можу псевдонім "аргументи", але я все одно повинен написати "виклик", правда?
gpilotino

9
@ Дарін: це дещо спрощує це. Це незмінні проти змінних типів, а не примітивні типи проти об’єктів. У JavaScript все є об’єктом у певній формі.
Crescent Fresh

7
У JS посилання передається за значенням. Існує різниця між "передача-за-посиланням" та "передача-за-посиланням-за-значенням". У Javascript передача параметрів за посиланням не підтримується.
Корнеліу,

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); // друкує 2" має бути: "alert (y ()); // друкує 2" Вам потрібно фактично викликати функцію, щоб отримати результат. Шкода, оскільки запропонований синтаксис був би корисним у певних ситуаціях.
Nathan Labenz

3
Це повторне визначення toString існує з певної причини, тому alert(y)насправді є правильним. Хоча перевизначення методів прототипу функції є дуже поганим стилем. Але ей, це працює!
metalim

8

Чи можете ви встановити псевдонім, залежить від типу даних. Об’єкти, масиви та функції будуть оброблятися за допомогою посилань, і можливе створення псевдонімів. Інші типи є по суті атомними, і змінна зберігає значення, а не посилання на значення.

argument.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 році?)
aljgom

1

редагувати до моєї попередньої відповіді: якщо ви хочете порахувати виклики функції, ви можете спробувати:

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

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

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

Тут c служить лічильником, і вам не потрібно використовувати аргументи .callee.


або ви можете використовувати статичну змінну countMe = function f(){ return ++f.c || (f.c = 1); }
aljgom


0

у 2019 році мені потрібно написати мініфіковані плагіни jquery, тому мені він теж потрібен, цей псевдонім, і тому, перевіряючи ці приклади та інші, з інших джерел, я знайшов спосіб без копіювання в пам'яті всього об'єкта, але створивши лише посилання. Я тестував це вже з firefox і спостерігав за пам'яттю вкладки диспетчера завдань у firefox раніше. Код:

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

Це нічого не передає за посиланням, ви можете просто передати документ безпосередньо (який вже є посиланням на об'єкт і передається за значенням). Деструктуризація не створює псевдонімів.
Згадайте Моніку
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.