2009-11-06 8 views
84

Возможно ли в javascript назначить псевдоним/ссылку на локальный var?ссылка на переменную javascript

Я имею в виду то, что C-типа:

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

= EDIT =

Можно ли псевдоним arguments.callee в этом коде ?:

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

Простой ответ: нет. Но у меня такое чувство, что кто-то из SO придет с взломом, чтобы сделать это :) – Amarghosh

ответ

161

В JavaScript примитивных типов такие как целые числа и строки, передаются по значению, тогда как объекты передаются по ссылке. Поэтому для того, чтобы достичь этого вам нужно использовать объект:

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

, который был быстрым =) Я хочу сделать псевдоним для аргументов.callee внутри моей функции (просто чтобы не набирать аргументы.callee каждый раз) , возможно ли это с помощью этого метода? Если я понимаю, я могу использовать псевдонимы «аргументы», но мне все равно придется писать «вызывающе», не так ли? – gpilotino

+0

не могли бы вы разместить свой код? –

+0

. Я принимаю этот ответ, поскольку мой вопрос был слишком общим. – gpilotino

1

редактировать на мой предыдущий ответ: если вы хотите, чтобы рассчитывать заклинания функции,, вы можете попробовать:

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

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

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

Здесь c служит счетчиком, и вам не нужно использовать arguments.callee.

+0

или вы можете использовать статическую переменную 'countMe = function f() { return ++ f.c || (f.c = 1); } ' – aljgom

12

В какой-то степени это возможно, вы можете создать псевдоним для переменной с помощью затворов:

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

Я считаю "предупреждение (у); // печатает 2" должно быть: "предупреждение (у()); // печатает 2" Вы должны фактически вызвать функцию получить результат. Жаль, так как предложенный синтаксис был бы полезен в определенных ситуациях. –

+2

То, что перекрестное определение toString существует по какой-либо причине, поэтому 'alert (y)' на самом деле прав. Хотя переопределение методов прототипа функции очень плохой стиль. Но эй, это работает! – metalim

7

Если вы можете что-то псевдоним зависит от типа данных. Объекты, массивы и функции будут обрабатываться с помощью ссылки, а псевдонирование возможно. Другие типы по существу атомарны, и переменная сохраняет значение, а не ссылку на значение.

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, который присваивает переменной значение «новое».

+0

спасибо, вот что мне нужно знать. – gpilotino

+0

не говоря уже о том, что 'arguments.callee' уже имеет псевдоним, который является именем функции. В этом примере вы можете просто использовать 'foo.myStaticVar' (может быть, это было не так в 2009 году?) – aljgom

0

Я искал сегодня для моего проекта и нашел это, который выглядит лучшим способом сделать: http://sirdarckcat.blogspot.com/2007/07/passing-reference-to-javascript.html

+4

Рассмотрите возможность улучшения своего сообщения, так как ваш ответ по существу является ссылкой. См.: [Являются ли ответы, которые содержат только ссылки в других местах «хорошие ответы»?] (Http://meta.stackexchange.com/q/8231/156620) и [Почему ссылка плохо?] (Http: //meta.stackexchange .com/д/7515/156620) – 2011-07-04 07:35:56

1

Расширяя user187291's post, вы также можете использовать геттеры/сеттеры, чтобы обойти того, чтобы использовать функции.

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' 
Смежные вопросы