JS data type
- Six basic data types:
- Boolean. Boolean value, True and false.
- Null. A special keyword that indicates a null value. JavaScript is case-sensitive, so null is completely different from NULL, NULL, or other variables.
- Undefined. property when the variable is not defined.
- Number. Represents a number, for example: 42 or 3.14159.
- String. Represents a string, for example: "Howdy"
- Symbol (The newly added type in ECMAScript 6): A data type whose instance is unique and immutable.
- And the Object object reference data type
In most cases, we can typeof
judge by attributes. There are only a few exceptions, such as:
var=newFunction (‘a‘,‘b‘,‘return a + b‘)typeof// function
About the function
type of data that is not JS, there are related discussions in JavaScript is also a basic type of Function?
Related differences between basic types and reference data types basic data types
Let's take a look at some definitions of the basic data types in the MDN:
All types except Object are immutable (the value itself cannot be changed). For example, unlike the C language, strings in JavaScript are immutable (e.g., the operation of a string in JavaScript must return a new string, and the original string has not been changed). We call these types a value of "original value".
var=‘string‘a[0=‘a‘console.log(a) // string
We typically reassign a variable instead of changing the value of the base data type. In JS, there is no way to change the Boolean values and numbers. There are many ways to manipulate strings, but all of these methods return a new string and do not change their original data. Like what:
- Gets a substring of a string that can be selected by selecting individual letters or using STRING.SUBSTR ().
- A connection operator (+) or String.Concat () is used to connect two strings.
Reference data type
The reference type (object) is stored in the heap memory, and the variable is actually a pointer to the stack memory, which points to the address in the heap memory. Each space size is different, depending on the circumstances of the specific allocation, for example.
var={name:‘jozo‘};var={name:‘xiaom‘};var={name:‘xiaoq‘};
The value of the reference type is variable:
person1[‘name‘=‘muwoo‘console.log// {name: ‘muwoo‘}
Transmit Value and address
After understanding the difference between the basic data type and the reference type, we should be able to understand the difference between the value of the pass and the address.
When we perform an assignment, the assignment of the base data type (=) is to open a new stack of memory in memory and then assign the value to the new stack. For example:
var=10;var= a;++;console.log(a);// 11console.log(b);// 10
Therefore, the two variables of the basic type assignment are two independent variables that do not affect each other.
But the assignment of the reference type is the address. Just change the pointer's direction, for example, the assignment of the reference type is the assignment of the address that the object holds on the stack, so that the two variables point to the same object, so that the operation affects each other. For example:
varA= {}; //A saves an instance of an empty objectvarB=A; //A and B all point to this empty objecta.name = ' Jozo ';Console.Log(a.name); //' Jozo 'Console.Log(b.name); //' Jozo 'b. Age = A;Console.Log(b. Age);//Console.Log(a. Age);//Console.Log(A==b;//True
Shallow copy
Let's look at the execution of a piece of code:
varObj= {a: 1, b: {C: 2}}varObj1=ObjvarObj2= shallowcopy(obj);function shallowcopy(SRC){ varDst= {}; for(varPropinchSrc{ if(src.hasOwnProperty(prop)){Dst[prop]=Src[prop]; } } returnDst;}varObj3= Object.Assign({},Objobj.a = 2obj.b.C = 3Console.Log(obj)//{a:2, B: {c:3}}Console.Log(OBJ1)//{a:2, B: {c:3}}Console.Log(OBJ2)//{a:1, B: {c:3}}Console.Log(OBJ3)//{a:1, B: {c:3}}
This code shows that the object that is assigned to it is obj1
simply changing the pointer, which is still referencing the same object, while a shallow copy obj2
is recreating the new object. However, if obj
there is another object in the original object, the object will not be copied another time, but only the address of its variable object. This is because a shallow copy copies only the properties of a layer of objects, and does not include data that is reference types inside the object.
For arrays, the longer-seen shallow copy method is slice(0)
concat()
ES6 relatively common shallow copy method isObject.assign
Deep copy
With these instructions above, I believe you have a general understanding of what a deep copy is: A deep copy is a copy of an object and all its child objects. So how do you implement such a deep copy?
1. Json.parse (json.stringify (obj))
For regular objects, we can resolve the JSON.stringify
problem that the memory address points to the same by saying that the object is converted to a string and then used JSON.parse
to assign another storage address to it:
var obj = { a : { span class= "DT" >b : 1 }} var copy = json . parse (json .) stringify (obj)) obj . a . b = 2 console . Span class= "at" >log (obj) //{a: {b:2}} console . log (copy) //{a: {b:1}}
However JSON.parse()
, JSON.stringify
there is also a problem, JSON.parse()
and J SON.stringify()
can properly handle the object only Number、String、Array
such as the JSON can be represented by the data structure, so the function of such a type can not be represented by JSON will not be processed correctly.
varTarget= { a: 1, b: 2, Hello: function(){ Console.Log("Hello, world!."); }};varCopy= JSON.Parse(JSON.stringify(target));Console.Log(copy); //{a:1, b:2}Console.Log(JSON.stringify(target)); //"{" A ": 1," B ": 2}"
2. Traversal to implement property replication
Since a shallow copy can only implement object
a copy of a non-first-level attribute, it is object
only necessary to simply recursively implement a shallow copy of its internal properties:
function Extend(source){ varTargetif(typeofSource=== ' object '){Target= Array.IsArray(source)?[] :{} for(varKeyinchSource{ if(Source.hasOwnProperty(key)){ if(typeofSource[key]!== ' object '){Target[key]=Source[key]} Else {Target[key]= Extend(Source[key])} } } } Else {Target=Source} returnTarget}varObj1= {a: {b: 1}}varCpObj1= Extend(OBJ1)obj1.a.b = 2Console.Log(CPOBJ1)//{a: {b:1}}varObj2=[[1]]varCpObj2= Extend(OBJ2) obj2[0][0]= 2Console.Log(CPOBJ2)//[[1]]
Let's take Zepto
a look at the code in the deep copy:
//Internal method: The user merges one or more objects into the first object //Parameters: //target object objects are merged into target //Source Merge Object //Deep merge is performed function Extend(Target,Source,Deep{ for(KeyinchSourceif(Deep&&(Isplainobject(Source[key])|| IsArray(Source[key]))){ ///Source[key] is an object, and Target[key] is not an object, then Target[key] = {} Initializes, otherwise recursion will go wrong if(Isplainobject(Source[key])&& !Isplainobject(Target[key])) Target[key]= {} ///Source[key] is an array, and Target[key] is not an array, then target[key] = [] Initialize, otherwise recursion will go wrong if(IsArray(Source[key])&& !IsArray(Target[key])) Target[key]=[]//Perform recursion Extend(Target[key],Source[key],Deep} //Do not meet the above conditions, description Source[key] is a general value type, directly assigned to target is the Else if(Source[key]!== undefined) Target[key]=Source[key]}
Internal implementations are actually similar.
Postscript
For more front-end diaries, please refer to here:
Vue Source Code Interpretation
Axios Source Code Interpretation
JS Advanced Section
Resources
JS deep copy vs Shallow copy
JS data type, assignment, deep copy, and shallow copy