JavaScript中的指针?
我们是否可以传递一个变量的引用,该变量作为函数中的参数是不可变的 例如:JavaScript中的指针?,javascript,Javascript,我们是否可以传递一个变量的引用,该变量作为函数中的参数是不可变的 例如: var x = 0; function a(x) { x++; } a(x); alert(x); //Here I want to have 1 instead of 0 这个问题可能有助于: 总而言之,Javascript原语类型总是通过值传递,而对象中的值是通过引用传递的(感谢注释者指出我的疏忽)。因此,要解决这个问题,必须将整数放入对象中: var myobj={x:0}; 功能a(obj) { obj
var x = 0;
function a(x)
{
x++;
}
a(x);
alert(x); //Here I want to have 1 instead of 0
这个问题可能有助于:
总而言之,Javascript原语类型总是通过值传递,而对象中的值是通过引用传递的(感谢注释者指出我的疏忽)。因此,要解决这个问题,必须将整数放入对象中:
var myobj={x:0};
功能a(obj)
{
obj.x++;
}
a(myobj);
警报(myobj.x);//返回1
在JavaScript中,这将是一个全球性的问题。但是,您的函数看起来更像这样:
function a(){
x++;
};
由于
x
处于全局上下文中,因此不需要将其传递到函数中。由于JavaScript不支持通过引用传递参数,因此需要将变量改为对象:
var x={Value:0};
功能a(obj)
{
对象值++;
}
a(x);
文件。写入(x.Value)//在这里,我希望在JavaScript中使用1而不是0,您不能通过引用函数来传递变量。但是,您可以通过引用传递对象。我发现了一种稍微不同的实现指针的方法,从C的角度来看,这种方法可能更通用、更容易理解(因此更适合用户示例的格式)
在JavaScript中,就像在C中一样,数组变量实际上只是指向数组的指针,因此可以使用与声明指针完全相同的数组。这样,代码中的所有指针都可以以相同的方式使用,不管您在原始对象中如何命名变量
它还允许使用两种不同的符号来表示指针的地址和指针的地址
下面是一个示例(我使用下划线表示指针):
屈服
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中,可以缩短代码以使用lambda表达式:
var myName = 'joe';
var myNamePtr = ptr(=> myName, v => myName = v);
helloWorld(myNamePtr); // joe, jack
console.log(myName); // jack
在您的示例中,实际上有两个同名的变量。(全局)变量x和函数的作用域为变量x。有趣的是,javascript在选择如何处理两个同名变量时,会使用函数作用域名称,并忽略作用域外变量
假设javascript总是以这种方式运行可能是不安全的
干杯 我认为与C或任何带指针的语言相反:
/** Javascript **/
var o = {x:10,y:20};
var o2 = {z:50,w:200};
- 显然,在javascript中,您无法访问内存中的对象o和o2地址
- 但是你也不能比较他们的地址:(对他们进行排序,然后通过二分法访问,这是不可能的。)
o==o2//明显错误:内存中的地址不同
o=o2//同样正确!!
这是一个巨大的问题:
- 这意味着您可以列出/管理应用程序创建(分配)的每个对象
- 从庞大的对象列表中,计算有关这些对象的一些信息(例如,它们是如何链接在一起的)
- 但是,当您想要检索您创建的关于特定对象的信息时,您无法通过二分法在庞大的列表中找到它:每个对象都没有唯一标识符可以用来替换实际内存地址
这最后意味着,如果您想用javascript编写,这是一个巨大的问题:
- javascript调试器/IDE
- 或者一个特别优化的垃圾收集器
- a数据结构抽屉/分析器
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中:
JavaScript不支持通过引用传递基元类型。不过,还有一个解决办法
将需要传递的所有变量放入对象中。在本例中,只有一个变量,x
。不要传递变量,而是将变量名作为字符串传递,即“x”
var变量={x:0};
函数a(x)
{
变量[x]++;
}
a(“x”);
警报(variables.x)代码>这可能是不可能的,因为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);
根据您希望执行的操作,您可以简单地保存变量名,然后稍后访问它,如下所示:
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
它只是不支持指针,故事的结尾:-(
我想补充一点,虽然我是全新的,来自C语言背景,但从我读到的关于事件循环和堆栈的内容来看,你应该让任何对象尽可能靠近它的调用者。因为我是全新的,我可能有这个错误
这里的许多答案都建议将其设置为全局,但如果我阅读正确,这可能会增加堆栈跳数,并且在某种程度上可能会不必要地分割事件循环(取决于调用的对象当前正在执行的操作)
还有,给出的任何例子
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);
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