JavaScript raw values and wrapper objects

Tangerine peel 2022-06-24 05:45:48 阅读数:191

javascriptrawvalueswrapperobjects

Preface

With JavaScript More and more popular , More and more developers are coming into contact with and using JavaScript.

And I also found that , A lot of developers are interested in JavaScript The most basic raw values and packaging objects are not clearly understood .

So this article , Let's talk about them in detail .

🧐 Don't talk much ,Let's go!


Text

The original type (Primitive types)

Primitive types are also called “ Basic types ”.

Currently in JavaScript There are several primitive types in :

  • string( character string )
  • number( Numbers )
  • boolean( Boolean )
  • null( empty )
  • undefined( Undefined )
  • bigint( Large integer ,ES6)
  • symbol( sign ?ES6)

as follows :

typeof 'chenpipi'; // "string"
typeof 12345; // "number"
typeof true; // "boolean"
typeof null; // "object"
typeof undefined; // "undefined"
typeof 12345n; // "bigint"
typeof Symbol(); // "symbol"

, Don't pay attention to

typeof null Although return to "object", But that doesn't mean null It's the object , This is actually JavaScript One of the Bug, And from JavaScript It's been like this since it was born .

stay JavaScript In the initial implementation ,JavaScript The value in is represented by a label representing the type and the actual data value . The type label of the object is 0. because null Represents a null pointer ( Most platform values are 0x00), therefore ,null The type label of is 0,typeof null And so back to "object".

The history of “typeof null”:https://2ality.com/2013/10/typeof-null.html

Original value (Primitive values)

The original value is the value of the original type ( data ).

A primitive value is data that is not an object and has no methods.

Raw value is a kind of non object data without any method .

in other words ,stringnumber and boolean The value of primitive type itself has no properties or methods .

At this time, the olfactory little friend is not aware of something wrong ?

It's cumin ! I added cumin !( Hand the dog's head and scratch it off )

Here's a very interesting point , But before we talk about it , Let's get to know the packaging object first .

Packaging object (Wrapper objects)

except null and undefined All primitive types have their own packaging objects :

  • String( character string )
  • Number( Numbers )
  • Boolean( Boolean )
  • BigInt( Large integer ,ES6)
  • Symbol( sign ?ES6)

object (Object)

Object is a reference type .

First , The wrapper object itself is an object , Is also a function .

String instanceof Object; // true
String instanceof Function; // true

Constructors (Constructor)

example (Instance)

among StringNumber and Boolean Both support the use of new Operator to create the corresponding Wrapper object instance .

for example String Statement of ( excerpts ):

interface StringConstructor {
new(value?: any): String;
(value?: any): string;
readonly prototype: String;
}
declare var String: StringConstructor;

Use new The data from the operator is the object (Object):

// character string
typeof 'pp'; // "string"
typeof new String('pp'); // "object"
new String() instanceof Object; // true
// Numbers
typeof 123; // "number"
typeof new Number(123); // "object"
new Number() instanceof Object; // true
// Boolean
typeof true; // "boolean"
typeof new Boolean(true); // "object"
new Boolean() instanceof Object; // true

We can call the valueOf() Function to get its original value :

// character string
let s = new String('pp');
s.valueOf(); // "pp"
typeof s.valueOf(); // "string"
// Numbers
let n = new Number(123);
n.valueOf(); // 123
typeof n.valueOf(); // "number"
// Boolean
let b = new Boolean(true);
b.valueOf(); // true
typeof b.valueOf(); // "boolean"

“ Alien species ” (Attention)

and BigInt and Symbol All belong to “ Incomplete classes ”, I won't support it new Operator .

for example BigInt Statement of ( excerpts ):

interface BigIntConstructor {
(value?: any): bigint;
readonly prototype: BigInt;
}
declare var BigInt: BigIntConstructor;

You can see BigInt There is no new Operator dependent functions .

Ordinary function (Function)

Packaging objects can also be used as Ordinary function To use .

among String()Number() and Boolean() Functions can be used to explicitly type convert any type of data .

in addition Object() Functions can also be used for explicit type conversions , But this article will not expand .

String

Sample code :

typeof String(); // "string"
String(); // ""
String('pp'); // "pp"
String(123); // "123"
String(true); // "true"
String(false); // "false"
String(null); // "null"
String(undefined); // "undefined"
String([]); // ""
String({}); // "[object Object]"

Small Tips 1

When we use String() Function to convert an object ,JavaScript Will first access the toString() function , If not , It will search up the prototype chain .

Take a chestnut : perform String({ toString() { return 'pp'; } }) The result is "pp", Is not "[object Object]".

therefore String() Function can not be used to determine whether a value is an object ( It's rollover ).

Small Tips 2

The common way to judge an object is Object.prototype.toString({}) === '[object Object]'.

Take a chestnut : perform Object.prototype.toString({ toString() { return 'pp'; } }) The return is "[object Object]".

Number

Sample code :

typeof Number(); // "number"
Number(); // 0
Number(''); // 0
Number('pp'); // NaN
Number(123); // 123
Number(true); // 1
Number(false); // 0
Number(null); // 0
Number(undefined); // NaN
Number([]); // 0
Number({}); // NaN

Small Tips

about Number() In terms of functions , Perhaps the most practical conversion is to convert true and false Convert to 1 and 0 Well .

Boolean

Sample code :

typeof Boolean(); // "boolean"
Boolean(); // false
Boolean(''); // false
Boolean('pp'); // true
Boolean(0); // false
Boolean(1); // true
Boolean(null); // false
Boolean(undefined); // false
Boolean([]); // true
Boolean({}); // true

Small Tips

In some cases , We'll use it in the data 0 and 1 To show the true or false state , You can use Boolean() Judge the state .

BigInt

BigInt() Function is used to convert integers to large integers .

This function takes an integer as an argument , If the input parameter is a floating-point number or any non numeric data, an error will be reported .

Sample code :

BigInt(123); // 123n
BigInt(123n); // 123n
typeof 123n; // "bigint"
typeof BigInt(123); // "bigint"
BigInt & Number

It should be noted that ,BigInt and Number It's not strictly equal ( Loose is equal ) Of .

Sample code :

123n === 123; // false
123n == 123; // true

Symbol

Symbol() Function to create a symbol Type value .

This function takes a string as a descriptor ( Parameters ), If you pass in a value of another type, it will be converted to a string ( except undefined).

Be careful , every last symbol Values are unique , Even if their descriptors are the same .

And symbol Data of type can only be accessed through Symbol() Function to create .

Sample code :

// The following return value is Devtools Simulated , It's not the actual value
Symbol('pp'); // Symbol(pp)
Symbol(123); // Symbol(123)
Symbol(null); // Symbol(null)
Symbol({}); // Symbol([object Object])
// type
typeof Symbol('pp'); // "symbol"
Symbol('pp') === Symbol('pp'); // false
// The descriptor
Symbol('pp').description; // "pp"
Symbol(123).description; // "123"
Symbol({}).description; // "[object Object]"
Symbol().description; // undefined
Symbol(undefined).description; // undefined

The original value is not an object (Primitive not Object)

Yes Here comes the meaning ~

There are no properties or methods (No properties, no functions)

As mentioned earlier in this article :「 Raw value is a kind of non object data without any method .」

We all know the object (Object) There can be properties and methods on .

But strings are not objects , So you can't add attributes to strings .

Do a little experiment :

let a = 'chenpipi';
console.log(a.length); // 8
// Try adding new attributes
a.name = ' Wu Yanzu ';
console.log(a.name); // undefined
// Try modifying an existing property
typeof a.slice; // "function"
a.slice = null;
typeof a.slice; // "function"

residue Little theater of pi

At this time, a little friend of toutie used the refutation skill .

Scum, don't fool people here , I usually write Bug Oh, you can call the string when you don't write code 、 Methods on numbers and Booleans !

For example, the following code , Be able to execute normally and get the expected results :

// character string
let s = 'chenpipi';
s.toUpperCase(); // "CHENPIPI"
'ChenPiPi'.slice(4); // "PiPi"
// Numbers
let n = 123;
n.toString(); // "123"
(123.45).toFixed(2); // "123.5"
// Boolean value
let b = true;
b.toString(); // "true"
false.toString(); // "false"

nothing With a little knowledge

Did you find , You can't call a function directly after the literal value of a number ? For example, to perform 123.toString() Will be submitted to the SyntaxError( Grammar mistakes ).

It's because of the numbers ( Floating point numbers ) It uses the decimal point itself ., And calling functions also requires a decimal point , Then there is ambiguity ( Strings and Booleans don't have this trouble ).

In this case , We can use brackets () Wrap up the numbers , Such as (123).toString(); Or use two consecutive decimal points .. To call a function , Such as 123..toString().

p. That's weird

Since the string is not an object , So why do strings have properties and methods ?

Think about it. , Numbers are numbers , How can there be a way with numbers ?

It's really not logical , But it contradicts the reality .

Editor's Note it ???

Surrogate messenger (I can't translate this)

The answer is announced. ~

dark In the operation

In string (string) For example , When we read string properties or methods in code , JavaScript Will perform the following operation silently :

  1. Pass the string through new String() To create a temporary wrapper object instance ;
  2. Execute our code logic by creating objects ( Read properties or execute functions );
  3. Temporary objects are no longer used , Can be destroyed .

Like the chestnuts below :

let a = 'chenpipi';
console.log(a); // "chenpipi"
// ------------------------------
let b1 = a.length;
console.log(b1); // 8
// The above code is equivalent to :
let b2 = (new String(a)).length;
console.log(b2); // 8
// ------------------------------
let c1 = a.toUpperCase();
console.log(c1); // "CHENPIPI"
// The above code is equivalent to :
let c2 = (new String(a)).toUpperCase();
console.log(c2); // "CHENPIPI"

Numbers (number) And Boolean (boolean) Empathy , But the numbers go through new Number() To create temporary objects , Boolean values are determined by new Boolean() To create .

Except for the example above , The most powerful proof , It's their constructor :

'chenpipi'.constructor === String; // true
(12345).constructor === Number; // true
true.constructor === Boolean; // true

All this is JavaScript Done in the dark , And the temporary objects generated in the process are all disposable ( Throw it when you use it ).

primary Come so

wuhu , That makes sense !

This explains why we can access properties and methods on strings , But you can't add or modify attributes .

That's because our actual goal is JavaScript Temporary objects created , Not the string itself !

So our addition or modification is actually effective , It's just that It's in effect on the temporary object

Just like this. :

// In the code :
let a = 'chenpipi';
a.name = ' Wu Yanzu ';
console.log(a.name); // undefined
// amount to :
let a = 'chenpipi';
(new String(a)).name = ' Wu Yanzu ';
console.log(a.name); // undefined
// amount to :
let a = 'chenpipi';
let temp = new String(a);
temp.name = ' Wu Yanzu ';
console.log(a.name); // undefined

summary (Summary)

above , This is the whole content of this article .

Finally, let's summarize :

  1. Most primitive types have a corresponding wrapper object ;
  2. Some packaging objects can be new, Some can't ;
  3. Wrapper objects are generally used for explicit type conversion ;
  4. Objects have properties and methods ;
  5. There are no properties or methods on the original values ;
  6. There can't be attributes or methods on the original value ;
  7. But we can manipulate the original values just like we manipulate objects ;
  8. This is because JavaScript When executing code, make small moves secretly ;
  9. JavaScript Temporary wrapper objects are used to perform operations on the original values .

We don't pay much attention to it when we write code , In fact, it doesn't affect our code .

therefore , This article is for nothing ?

yes , It's not all ~

Enemy and know yourself , The mutant .

Learn these useless little knowledge , That's right. JavaScript Have a deeper understanding , At least it can be used to blow leather ( Manual formation ~).


Related information

《JavaScript Advanced programming ( The first 4 edition )》

《JavaScript Authoritative guide ( The first 6 edition )》

Primitive - MDN:https://developer.mozilla.org/en-US/docs/Glossary/Primitive

The history of “typeof null”:https://2ality.com/2013/10/typeof-null.html


Portal

Wechat tweet version

Personal blog : Rookie Inn

Open source Homepage : Tangerine peel

Eazax Cocos Game development kit


Share more

《Cocos Creator performance optimization :DrawCall》

《 stay Cocos Creator It's a cool radar map 》

《 use Shader Write a perfect wave 》

《 stay Cocos Creator Manage pop ups gracefully and efficiently 》

《Cocos Creator Source code interpretation : Engine start and main loop 》

《JavaScript Memory details & Analysis Guide 》

《Cocos Creator Editor Extension :Quick Finder》


official account

Rookie Inn

I'm tangerine peel , A game developer who is still learning , One who loves sharing Cocos Star Writer.

This is my personal official account. , Focus on but not limited to game development and front-end technology sharing .

Every original article is very attentive , Your attention is the driving force of my originality !

Input and output.

copyright:author[Tangerine peel],Please bring the original link to reprint, thank you. https://en.javamana.com/2022/175/20210804144345172g.html