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