有没有更好的方法来模拟 JavaScript 中的指针?

Aad*_*hah 3 javascript closures pointers simulate dynamic-scope

我使用动态作用域来模拟JavaScript 中的指针,如下所示

var ptr = (function () {
    var ptr = "(" + String(function (value) {
    if (value === void 0) return upvalue;
    else upvalue = value;
}) + ")";

    return function (upvalue) {
        return ptr.replace(/upvalue/g, upvalue);
    };
}());

function swap(xptr, yptr) {
    var t = xptr();
    xptr(yptr());
    yptr(t);
}

var x = 2;
var y = 3;

alert([x, y]);
swap(eval(ptr("x")), eval(ptr("y")));
alert([x, y]);
Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以达到相同的结果(即不诉诸eval)?这似乎是太多的样板文件。

Ray*_*hen 5

由于您使用指针的唯一目的是取消引用它以访问另一个变量,因此您可以将其封装在属性中。

function createPointer(read, write) {
  return { get value() { return read(); }, set value(v) { return write(v); } };
}
Run Code Online (Sandbox Code Playgroud)

要创建指针,请传递读取和写入所指向的变量的访问器方法。

var i;
var p = createPointer(function() { return i; }, function(v) { i = v; });
// p is now a "pointer" to i
Run Code Online (Sandbox Code Playgroud)

要取消引用指针,请访问其值。换句话说,在 C 语言中,您可以*p在此处编写p.value.

i = "initial";
alert(p.value); // alerts "initial"
p.value = "update";
alert(i); // alerts "update"
p.value += "2";
alert(i); // alerts "update2"
Run Code Online (Sandbox Code Playgroud)

您可以创建多个指向同一变量的指针。

var q = createPointer(function() { return i; }, function(v) { i = v; });
// q is also a "pointer" to i
alert(q.value); // alerts "update2"
q.value = "written from q";
alert(p.value); // alerts "written from q"
Run Code Online (Sandbox Code Playgroud)

您可以通过简单地用另一个指针覆盖指针变量来更改指针指向的内容。

var j = "other";
q = createPointer(function() { return j; }, function(v) { j = v; });
// q is now a "pointer" to j
Run Code Online (Sandbox Code Playgroud)

您可以通过指针交换两个变量。

function swap(x, y) {
    var t = x.value;
    x.value = y.value;
    y.value = t;
}
Run Code Online (Sandbox Code Playgroud)

让我们使用它们的指针交换i和的值。j

swap(p, q);
alert(i); // alerts "other"
alert(j); // alerts "written from q"
Run Code Online (Sandbox Code Playgroud)

您可以创建指向局部变量的指针。

function example() {
    var myVar = "myVar as local variable from example";
    var r = createPointer(function() { return myVar; }, function(v) { myVar = v; });
    swap(p,r);
    alert(i); // alerts "myVar as local variable from example"
    alert(myVar); // alerts "other"
}
example();
Run Code Online (Sandbox Code Playgroud)

通过闭包的魔力,这为您提供了一种模拟 malloc 的方法。

function malloc() {
    var i;
    return createPointer(function() { return i; }, function(v) { i = v; });
}
var p = malloc(); // p points to a variable we just allocated from the heap
p.value = 2; // write a 2 into it
Run Code Online (Sandbox Code Playgroud)

你的魔术也有效:

var flowers = new Misdirection(
       createPointer(function() { return flowers; }, function(v) { flowers = v; }));
flowers.abracadabra();
alert(flowers);

function Misdirection(flowers) {
    this.abracadabra = function() {
        flowers.value = new Rabbit;
    };
}

function Rabbit() {
    this.toString = function() { return "Eh... what's up doc?" };
}
Run Code Online (Sandbox Code Playgroud)