JS data base type and reference type
Basic types: undefined, NULL, string, number, Boolean, symbol (ES6)
Common basic types: undefined, null, symbol (ES6)
Special basic packing types: String, Number, Boolean
Reference types: Object, Array, RegExp, Date, Function
Difference: Reference type values can add attributes and methods, whereas primitive type values cannot.
Basic types of
- Variables of basic types are stored in the Stack
- Values of basic data types are accessed by value
- Values of primitive types are immutable
- A comparison of primitive types is a comparison of their values
Reference types
- The value of the reference type is an Object stored in the Heap.
- Values of reference types are accessed by reference
- The value of a reference type is mutable
- A direct comparison of reference types is a comparison of reference addresses
(NaN is a number type) JS data type
A wrapper class
{String, Number, Boolean}} {String, Number, Boolean}} {String, Number, Boolean}} Using string as an example, what is the difference and relationship between a primitive data type and its wrapper class?
string vs String
We know that the values of basic data types are stored directly in stack memory and are continuously stored in memory, accessed by value. Basic data types like NULL cannot operate on.property because it is a value. The.property method should not be used for basic data types, but in everyday use, for string, which is also a basic data type, the.length method can be used to obtain its length.
var a='test'; console.log(a.length); //4 var b=null; console.log(b.length); //Uncaught TypeError: Cannot read property 'length' of nullCopy the code
Why is string ok and null not?
As you can see from the previous type summary, js has a string and a string, and the two are not the same thing.
What is String(val)? What are you doing?
Using String as an example, we can see that there are several definitions related to String in the ECMA262 documentation:
- String Value: The original value of an ordered number of finite length in memory
- String type: All
String value
The combination of - String Object: Obviously this is a
Object
Is built-in JSString constructor
The instance. When usingnew String(str)
The object is created when the form is called.
We can see that there are several definitions of String that refer to Object, so is the.length property implemented by Object?
var a = String('a');
var a2 = String('a');
console.log(a === a2);
//true
var b = new String('b');
var b2 = new String('b');
console.log( b === b2);
// false
console.log( b == b2);
// false
Copy the code
New String(‘b’) returns a special String Object with the length property, so of course you can access its length directly.
In addition, we can see that __proto__ of instance B refers to String, and we can expand to see a special String.prototype object that defines some of the common operations on String.
For now, it’s a little easier to understand how new String(val) can access.length, because it returns an instance of a particular String object, so of course you can access all the methods defined on the String prototype. In other words, access to the length of a String is, after all, implemented with the help of a special Object.
The difference between new String() and String()
We know that the new keyword process involves the creation of a new object, so the result of new String(STR) returns a new instance of String. Therefore, b and B2 store references to two objects. Their reference addresses are different.
In ecma262, attributes for String instances are described like this:
String instances are String exotic objects and have the internal methods specified for such objects. String instances inherit properties from the String prototype object. String instances also have a [[StringData]] internal slot.
String instances have a “length” property, and a set of enumerable properties with integer-indexed names. The String instance belongs to String Exotic Objects. The instance inherits the String Prototype Object properties and also has [[StringData]] built-in properties. String instances also have a length attribute.
So why can String(STR) values still be compared by value? This looks like a constructor method, right? Even if Object is not used with new, the type of reference instance returned will be different.
var c = Object('a');
var d = Object('a');
console.log(c === d);
//false
Copy the code
Ecma262 /#sec-string-constructor constructor (…) ) also has two sentences that say:
- creates and initializes a new String object when called as a constructor.
- When called as a constructor (that is, when new), a new String is created and initialized
- performs a type conversion when called as a function rather than as a constructor.
- When called as a function (which is simply String(…)) ) will perform type conversions
That is, when new is not used, String(…) === toString(…) Verify this with code:
var a = String(1); var b = '1'; console.log( a === b); // true var c = String({a:1}); var d = "[Object Object]" console.log( c === d); // true console.log(d.length); / / 15Copy the code
String(val) returns an ordinary String, but it can still call.length. Let’s look at the output of this code
console.log('1'.__proto__);
Copy the code
The String ‘1’ is a simple String value. It is not created by a new String(val). Why output __proto__?
Also, adding an attribute to it will not succeed. The following code will work, but the value of the added attribute is undefined.
var a = '2'; a.haha = '123'; console.log(a); //2 console.log(a.haha); //undefinedCopy the code
String value is accessed by value. Why can a String value access properties? That’s the key. Operating on. The name of the dot operation is Property Accessors. stackoverflow/difference-between-the-javascript-string-type-and-string-object
What happens to Property Accessors(.xxx)
In the usecma262In theMemberExpression. IdentifierName (similar to a.)
What happens when you get a property this way?a.property
The key isevaluate-property-access-with-identifier-keyIn this method, the call toToObject(a)
Methods. So the point is,ToObjectWhat exactly does the method do with parameters of different data types?
In this table, we see the three conspicuous words new String object in the String line. Combined with the new String() that we learned earlier, we can see that for a normal String value, when it is called. To do this, JS silently uses ToObject, calling new String(val) to create a new String Object. In this process, the reference operation is used to check whether the new String Object has the value of the property to be accessed.
So thislength
It’s not'1'
The String value property, but insteadString Obj
Instance properties.
So in terms of code, we can simply understand as:
'1'. Length is created not because '1' has the 'length' attribute, but because it creates an instance of String and accesses the length attribute on that instance. var a = new String('1'); // a is a String. Object is an object that points to the string. prototype object.Copy the code
ToObject(obj) returns the object itself, so ee.heihei = ‘123’. This adds an attribute directly to EE, so you can still access it later.
var ee = new String('a');
console.log(ee.heihei);
//undefined
ee.heihei = '123';
console.log(ee);
Copy the code
For ‘1’. Haha, undefined, many articles explain that the object will be destroyed when the wrapper class is created.
But for'1'.haha='123'
For example, every time.
I’m creating a new String obj
'1'.haha = '123'; Create String obj console.log('1'.haha); Another String obj is created, and each new String obj has no haha attributeCopy the code
So even if you do an assignment, you can’t access the value of the HAHA attribute on it later.
From ToObject’s processing logic, null/undefined is called. The real reason for the error is clear.
The above is mainly after reading the ECMA document collated personal understanding, if there are mistakes welcome to correct.