javascript 中有指针吗?

Are there pointers in javascript?

提问人:Dylan Vander Berg 提问时间:6/30/2013 最后编辑:Dylan Vander Berg 更新时间:11/13/2023 访问量:133509

问:

我以前使用过 C++,我意识到指针非常有用。javascript 中有什么东西可以充当指针吗?javascript 有指针吗?当我想使用类似的东西时,我喜欢使用指针:

var a = 1;
var b = "a";
document.getElementById(/* value pointed by b */).innerHTML="Pointers";

我知道这是一个非常简单的例子,我可以只使用 ,但有几个更复杂的例子,我会发现指针非常有用。有什么想法吗?a

JavaScript 指针

评论

6赞 Ry- 6/30/2013
嗯......通常不需要指针。你能举一个更真实的例子来说明你遇到的一个案例,指针会有所帮助吗?
0赞 Dan Dascalescu 9/14/2016
JavaScript 中指针的可能重复?
0赞 EzioMercer 10/12/2023
@Ry- 老实说,我来这里是为了找到一种像 C :) 一样编写函数的方法swap
0赞 Ry- 10/13/2023
@EzioMercer:JS中的成语是解构:[a, b] = [b, a];
0赞 EzioMercer 10/15/2023
@Ry- 如果 和 是引用:)我的意思是你不能在另一个函数中交换基元(例如数字)的值,但你可以在 C 中使用指针轻松完成ab

答:

125赞 Alnitak 6/30/2013 #1

不,JS 没有指针。

通过传递引用的副本来传递对象。程序员无法访问任何表示对象地址的类似 C 的“值”。

在函数中,可以通过该引用更改传递对象的内容,但不能修改调用方的引用,因为引用只是一个副本:

var foo = {'bar': 1};

function tryToMungeReference(obj) {
    obj = {'bar': 2};  // won't change caller's object
}

function mungeContents(obj) {
    obj.bar = 2;       // changes _contents_ of caller's object
}

tryToMungeReference(foo);
foo.bar === 1;   // true - foo still references original object

mungeContents(foo);
foo.bar === 2;  // true - object referenced by foo has been modified

评论

1赞 Dylan Vander Berg 6/30/2013
什么是参考文献的副本,它可以像指针一样使用吗,我该如何使用它?
3赞 Mataniko 6/30/2013
引用是对象的名称,copy 基本上是指向同一地址的新名称
0赞 Alnitak 6/30/2013
@user2297366它只是表示对象内容的占位符,而不是对对象本身的引用。
0赞 Frank 2/4/2021
“引用副本”占用多少内存?它基本上只是在哪里找到实际对象的地址,还是从字面上分配内存中的另一个空间来将对象复制到其中?
3赞 Aeternus 4/25/2023
即使对象是通过传递引用的副本来传递的,它是否仍被视为指针?从我们可以直接访问它的意义上讲,它不是一个指针,而是一个指针,因为它是对对象的内存位置的引用,JavaScript 确实有。也许改写第一句话的更好方法是“不,JS 没有指针”,也许是“不,JS 没有类似 C 的指针”。因为从技术上讲,对象仍然是 JS 中的指针。那么函数指针/引用呢?
63赞 user3015682 5/12/2015 #2

你敢打赌 JavaScript 中有指针;对象是指针。

//this will make object1 point to the memory location that object2 is pointing at
object1 = object2;

//this will make object2 point to the memory location that object1 is pointing at 
function myfunc(object2){}
myfunc(object1);

如果不再指向内存位置,则那里的数据将丢失。

与 C 不同,您看不到指针的实际地址,也看不到指针的实际值,您只能取消引用它(获取它指向的地址处的值)。

评论

0赞 Tyler 5/28/2019
第一部分 100% 工作。var object1 仅指向 object2。如果我们更改 object1,则 object2 实际上会更改。当我们检查 object1 的内容时,直接更改 object2 也可以很好地显示出来。它将显示 object1 也发生了变化,因为它指向内存中的相同数据。我已经测试过了。我不明白第二部分,但没关系。
1赞 user3015682 5/29/2019
Javascript 将对象传递给函数有点有趣。如果函数一次更改对象的一个成员,则通过引用传递该函数。但是,如果尝试使用大括号完全更改对象,则它似乎是按值传递的。我猜这是因为当您执行 = {...} 时,Javascript 会自动认为您正在创建一个新对象,基本上是创建一个恰好与参数同名的局部变量。
1赞 Tyler 5/30/2019
正如您明确所说,这实际上与创建新对象无关。我了解到这是关于始终传递引用:当您执行 objX = {..} 时,您实际上将引用传递给新创建的对象。当您执行 objX = objY 时,您将引用传递给已经存在的 objY 对象。但是 = 实际上总是传递赋值运算符右侧对象所在的地址(不管它是新创建的还是已经存在的 - 赋值运算符的右侧首先解析)。
0赞 user3015682 5/31/2019
好点子!经过一些测试,我学到了更多,它实际上总是通过引用传递,只是要注意不要更改它的地址。
6赞 Aleksandr Hovhannisyan 2/6/2020
@user3015682 不,JavaScript 是按值传递的,而不是按引用传递的。JavaScript 在引擎盖下确实有“指针”。指针只是存储对象地址的变量。它们是按值传递的。因此,您可以修改指向的对象,但不能通过将对象传递给函数来强制该对象指向其他内容。
1赞 Eggon 2/17/2022
这些充其量只是伪指针。您不能将它们用作对象的键,这将非常有用。
1赞 tweekz 8/11/2022
许多人似乎混淆了指针和引用的概念。引用只是同一内存地址的别名。指针是保存实际对象的内存地址(或某些类似标识符)的变量。即使无法显式访问指针中存储的地址/标识符,也不意味着它们不是指针。
-8赞 Sam Araiza 5/28/2016 #3

从技术上讲,JS 没有指针,但我发现了一种模仿它们行为的方法;)

var car = {
    make: 'Tesla',
    nav: {
       lat: undefined,
       lng: undefined
    }
};

var coords: {
    center: {
       get lat() { return car.nav.lat; }, // pointer LOL
       get lng() { return car.nav.lng; }  // pointer LOL
    }   
};

car.nav.lat = 555;
car.nav.lng = 777;

console.log('*** coords: ', coords.center.lat); // 555
console.log('*** coords: ', coords.center.lng); // 777

评论

8赞 Dimitri L. 9/12/2017
您只需返回 .它与指针或模仿无关,被称为carscope
1赞 RickyA 12/23/2019
从技术上讲,JS 只不过是指针。但是,您只能取消引用它们,而不能操作指针本身。
3赞 Toshiro99 6/14/2019 #4

由于 JS 的性质是按值(如果引用对象完全更改)或引用(如果引用对象的字段更改)传递对象,因此不可能完全替换引用对象。

但是,让我们使用可用的内容:替换引用对象的单个字段。通过这样做,以下功能可以实现您的要求:

function replaceReferencedObj(refObj, newObj) {
    let keysR = Object.keys(refObj);
    let keysN = Object.keys(newObj);
    for (let i = 0; i < keysR.length; i++) {
        delete refObj[keysR[i]];
    }
    for (let i = 0; i < keysN.length; i++) {
        refObj[keysN[i]] = newObj[keysN[i]];
    }
}

对于 user3015682 给出的示例,您将按如下方式使用此函数:

replaceReferencedObj(foo, {'bar': 2})
6赞 Timur Baysal 4/8/2021 #5

我刚刚做了一件奇怪的事情,也成功了。

不要传递指针,而是将填充其参数的函数传递到目标变量中。

var myTarget;

class dial{
  constructor(target){
    this.target = target;
    this.target(99);
  }
}
var myDial = new dial((v)=>{myTarget = v;});

这可能看起来有点邪恶,但效果很好。在这个例子中,我创建了一个通用的刻度盘,可以用这个小函数“(v)=>{target = v}”的形式为它分配任何目标。不知道它在性能方面会有多好,但它表现得很漂亮。

0赞 octo 5/12/2022 #6

按引用和数组分配。

let pizza = [4,4,4];
let kebab = pizza;  // both variables are references to shared value
kebab.push(4);
console.log(kebab); //[4,4,4,4]
console.log(pizza); //[4,4,4,4]

由于未修改原始值,因此不会创建新引用。

kebab = [6,6,6,6];  // value is reassigned
console.log(kebab); //[6,6,6,6]
console.log(pizza); //[4,4,4,4]

重新赋值变量中的复合值时,将创建一个新的引用。

0赞 Adioz Daniel 11/13/2023 #7

是的,事实上,所有对象和数组都是指针。 如果我必须从字面上理解您的示例,那么,您只需要将变量转换为对象类型,例如

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pointers</title>
</head>
<body>
    <h1>Asynchronous JavaScript</h1>

<!--the pointer with class b--->
    <p>Our City</p>
    <p id="variableA" >Minnesota</p>

    <script src="pointers.js" ></script>
</body>
</html>

然后指针.js

var a = {name: "todos", data: {pointerOne: 'Minnesota', pointerTwo: 'NewYork'}};
var b = a;//pointer to a

setTimeout(()=>{
//using timeout to see our pointer at work!

b.data.pointerOne = 'Nairobi';
document.getElementById('variableA').innerHTML = a.data.pointerOne;

}, 3000);

JavaScript 的主要区别在于指针的实际呈现方式或缺乏识别指针的直接方法。在 C 中,Golang 和 C# 指针是使用“&”运算符创建的。

这是最基本的。获得这个概念后,您现在可以将其进一步开发为函数指针、链表,或者像结构体一样使用它;并以 C++ 的方式执行 JavaScript。 尽管我建议您在命名变量时使用当前的 JavaScript 约定。 即

const a = {name: "todos", data: {pointerOne: 'Minnesota', pointerTwo: 'NewYork'}};
const b = a;//pointer to a