今天我们将讨论 Javascript 中最基本的概念之一“按值传递”和“按引用传递”。 这个概念非常重要,甚至这个问题也经常出现在求职面试中。 这是为什么? 了解它是如何工作的,它将帮助我们成为更好的程序员,能够理解应用程序中的数据流。
在我们深入解释之前。 我们必须知道,在 Javascript 中数据类型分为两类:原始的和非原始的。
以下是 Javascript 中的原始数据类型列表:
同时,所有对象、数组和函数都属于非原始数据类型。
好的,我们得到了这个。 让我们进入解释!
通过引用传递
我们通过下面的代码来了解一下引用传递的是什么
let john = { name: 'John Doe', gender: 'male', score: 95};let JohnDupe = john;console.log(JohnDupe); // {name: 'John Doe', gender: 'male', score: 95}console.log(john); // {name: 'John Doe', gender: 'male', score: 95}好的,我们创建了一个新变量 JohnDupe,并为 John 赋值。 如果我们修改 JohnDupe 的分数,接下来会发生什么?
johnDupe.score = 50;console.log(JohnDupe); // {name: 'John Doe', gender: 'male', score: 50}console.log(john); // {name: 'John Doe', gender: 'male', score: 50}请注意,他们对 John 的价值得分也发生了变化! 究竟发生了什么? 当我们创建 John(一个新对象)时,我们将值存储在某个地址的内存中。 而当我们将 John 的值分配给 johnDupe 时,实际上不是创建 John 的副本,JohnDupe 的值是引用内存中 John 的值(地址)。
要解决上述问题,我们需要实际创建 John 的副本并将其分配给一个新变量,然后我们可以在不影响原始 John 的情况下更改分数。
let john = { name: 'John Doe', gender: 'male', score: 95};let anotherJohn = {...john}anotherJohn.score = 50;console.log(john); // {name: 'John Doe', gender: 'male', score: 95}console.log(anotherJohn); // {name: 'John Doe', gender: 'male', score: 50}在上面的代码中,我们使用扩展运算符复制了 john,然后将其分配给 anotherJohn。 通过创建一个新对象,anotherJohn 实际上将复制的对象存储在与 john 不同的地址的内存中。 anotherJohn 不再像以前那样引用 john,它们是完全不同的实体。 为了证明这一点,请看下面的代码
let person = { name: 'Nicola Tesla', gender: 'male',};let personDupe = person;let anotherPerson = { name: 'Nicola Tesla', gender: 'male',};console.log(person === personDupe); // trueconsole.log(person === anotherPerson); // false在上面的示例中,我们尝试比较相等的 person === personDupe,这将打印为 true,因为 personDupe 指向的是 person 的地址。 但是,当我们尝试比较一个相等的人 === anotherPerson 时,这将打印为 false,因为即使它们具有相同的属性和值,它们也不是同一个对象。
这种行为也与 Array 相同。
let fruits = ['apple ', 'strawberry ', 'banana '];let fruitsDupe = fruits;let anotherFruits = ['apple ', 'strawberry ', 'banana '];console.log(fruits === fruitsDupe); // trueconsole.log(fruits === anotherFruits); // false我有一个类比,通过假设它是一个谷歌表/谷歌文档,让我们更容易理解“通过引用”。
假设一群学生被老师分配给他们对全球变暖的看法。老师希望作业的格式在一个文件中。
约翰作为班长主动创建了一个谷歌文档,以便学生可以轻松协作。约翰然后与他的同学分享链接。 Mary 是第一个更改文档并添加一堆关于全球变暖的想法的学生。那天晚上晚些时候,苏西打开了谷歌文档并添加了她自己的意见,然后是安迪等。最后,在所有学生都添加完自己的意见后,John 将 google docs 分享给了老师。一切都很好,班级的作业得了“A”
从上面的案例来看,google docs无论被学生修改多少次,最终还是只修改了一个文件(主文件)。
到目前为止,一切都很好!我们知道传递引用到底是什么。
按值传递
如果您已经了解了按引用传递,那么您就已经了解了按值传递是什么。诸如数字或字符串之类的原始值实际上会创建一个副本。
const num = 10function passByValue(val) { return val += 1}console.log('[passByValue]:', passByValue(num)) // [passByValue]: 11console.log('[num]:', num) // [num:] 10在上面的代码中,我们创建了一个值为 10 的变量 num。此外,我们创建了一个函数 passByValue,它接受一个值作为参数并将其加 1。如果我们试图运行上面的代码,passByValue 将返回 11 ,但是num变量仍然是10。num的原始值根本没有改变。
结论!!
希望这篇短文能帮助你理解传递引用和传递值的概念。 按值传递和按引用传递的主要区别在于,按值传递将在内存中创建一个新空间并复制一个值。 但是通过引用传递而不是复制,存储在内存中的值被引用。
关注七爪网,获取更多APP/小程序/网站源码资源!
| 留言与评论(共有 0 条评论) “” |