JS has 7 basic data types: Boolean, Null, Undefined, Number, BigInt, String, Symbol. These basic data types are passed by value.
It’s worth noting that there are three other types: Array, Function, and Object, which are passed by reference. From the underlying technology, all three are objects.
Basic data types
Basic types are stored on the stack, accessed by value, and assigned in the normal way
- If a base datatype is bound to a variable, we can assume that the variable contains the value of the base datatype.
let x = 10
let y = 'abc'
let z = null
Copy the code
- When we assign to these primitive data types using =, we actually make a copy of the corresponding value and assign it to the new variable. We call this value passing.
let a = 11
let b = 'ab'
let aa = a
let bb = b
console.log(a, b, aa, bb) // 11, ab, 11, ab
Copy the code
- Both A and AA contain 11, and they are independent copies of each other and do not interfere with each other. If we change the value of A, AA will not be affected.
a = 1111
console.log(a, aa) / / 1111, 11
b = 'abcd'
console.log(b, bb) // abcd, ab
Copy the code
2. Reference data types
Reference types refer to objects. We can have properties and methods, and we can modify their properties and methods. A reference object is stored in the stack with its variable name and heap address, and in the heap with its data.
Object uses reference assignment. When we assign an object to a new variable, we assign the object’s address in the heap, not the data in the heap. That is, two objects point to the same storage space. If any object is changed, it is the content of the changed storage space. Therefore, the two objects are linked.
If a variable is bound to a non-basic data type (Array, Function, Object), it records only one memory address where specific data is stored. Note that variables pointing to primitive data types contain data, whereas variables pointing to non-primitive data types do not themselves contain data.
- Objects are created in memory, and when we declare arr = [], we create an array in memory. Arr records the address of that memory
let arr = [1.2.3]
Copy the code
When the execution is complete, an empty array object is created in memory with the memory address #001 to which arR points
variable | address | object |
---|---|---|
arr | # 001 | [1, 2, 3] |
- Objects are passed by reference, not by value. That is, variable assignments simply pass the address
let arr2 = arr
console.log(arr, arr2) // [1, 2, 3], [1, 3]
Copy the code
variable | address | object |
---|---|---|
arr | # 001 | [1, 2, 3] |
arr2 | # 001 | (write) |
- Arr and arR2 refer to the same array. If we update arR, ARR2 will also be affected
arr.push(4)
console.log(arr, arr2) [1, 2, 3, 4] // [1, 2, 3, 4]
Copy the code
variable | address | object |
---|---|---|
arr | # 001 | [1, 2, 3, 4] |
arr2 | # 001 | (write) |
- Reference reassignment: If we reassign an already assigned variable, it will contain the new data or reference address. If the original object content has no variables to reference, JS will free the original object memory.
let obj = { a: 1 }
console.log(obj) // {a: 1}
Copy the code
variable | address | object |
---|---|---|
obj | # 0001 | {a: 1} |
obj = { a: 1.b: 2 }
console.log(obj) // {a: 1, b: 2}
Copy the code
variable | address | object |
---|---|---|
(empty) | # 0001 | {a: 1} |
obj | # 0002 | {a: 1, b: 2} |
=== === ===
- For variables of reference type, == and === only determine whether the address of the reference is the same, not whether the attributes and values of the object are the same. Therefore, if two variables refer to the same object, return true
let aa = [1.2]
let bb = aa
console.log(aa === bb) // true
Copy the code
variable | address | object |
---|---|---|
aa | # 001 | [1, 2] |
bb | # 001 | (write) |
- False is returned if the objects are different, even if they contain the same properties and values
let aa = [1.2]
let bb = [1.2]
console.log(aa === bb) // false
Copy the code
variable | address | object |
---|---|---|
aa | # 001 | [1, 2] |
bb | # 002 | [1, 2] |
- If you want to determine if two different objects are really the same, an easy way to do this is to convert them to strings and determine (imperfectly)
let str = JSON.stringify(aa)
let str2 = JSON.stringify(bb)
console.log(str === str2) // true
Copy the code
4. Function parameter transfer
- Js function parameters are passed by value. When an argument of primitive type is passed in, it copies the content to I, and there is no relation between I and age
function setAge(i) {
alert(i) / / 24
i = 18
alert(i) //18, I change does not affect the outside age
}
let age = 24
setAge(age)
alert(age) / / 24
Copy the code
- When the parameter passed is of reference type. It was an address.
function setName(obj) {
obj.name = 'haha'
}
let obj2 = new Object()
setName(obj2)
alert(obj2.name) // haha
Copy the code
5. Relevant interview questions
Ali’s 2014 pen test
let a = 1
let obj = {
b: 2,}let fn = function () {}
fn.c = 3
function test(x, y, z) {
x = 4
y.b = 5
z.c = 6
return z
}
test(a, obj, fn)
alert(a + obj.b + fn.c) / / 12
Copy the code
The first argument passed to test is a primitive, obj is object, and fn is certainly not a primitive. When test is executed, x is assigned 4, y’s b is assigned 5, obj’s B becomes 5, z’s C becomes 6, and fn’s C becomes 6. Alert =1 +5+6 =12.
JavaScript’s value passing and reference passing