JavaScript 中的指针?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10231868/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 00:25:01  来源:igfitidea点击:

Pointers in JavaScript?

javascript

提问by user1342369

Can we pass a reference of a variable that is immutable as argument in a function?

我们可以将不可变变量的引用作为函数中的参数传递吗?

Example:

例子:

var x = 0;
function a(x)
{
    x++;
}
a(x);
alert(x); //Here I want to have 1 instead of 0

回答by Mike Christensen

Since JavaScript does not support passing parameters by reference, you'll need to make the variable an object instead:

由于 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

In this case, xis a reference to an object. When xis passed to the function a, that reference is copied over to obj. Thus, objand xrefer to the same thing in memory. Changing the Valueproperty of objaffects the Valueproperty of x.

在这种情况下,x是对对象的引用。当x传递给函数时a,该引用被复制到obj. 因此,objx指内存中相同的东西。更改 的Value属性obj会影响 的Value属性x

Javascript will always pass function parameters by value. That's simply a specification of the language. You couldcreate xin a scope local to both functions, and not pass the variable at all.

Javascript 将始终按值传递函数参数。这只是语言的规范。您可以x在两个函数的本地范围内创建,而根本不传递变量。

回答by n00dle

This question may help: How to pass variable by reference in javascript? Read data from ActiveX function which returns more than one value

这个问题可能有帮助: How to pass variable by reference in javascript? 从返回多个值的 ActiveX 函数读取数据

To summarise, Javascript primitive types are always passed by value, whereas the values inside objects are passed by reference (thanks to commenters for pointing out my oversight). So to get round this, you have to put your integer inside an object:

总而言之,Javascript 原始类型总是按值传递,而对象内部的值是按引用传递的(感谢评论者指出我的疏忽)。所以为了解决这个问题,你必须把你的整数放在一个对象中:

var myobj = {x:0};

function a(obj)
{
    obj.x++;
}

a(myobj);
alert(myobj.x); // returns 1

  

回答by William Oliver

I have found a slightly different way implement pointers that is perhaps more general and easier to understand from a C perspective (and thus fits more into the format of the users example).

我发现了一种稍微不同的实现指针的方式,从 C 的角度来看,它可能更通用且更容易理解(因此更适合用户示例的格式)。

In JavaScript, like in C, array variables are actually just pointers to the array, so you can use an array as exactly the same as declaring a pointer. This way, all pointers in your code can be used the same way, despite what you named the variable in the original object.

在 JavaScript 中,就像在 C 中一样,数组变量实际上只是指向数组的指针,因此您可以像声明指针一样使用数组。这样,您代码中的所有指针都可以以相同的方式使用,而不管您在原始对象中为变量命名了什么。

It also allows one to use two different notations referring to the address of the pointer and what is at the address of the pointer.

它还允许使用两种不同的符号来表示指针地址和指针地址处的内容。

Here is an example (I use the underscore to denote a pointer):

这是一个示例(我使用下划线表示指针):

var _x = [ 10 ];

function foo(_a){
    _a[0] += 10;
}

foo(_x);

console.log(_x[0]);

Yields

产量

output: 20

回答by AlexisK

You refer to 'x' from window object

您从 window 对象引用“x”

var x = 0;

function a(key, ref) {
    ref = ref || window;  // object reference - default window
    ref[key]++;
}

a('x');                   // string
alert(x);

回答by Himanshu

Late answer but I have come across a way of passing primitive values by reference by means of closures. It is rather complicated to create a pointer, but it works.

迟到的答案,但我遇到了一种通过闭包通过引用传递原始值的方法。创建指针相当复杂,但它有效。

function ptr(get, set) {
    return { get: get, set: set };
}

function helloWorld(namePtr) {
    console.log(namePtr.get());
    namePtr.set('Hyman');
    console.log(namePtr.get())
}

var myName = 'joe';
var myNamePtr = ptr(
    function () { return myName; },
    function (value) { myName = value; }
);

helloWorld(myNamePtr); // joe, Hyman
console.log(myName); // Hyman

In ES6, the code can be shortened to use lambda expressions:

在 ES6 中,可以缩短代码以使用 lambda 表达式:

var myName = 'joe';
var myNamePtr = ptr(=> myName, v => myName = v);

helloWorld(myNamePtr); // joe, Hyman
console.log(myName); // Hyman

回答by Maess

In JavaScript that would be a global. However, your function would look more like this:

在 JavaScript 中,这将是一个全局变量。但是,您的函数看起来更像这样:

function a(){
   x++;
};

Since xis in the global context, you don't need to pass it into the function.

由于x是在全局上下文中,您不需要将其传递到函数中。

回答by Dmitry

It might be impossible since JavaScript doesn't have Perl's "\" operator to get a primitive by reference, but there is a way to create an "effectively a pointer" object for a primitive using this pattern.

这可能是不可能的,因为 JavaScript 没有 Perl 的“\”运算符来通过引用获取原语,但是有一种方法可以使用这种模式为原语创建一个“有效的指针”对象。

This solution makes the most sense for when you already have the primitive(so you can't put it into an object anymore without needing to modify other code), but still need to pass a pointer to it for other parts of your code to tinker with its state; so you can still tinker with its state using the seamless proxy which behaves like a pointer.

当您已经拥有原语(因此您不能再将其放入对象而无需修改其他代码)时,此解决方案最有意义,但仍然需要将指向它的指针传递给代码的其他部分以进行修补与其状态;所以你仍然可以使用无缝代理修改它的状态,它的行为就像一个指针。

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);

回答by Emmanuel Mahuni

Javascript should just put pointers into the mix coz it solves a lot of problems. It means code can refer to an unknown variable name or variables that were created dynamically. It also makes modular coding and injection easy.

Javascript 应该只是将指针放入混合中,因为它解决了很多问题。这意味着代码可以引用一个未知的变量名或动态创建的变量。它还使模块化编码和注入变得容易。

This is what i see as the closest you can come to c pointers in practice

这是我认为在实践中最接近 c 指针的地方

in js:

在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

in c:

在 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

回答by clickbait

JavaScript doesn't support passing primitive types by reference. There is a workaround, though.

JavaScript 不支持通过引用传递原始类型。不过,有一个解决方法。

Put all the variables you need to pass in an object. In this case, there's only one variable, x. Instead of passing the variable, pass the variable name as a string, which is "x".

将所有需要传递的变量放入一个对象中。在这种情况下,只有一个变量,x。不是传递变量,而是将变量名称作为字符串传递,即"x".

var variables = {x:0};
function a(x)
{
    variables[x]++;
}
a("x");
alert(variables.x);

回答by reuns

I'm thinking that in contrary to C or any language with pointers :

我认为与 C 或任何带有指针的语言相反:

/** Javascript **/
var o = {x:10,y:20};
var o2 = {z:50,w:200};
  • obviously in javascriptyou cannot access to objects oand o2addresses in memory
  • but you can't comparetheir address neither : (no trivial possibility to sortthem, and then access by dichotomy)
  • 显然在javascript 中你不能访问内存中的对象oo2地址
  • 但你也不能比较他们的地址:(不可能它们进行排序,然后通过二分法访问)

.

.

o == o2 // obviously false : not the same address in memory
o <= o2 // true !
o >= o2 // also true !!

that's a huge problem :

这是一个巨大的问题:

  • it means that you can list/manage every objects created (allocated) by your application,

  • from that huge listof objects, compute some information about these (how they are linked together for example)

  • but when you want to retrieve the information you created about a specific object, you cannot find it in your huge listby dichotomy : there is no unique identifier per objectthat could be used as a replacement of the real memory address

  • 这意味着您可以列出/管理应用程序创建(分配)的每个对象,

  • 庞大的对象列表中,计算有关这些对象的一些信息(例如,它们如何链接在一起)

  • 但是当你想检索你创建的关于特定对象的信息时,你无法通过二分法在庞大的列表中找到它:每个对象没有唯一的标识符可以用作真实内存地址的替换

this finally means that this is a huge problem, if you want to write in javascript :

这最终意味着这是一个巨大的问题,如果你想用 javascript 编写:

  • a javascript debugger / IDE
  • or a specially optimized garbage collector
  • a data structure drawer / analyzer
  • 一个JavaScript 调试器/IDE
  • 专门优化的垃圾收集器
  • 一个数据结构抽屉/分析器