一篇思考文,关于JS的reference和Go的指针。(臆想型论文?)

最近投入大量时间接触Golang,了解“指针”的时候,想起了以前学习C语言时对“指针”的疑问:指针是什么。

以前还小不理解指针和野指针,只知道野指针会出现内存溢出或者值不正确的情况。而且网上大多讲指针的文章看起来都很难。就像现在的知乎:一句话能说清楚的东西恨不得从它的诞生还是写起。就连LOL赛评也是这副P样。

以至于我后面对C语言没好感,对C++厌恶,对有“指针”的语言直接没兴趣。

在看到Go的指针的时候,我已经想放弃了。但是想回来,毕竟上一次接触指针已经6年了,也许现在看就能理解出什么呢。(过程中接触的OC根本不能算经验,因为当时完全就是靠抄靠背来写iOS应用,最后还是嫌弃OC麻烦进阶无法理解去学习了swift)

Reference == Pointer?

以前看到什么内存地址啊,指向啊就已经乱了,满脑子都在想内存里面是什么样的,内存地址,寄存器又是什么东西。跟着官方教程走了一遍,了解到指针就是通过一个变量去指向一个有的变量或者说是对象,从而产生一种绑定。通过修改指针变量也可以达到修改本体的效果

这让我想到JS,因为每天都在操作对象,知道:如果你要建立一个新的变量,比如a = 1,我可以通过var b = a得到一个新的变量。但是如果是对象则不是。如果是a = {}; var b = a的话,b只是单纯指向了a,并没有复制a

所以我立刻去搜索关于JavaScript的指针。得到这么一个结果 JavaScript 的指针是什么? - 知乎

JavaScript 里头什么时候有指针的概念?倒是有 reference (引用)的说法。 —— 陈木野

关于this的总结,不单我自己,网络上已经大量的文章了。不管是详细解析,还是总结,都已经很多了。但是如果说:指针就是一种指向变量的话,那JavaScript就很多了,遍地都是。而这样的话,就跟reference有关系了。

说起来也是邪门了,今天打算把《红宝书》拿出来翻一下,翻到了第四章4.1.2,看到了这么一句

当使用 num1 的值来初始化 num2 时,num2 中也保存了值 5。但 num2
中的 5 与 num1 中的 5 是完全独立的,该值只是 num1 中 5 的一个副本。

当从一个变量向另一个变量复制引用类型的值时,同样也会将存储在变量对象中的值复制一份放到
为新变量分配的空间中。不同的是,这个值的副本实际上是一个指针,而这个指针指向存储在堆中的一
个对象。复制操作结束后,两个变量实际上将引用同一个对象。

于是我的想法 “引用是一种指针” 或许成立。(复习有好处的!)

Point == Reference

如果反过来,还能成立吗?我觉得不行。

C++,让我很崇拜很信仰的,却因不理解和学不会让我产生厌恶的语言,在这方面是两者皆有。由于根本不懂所以不参加讨论。

Java,他也有reference,但是在Java的Reference感觉很象C++的指针,但是区别是本质的 - f…_博客园 提到:

Java中你无法对这个地址进行任何数学运算,并且这个地址你不知道,是Java Runtime分配给你的,它随时还要调整这个地址(After GC,Memory要Compact,这时候一个Object Reference的地址就会改变)。

我不是很理解,所以我也不敢评论什么。我只想关于Go和JS的东西。

也许是心理隔阂,也许是真理。我怎么都想不出怎么让“指针是一种引用”成立。

老是想内存内存,不如想成一个盒子,指针就是给盒子里的东西连了一条线。这样做就不用我找这个东西的时候去盒子里找,而是直接去找这条线?

可是在JS中,引用也不能修改和做任何运算吗?

Reference === Pointer?

我不是语言专家,我一点都不敢保证。或者说我不懂。

我不知道所谓的指针是什么东西,但是我知道reference是一个object,毕竟不知道哪篇文章写道:函数是JavaScript第一公民。但并不是很纯的函数式编程语言。

其实思考到现在,我又有新的问题了:前端语言,或者说函数式编程语言,有没有内存,指针一说?

不过现在可以知道的是:

​ 在指令式编程中,数值就是数值,一切工作之后无非就是想得到一个值,过程中也在围绕着值。

​ 在函数式编程中,函数还是占主要地位,它需要以数学的方式去解决编程的问题。

那我现在可不可以有一种新的理解:

​ 比如C语言这种,他定义指针是需要 * 这种东西,也就是int *a = b是用a指针指向b,我可以通过a来修改b。但是如果直接int a = b的话,我就相当于复制了这个变量了,没权修改b变量了。而如果int a是一个函数的话,那它最后也需要返回一个int返回值。所以它并没有“用函数搞事”的权利。

​ 而JS语言这种,我想用一个代码框来写:

1
2
3
4
5
6
7
8
9
10
11
12
// 还是根据红宝书的例子
var a = 5;
var b = a; // 一种复制,相互独立

var x = {a: 5}
var y = x // 一种引用,实际上操作y的时候还是在操作x

//现在暂时借用一下以 _ 代替*
var o = { a: 5 }
var _b = o.a // 达到继承的目的?

// var _b = int *b 在某种意义上?

在红宝书接下来有一句:

换句话说,obj1和 obj2 都指向同一个对象。这样,当为 obj1 添加 name 属性后,可以通过 obj2 来访问这个属性,
因为这两个变量引用的都是同一个对象。

按我的角度翻译一下,就是:我定义一个b出来,无非就是给a多了一个出口

所以综上所述,我认为,对我来说,或者对C系除外的语言来说,把“指针”说成“指向”,或许让人更好理解。

哼,计算机真是有趣。

(最后感谢所有被引用的文章和作者,谢谢。)