This is the 11th day of my participation in the August Wenwen Challenge.More challenges in August
Basic types of
There are seven basic data types: Number, String, Boolean, Null, Undefined, Symbol (ES6), BigInt (ES10). Variables are stored on the stack according to their values. Assign values directly with =.
Reference types
There is one reference data type: Object. Variable memory addresses are stored on the stack, values are stored in the heap, and assignment of reference types is closely related to shallow and deep copies discussed below.
Shallow copy
First declare shallow copy ≠ assignment.
Assignment = assigns the memory address of the object. Two objects refer to the same storage space in the heap and affect each other.
let obj1 = {
name: 'jin line'.list: ['JS'.'CSS'.'HTML']}let obj2 = obj1
obj2.name = 'seven gold'
obj2.list[0] = 'Java'
// {list: ['Java', 'CSS', 'HTML']}
// {list: ['Java', 'CSS', 'HTML']}
Copy the code
Shallow copy creates a new memory space in the heap. After the copy, the basic data types of objects do not affect each other, but the reference types still share the same storage space and affect each other.
function shallowClone (obj1) {
let obj2 = {}
for (let i in obj1) {
obj2[i] = obj1[i]
}
return obj2;
}
let obj1 = {
name: 'jin line'.list: ['JS'.'CSS'.'HTML']}let obj2 = shallowClone(obj1)
obj2.name = 'seven gold'
obj2.list[0] = 'Java'
console.log(obj1, obj2)
// {list: ['Java', 'CSS', 'HTML']}
// {list: ['Java', 'CSS', 'HTML']}
Copy the code
Array
Collate array shallow copy related API.
Extended operator
let arr1 = [1[2].3]
let arr2 = [...arr1]
arr2[0] = 4
arr2[1].push(5)
console.log(arr1, arr2) / / [1, 2, 5), 3] [4, (2, 5), 3]
Copy the code
Array.prototype.slice
let arr1 = [1[2].3]
let arr2 = arr1.slice()
arr2[0] = 4
arr2[1].push(5)
console.log(arr1, arr2) / / [1, 2, 5), 3] [4, (2, 5), 3]
Copy the code
Array.prototype.concat
let arr1 = [1[2].3]
let arr2 = arr1.concat([])
arr2[0] = 4
arr2[1].push(5)
console.log(arr1, arr2) / / [1, 2, 5), 3] [4, (2, 5), 3]
Copy the code
Array.from
Creates a new shallow-copy array instance of a class array or iterable.
let arr1 = [1[2].3]
let arr2 = Array.from(arr1)
arr2[0] = 4
arr2[1].push(5)
console.log(arr1, arr2) / / [1, 2, 5), 3] [4, (2, 5), 3]
Copy the code
Array.prototype.map
let arr1 = [1[2].3]
let arr2 = arr1.map(item= > item)
arr2[0] = 4
arr2[1].push(5)
console.log(arr1, arr2) / / [1, 2, 5), 3] [4, (2, 5), 3]
Copy the code
Array.prototype.filter
let arr1 = [1[2].3]
let arr2 = arr1.filter(item= > item)
arr2[0] = 4
arr2[1].push(5)
console.log(arr1, arr2) / / [1, 2, 5), 3] [4, (2, 5), 3]
Copy the code
Array.prototype.reduce
Reduce here may be a little bit of a cheat 🤣, does not really reflect its value, can be regarded as providing a novel idea.
let arr = [1[2].3]
let arr2 = arr.reduce((arr1,item) = > {
arr1.push(item)
return arr1
}, [])
arr2[0] = 4
arr2[1].push(5)
console.log(arr, arr2) / / [1, 2, 5), 3] [4, (2, 5), 3]
Copy the code
Object
Collate the API related to object shallow copy.
Extended operator
let obj1 = {
name: 'jin line'.list: ['JS'.'CSS'.'HTML']}letobj2 = {... obj1} obj2.name ='seven gold'
obj2.list[0] = 'Java'
console.log(obj1, obj2)
// {list: ['Java', 'CSS', 'HTML']}
// {list: ['Java', 'CSS', 'HTML']}
Copy the code
Object.assign
let obj1 = {
name: 'jin line'.list: ['JS'.'CSS'.'HTML']}let obj2 = Object.assign({}, obj1)
obj2.name = 'seven gold'
obj2.list[0] = 'Java'
console.log(obj1, obj2)
// {list: ['Java', 'CSS', 'HTML']}
// {list: ['Java', 'CSS', 'HTML']}
Copy the code
Deep copy
Heap memory is recreated to hold new objects, the two objects do not affect each other.
Array
serialization
Json.stringify converts the array to a JSON string, and json.parse converts the string to a new array.
let arr1 = [1[2].3]
let arr2 = JSON.parse(JSON.stringify(arr1))
arr2[0] = 4
arr2[1].push(5)
console.log(arr1, arr2) / / [[2] 1, 3] [4, (2, 5), 3]
Copy the code
Object
serialization
Json.stringify converts the object to a JSON string, and json.parse converts the string to a new object, but this method has drawbacks.
let obj1 = {
name: 'jin line'.list: ['JS'.'CSS'.'HTML']}let obj2 = JSON.parse(JSON.stringify(obj1))
obj2.name = 'seven gold'
obj2.list[0] = 'Java'
console.log(obj1, obj2)
// {list: ['JS', 'CSS', 'HTML']}
// {list: ['Java', 'CSS', 'HTML']}
Copy the code
There doesn’t seem to be any problems, and there’s no need to introduce the LoDash library. So, now add a method to the object to see ~
let obj1 = {
name: 'jin line'.list: ['JS'.'CSS'.'HTML'].work: function() {}}let obj2 = JSON.parse(JSON.stringify(obj1))
console.log(obj1, obj2)
/ / {name: jin line, list: [' JS ', 'CSS', 'HTML'], the work: the function () {}}
// {list: ['JS', 'CSS', 'HTML']}
Copy the code
Method lost after json.stringify… There is always a solution to everything, but when it comes to the lodash library.
What I did was turn the Function into a string to make sure it wasn’t lost again, and finally use new Function() to turn the string into a Function.
let obj1 = {
name: 'jin line'.list: ['JS'.'CSS'.'HTML'].work: function() {},}for(let i in obj1) {
if(typeof obj1[i] === 'function') {
obj1[i] = obj1[i].toString()
}
}
let obj2 = JSON.parse(JSON.stringify(obj1))
for(let i in obj2) {
if(typeof obj2[i] === 'string' && obj2[i].indexOf('function') = = =0) {
obj2[i] = new Function('return ' + obj2[i])
}
}
console.log(obj1, obj2)
/ / {name: jin line, list: [' JS ', 'CSS', 'HTML'], the work: the function () {}}
/ / {name: jin line, list: [' JS ', 'CSS', 'HTML'], the work: the function () {}}
Copy the code
Of course, this method is not perfect. If I do have a field of type string and the value is function, that would be a coincidence.
This phenomenon made me curious about json.stringify. What other types of data are lost? Enumerates the write attributes…
let obj1 = {
name: 'jin line'.list: ['JS'.'CSS'.'HTML'].work: function() {},
date: new Date(),
reg: new RegExp(),
symbol: Symbol(),
number: NaN.address: Infinity.age: undefined
}
console.log(JSON.stringify(obj1))
/ / {
// "name":" name",
// "list":["JS","CSS","HTML"],
/ / "date" : "the 2021-08-28 T11: they. 545 z",
// "reg":{},
// "number":null,
// "address":null
/ /}
Copy the code
The discovery is really deep pit 🤦♀️
- The function,
Symbol
,undefined
The loss of NaN
,Infinity
changenull
theRegExp
The object variable{}
Date
Object to string
Continue to look for json.stringify trolled articles on the web and beware of the following
- Methods with
toJSON
, returns the function directlyreturn
value
let obj1 = {
name: 'jin line'.toJSON: function() {
return 'jin line'}}console.log(JSON.stringify(obj1)) / / jin
Copy the code
- Property references itself, and an error is reported
let obj1 = {
name: 'jin line'.copy: obj1
}
console.log(JSON.stringify(obj1))
Copy the code
- Non-enumerable attributes exist and are also lost
let obj1 = {
name: 'jin line'
}
Object.defineProperty(obj1, 'name', {
enumerable: false
})
console.log(JSON.stringify(obj1)) / / {}
Copy the code
Some of these cases can also be converted to string first, and then back to the original attribute type, which is a kind of idea, but in the case of the value of the object is known, otherwise it is better to use the mature cloneDeep in LoDash.
Deep copy is so complicated that you can study the source code of cloneDeep in Lodash after preparation. Try writing it by hand and make a draft first. If you feel helpful, welcome to like + follow + collect 🧡, exchange learning