基本数据类型按值传递
复杂数据类型按引用传递
请问:函数感觉也是复杂数据类型,但它的传递好像是按值传递的,这个该怎么理解呢
const fn1 = () => console.log(111)
let fn2 = fn1
fn2 = () => console.log(222)
// 如果引用传递的话,它俩的打印不应该都是222吗,但实际如下
fn1() // 111
fn2() // 222
// 或者有什么方式的赋值,能体现出来函数是引用传递的?
基本数据类型按值传递
复杂数据类型按引用传递
请问:函数感觉也是复杂数据类型,但它的传递好像是按值传递的,这个该怎么理解呢
const fn1 = () => console.log(111)
let fn2 = fn1
fn2 = () => console.log(222)
// 如果引用传递的话,它俩的打印不应该都是222吗,但实际如下
fn1() // 111
fn2() // 222
// 或者有什么方式的赋值,能体现出来函数是引用传递的?
你对引用传递可能存在一些误解;
当 obj1 = {a:1}
的时候,计算机会为 {a:1}
开辟内存空间,并把 {a:1}
存入其中,之后会把所存内存空间的起始地址赋值给 obj1
, 也就是 obj1
在计算机里面记录的是一份 内存地址
, 类似 0x10000001
之类的,当你使用 obj2 = obj1
的时候,相当于把 内存地址
给了obj2
,所以 obj1
obj2
其实指向的是同一 内存地址
,也就是相同的内容,当你将 obj2 = {a : 222}
的时候, {a:222}
也会存放到某一段 内存中
, 并把内存地址给到 obj2
,因此 obj2
和 obj1
就不再指向同一个内存地址了。
看看下面的案例:
let obj1 = {
a: 1,
b: 2,
}
let obj2 = obj1;
obj2 = {
a: 11,
b: 22,
}
console.log(obj1) // { a: 1, b: 2 }
console.log(obj2); // { a: 11, b: 22 }
obj2 = obj1 ;
obj2.a = 111;
// 修改 obj2.a ,其实修改的也是 obj1.a
console.log(obj1); // { a: 111, b: 2 }
你对引用可能有误解,举例子:
如果说A是引用类型,那么执行B=A后,如果对A进行了修改,比如:
A.xxx=newVal
那么,B.xxx也会改变,反之也是。
不过,如果你执行了:
A=新的引用
那么,对B就没有影响了,反之也是。
总结:引用就是相当于A和B指向同一个对象,通过A或B就可以修改这个对象的内容,可是,比如B修改指向新的对象了,那么A依旧指向原来的对象,当然两个可以是不同的。
你这个属于误用了吧。fn2已经在你的修改下 fn2 = () => console.log(222)
,被重新定义了,那么就等于新开辟了内存空间去定义fn2了。当然fn2和fn1不一样了。
如同:
const a = {'a': 1, 'b': 2}
let b = a
b['c'] = 4
console.log(b)
// {a: 1, b: 2, c: 4}
console.log(a)
// {a: 1, b: 2, c: 4}
// 这里b被重新赋值,内存id与a的已经不同了
b = {'d': 5}
console.log(b)
// {d: 5}
console.log(a)
// {a: 1, b: 2, c: 4}
js 在 import、export 出来之前只有值传递,没有引用传递。
你对引用传递有误解,真正的引用传递:
function c(a) {
a = {v:2};
}
let a = {v:1};
c(a);
console.log(a);
// 如果是引用传递,应该输出 {v:2}
引用传递代表传递的内容是变量的地址,等于给变量一个别名,给别名赋值、原变量也会变化。
目前 js 中应该只有 import、export 才有这种应用。
let a = {v:1};
setTimeout(() => {a = {v:2}}, 1000);
export {a};
import {a} from './a.js';
console.log(a);
// {v:1};
setTimeout(() => console.log(a), 1000);
// {v:2}
或者有什么方式的赋值,能体现出来函数是引用传递的?
const f = () => 1
f.a = 2
const g = f
g.a = 3
console.log(f.a, g.a) // 3 3
// pointerFn1: () => console.log(111)
// pointerFn2: () => console.log(222)
const fn1 = pointerFn1
// 这里的赋值只是改变 fn1、fn2 的内存地址(指针)指向,并没有改变指向的值里的内容。
let fn2 = fn1 // 等价于 fn2 = pointerFn1
fn2 = pointerFn2
fn1() // 111
fn2() // 222
10 回答11.1k 阅读
6 回答3k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3k 阅读✓ 已解决
2 回答2.6k 阅读✓ 已解决
3 回答5.1k 阅读✓ 已解决
3 回答1.8k 阅读✓ 已解决
function 是对象,按引用传递。
但是 JS 中的引用和 C++ 中的引用概念不同,它更接近于 C++ 的 const 指针的概念。所以对一个引用赋值只是改变了它的指向,并不会改变原变量。
所以我觉得可以这样理解,都是按值传递,只不过基本数据类型传递的是本身的值,而复杂数据类型传递的是引用(地址)的值。