13 ответов:
поскольку JavaScript не поддерживает передачу параметров по ссылке, вам нужно будет сделать переменную объектом вместо этого:
var x = {Value: 0}; function a(obj) { obj.Value++; } a(x); document.write(x.Value); //Here i want to have 1 instead of 0в этом случае
x- это ссылка на объект. Когдаxпередается в функциюa, эта ссылка копируется вobj. Таким образом,objиxсм. то же самое в памяти. ИзменениеValueсобственностьobjвлияетValueсобственностьx.Javascript всегда будет передавать параметры функции по значению. Это просто спецификация языка. Ты может создать
xв области, локальной для обеих функций, и не передавать переменную вообще.
этот вопрос может помочь: Как передать переменную по ссылке в JavaScript? Чтение данных из функции ActiveX, которая возвращает более одного значения
подводя итог, примитивные типы Javascript всегда передаются по значению, тогда как значения внутри объектов передаются по ссылке (спасибо комментаторам за указание на мой надзор). Поэтому, чтобы обойти это, вы должны поместить свое целое число внутри объекта:
var myobj = {x:0}; function a(obj) { obj.x++; } a(myobj); alert(myobj.x); // returns 1
Я нашел немного другой способ реализации указателей, который, возможно, более общий и более понятный с точки зрения C (и, таким образом, больше вписывается в формат примера пользователей).
в JavaScript, как и в C, переменные массива на самом деле являются просто указателями на массив, поэтому вы можете использовать массив точно так же, как объявление указателя. Таким образом, все указатели в коде могут использоваться одинаково, несмотря на то, что вы назвали переменную в оригинале объект.
Он также позволяет использовать две разные обозначения, относящиеся к адресу указателя и тому, что находится по адресу указателя.
вот пример (я использую подчеркивание для обозначения указатель):
var _x = [ 10 ]; function foo(_a){ _a[0] += 10; } foo(_x); console.log(_x[0]);доходность
output: 20
вы ссылаетесь на' x ' из объекта окна
var x = 0; function a(key, ref) { ref = ref || window; // object reference - default window ref[key]++; } a('x'); // string alert(x);
поздний ответ, но я наткнулся на способ передачи примитивных значений по ссылке с помощью закрытия. Создать указатель довольно сложно, но он работает.
function ptr(get, set) { return { get: get, set: set }; } function helloWorld(namePtr) { console.log(namePtr.get()); namePtr.set('jack'); console.log(namePtr.get()) } var myName = 'joe'; var myNamePtr = ptr( function () { return myName; }, function (value) { myName = value; } ); helloWorld(myNamePtr); // joe, jack console.log(myName); // jackв ES6 код можно сократить, чтобы использовать лямбда-выражения:
var myName = 'joe'; var myNamePtr = ptr(=> myName, v => myName = v); helloWorld(myNamePtr); // joe, jack console.log(myName); // jack
в JavaScript это будет глобальный. Однако, ваша функция будет выглядеть примерно так:
function a(){ x++; };С
xнаходится в глобальном контексте, вам не нужно передавать его в функцию.
Javascript должен просто помещать указатели в микс, потому что он решает много проблем. Это означает, что код может ссылаться на неизвестное имя переменной или переменные, которые были созданы динамически. Это также делает модульное кодирование и инъекции легко.
это то, что я вижу, как ближе всего вы можете прийти к указателям c на практике
в js:
var a = 78; // creates a var with integer value of 78 var pointer = 'a' // note it is a string representation of the var name eval (pointer + ' = 12'); // equivalent to: eval ('a = 12'); but changes value of a to 12в c:
int a = 78; // creates a var with integer value of 78 int pointer = &a; // makes pointer to refer to the same address mem as a *pointer = 12; // changes the value of a to 12
это может быть невозможно, так как JavaScript не имеет оператора Perl "\" для получения примитива по ссылке, но есть способ создать объект "эффективно указатель" для примитива, используя этот шаблон.
Это решение имеет наибольший смысл, когда у вас уже есть примитив(поэтому вы больше не можете поместить его в объект без необходимости изменять другой код), но все равно нужно передать указатель на него для других частей вашего кода, чтобы возиться с его состоянием; поэтому вы можете все еще возиться с его состоянием, используя бесшовный прокси, который ведет себя как указатель.
var proxyContainer = {}; // | attaches a pointer-lookalike getter/setter pair // | to the container object. var connect = function(container) { // | primitive, can't create a reference to it anymore var cant_touch_this = 1337; // | we know where to bind our accessor/mutator // | so we can bind the pair to effectively behave // | like a pointer in most common use cases. Object.defineProperty(container, 'cant_touch_this', { 'get': function() { return cant_touch_this; }, 'set': function(val) { cant_touch_this = val; } }); }; // | not quite direct, but still "touchable" var f = function(x) { x.cant_touch_this += 1; }; connect(proxyContainer); // | looks like we're just getting cant_touch_this // | but we're actually calling the accessor. console.log(proxyContainer.cant_touch_this); // | looks like we're touching cant_touch_this // | but we're actually calling the mutator. proxyContainer.cant_touch_this = 90; // | looks like we touched cant_touch_this // | but we actually called a mutator which touched it for us. console.log(proxyContainer.cant_touch_this); f(proxyContainer); // | we kinda did it! :) console.log(proxyContainer.cant_touch_this);
в JavaScript нельзя передавать переменные по ссылке на функцию. Однако вы можете передать объект по ссылке.
Я думаю, что в отличие от C или любого языка с указателями:
/** Javascript **/ var o = {x:10,y:20}; var o2 = {z:50,w:200};
- очевидно javascript вы не можете получить доступ к объектам o и o2адреса в
- но ты не можешь сравнить их адрес ни : (нет банальной возможности вроде их, а затем доступ дихотомия)
.
o == o2 // obviously false : not the same address in memory o <= o2 // true ! o >= o2 // also true !!это огромная проблема :
это означает, что вы можете перечислять/управлять всеми объектами, созданными (выделенными) вашим приложением,
от этого огромный список объектов, вычислить некоторую информацию о них (как они связаны друг с другом например)
но когда вы хотите получить информацию, которую вы создали о конкретный объект, вы не можете найти его в своем огромный список по дихотомии: нет уникальный идентификатор для каждого объекта это может быть использовано в качестве замены реального адреса памяти
это, наконец, означает, что это огромная проблема, если вы хотите написать в javascript :
- a javascript debugger / IDE
- или специально оптимизированный сборщик мусора
- a структура данных ящик / анализатор
JavaScript не поддерживает передачу примитивных типов по ссылке. Однако есть обходной путь.
Поместите все переменные, которые вам нужно передать в объект. В этом случае, есть только одна переменная,
x. Вместо передачи переменной, передайте имя переменной в виде строки, которая является"x".var variables = {x:0}; function a(x) { variables[x]++; } a("x"); alert(variables.x);
в зависимости от того, что вы хотели бы сделать, вы можете просто сохранить имя переменной, а затем получить к нему доступ позже следующим образом:
function toAccessMyVariable(variableName){ alert(window[variableName]); } var myFavoriteNumber = 6; toAccessMyVariable("myFavoriteNumber");чтобы применить к вашему конкретному примеру, вы можете сделать что-то вроде этого:
var x = 0; var pointerToX = "x"; function a(variableName) { window[variableName]++; } a(pointerToX); alert(x); //Here I want to have 1 instead of 0
в вашем примере у вас на самом деле есть 2 переменные с одинаковым именем. (Глобальная) переменная x и
Comments