在JavaScript中的指针?
我们可以传递一个variables的引用,这个variables在函数中作为参数是不可变的吗?
例:
var x = 0; function a(x) { x++; } a(x); alert(x); //Here I want to have 1 instead of 0
由于JavaScript不支持通过引用传递参数,因此您需要将该variables作为对象:
var x = {Value: 0}; function a(obj) { obj.Value++; } a(x); document.write(x.Value); //Here i want to have 1 instead of 0
这个问题可能会帮助: 如何在JavaScript中通过引用传递variables? 从ActiveX函数中读取数据返回多个值
总而言之,Javascript原始types总是按值传递,而对象内部的值是通过引用传递的(感谢评论者指出我的疏忽)。 所以为了解决这个问题,你必须把你的整数放入一个对象中:
var myobj = {x:0}; function a(obj) { obj.x++; } a(myobj); alert(myobj.x); // returns 1
我发现了一个稍微不同的方法来实现指针,这个指针从C的angular度来看可能更为一般,也更容易理解(因此更适合用户的例子)。
在JavaScript中,就像在C中一样,数组variables实际上只是指向数组的指针,所以可以像声明一个指针一样使用数组。 这样,尽pipe在原始对象中命名了variables,但代码中的所有指针都可以以相同的方式使用。
它还允许使用两个不同的符号来指向指针的地址和指针的地址。
这里是一个例子(我用下划线来表示一个指针):
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);
迟到的答案,但我已经遇到了通过引用通过closures传递原始值的方式。 创build一个指针是相当复杂的,但它的工作原理。
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中,代码可以缩短为使用lambdaexpression式:
var myName = 'joe'; var myNamePtr = ptr(=> myName, v => myName = v); helloWorld(myNamePtr); // joe, jack console.log(myName); // jack
在JavaScript中,这将是一个全球性的。 但是,你的函数看起来更像这样:
function a(){ x++; };
由于x
在全局上下文中,所以不需要将它传递给函数。
JavaScript应该只是把指针混入因为它解决了很多问题。 这意味着代码可以引用一个未知的variables名或dynamic创build的variables。 这也使得模块化编码和注射变得容易。
这就是我所看到的最接近实践的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的“\”操作符来通过引用来获取原语,但是有一种方法可以为使用这种模式的原语创build“有效的指针”对象。
这个解决scheme对于什么时候已经有了原语是最有意义的(所以你不能把它放到一个对象中而不需要修改其他的代码),但是仍然需要传递一个指针给你的代码的其他部分去修补与它的状态; 所以你仍然可以用它的行为像一个指针的无缝代理修补它的状态。
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中,你不能通过引用一个函数来传递variables。 但是,您可以通过引用来传递对象。
我在想,与C或任何带有指针的语言相反:
/** Javascript **/ var o = {x:10,y:20}; var o2 = {z:50,w:200};
- 显然在javascript中你不能访问内存中的对象o和o2 地址
- 但是你不能把他们的地址比较 :( sorting他们的可能性不大,然后通过二分法来访问)
。
o == o2 // obviously false : not the same address in memory o <= o2 // true ! o >= o2 // also true !!
这是一个巨大的问题:
-
这意味着您可以列出/pipe理您的应用程序创build(分配)的每个对象,
-
从庞大的对象列表中,计算一些关于这些对象的信息(例如,它们如何链接在一起)
-
但是当你想检索你创build的关于一个特定对象的信息时,你不能通过二分法在你的巨大列表中find它: 每个对象没有唯一的标识符来代替实际的内存地址
这最后意味着这是一个巨大的问题,如果你想在javascript中写:
- 一个JavaScriptdebugging器/ IDE
- 或特别优化的垃圾收集器
- 一个数据结构抽屉/分析器
JavaScript不支持通过引用传递基元types。 有一个解决方法,虽然。
把所有需要传递给对象的variables。 在这种情况下,只有一个variablesx
。 而不是传递variables,传递variables名称作为string,这是"x"
。
var variables = {x:0}; function a(x) { variables[x]++; } a("x"); alert(variables.x);
取决于你想要做什么,你可以简单地保存variables名,然后再访问它,就像这样:
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
在你的例子中,你实际上有两个同名的variables。 (全局)variablesx和函数作用域variablesx。 有趣的是,看到这个javascript,当给出与2个相同名称的variables相关的select时,使用函数作用域名称并忽略超出范围的variables。
这可能是不安全的,认为JavaScript总是会这样…
干杯!