preface

I interviewed several developers before. They have done a lot of projects and have good ability, but found that js foundation was not solid, so I decided to write this basic article about javascrip data type. In fact, it was not only because OF the interview with them, I had been abused in the interview before. The interviewer said the most impressive line I remember to this day.

Foundation is very important, only a good foundation will be few bugs, most of the bugs are not solid foundation caused.

Koala is dedicated to sharing the complete Node.js technology stack, from JavaScript to Node.js, to back-end database. Wish you become an excellent senior Node.js engineer. [Programmer growth refers to north] Author, Github blog open source project github.com/koala-codin…

Here are two interview questions and answers related to the basis of our company’s data types, if you can both get them right and know why (you can choose to ignore this article) :

// Type conversion issues
var bar=true;
console.log(bar+0);
console.log(bar+"xyz");
console.log(bar+true);
console.log(bar+false);
console.log('1'>bar);
console.log(1+'2'+false);
console.log('2' + ['koala'.1]);

var obj1 = {
   a:1.b:2
}
console.log('2'+ obj1);var obj2 = {
    toString:function(){
        return 'a'}}console.log('2'+obj2)

Truexyz 2 1 false 12false 2koala,1 2[object object] 2a
Copy the code
// Scope and NaN
var b=1;
function outer(){
    var b=2;
    function inner(){
        b++;
        console.log(b);
        var b=3;
    }
    inner();
}
outer();
// Outputs the result NaN
Copy the code

This article will analyze and explain from the perspective of an interviewer asking questions

Js data type

Interviewer: What are the data types in javascript?

JavaScript has seven built-in data types, including primitive and object types.

Basic types of

There are six basic types:

  • String (string)
  • Boolean (Boolean)
  • Number = number
  • A symbol is a symbol.
  • Null
  • Undefined – undefined

Note:

  1. The Primitive types — string, Number, Boolean, and null — are referred to as Primitive types.

  2. Symbol is a new data type in ES6. Symbol represents a unique value and is generated by calling the symbol function. Since the generated symbol value is the original type, the symbol function cannot be called using new.

  3. Null and undefined are generally considered special values, and these two types of values are unique in themselves.

Object type

Object types are also called reference types. Array and function are subtypes of objects. Logically, an object is an unordered collection of attributes and a container for various values. Object values store reference addresses, so unlike the immutable nature of primitive values, object values are mutable.

Js weakly typed language

Interviewer: Tell me about your understanding that javascript is a weakly typed language?

JavaScript is a weakly typed language, and when JavaScript declares a variable, there is no pre-determined type. The type of a variable is the type of its value. That is to say, the current type of a variable is determined by its value. This process might have done something to cast it. While the fact that weak typing does not require pre-typing is both convenient and confusing, it is important to understand the principles of type conversion in order to take full advantage of this feature.

Cast rules in js

Interviewer: Casting is a very buggy aspect of javascript. Do you know the rules for casting?

Note: The rules are best matched with the following when the conversion occurs. Use these rules for better results.

ToPrimitive(Convert to original value)

ToPrimitive does not convert the original type, only for reference type (Object), its purpose is to convert the reference type (object) to non-object type, that is, the original type.

The ToPrimitive operator takes a value and an optional expected type as an argument. The ToPrimitive operator converts a value to a non-object type, and if the object has the ability to be converted to more than one primitive type, that type can be implied with an optional expected type.

The original type of the converted result is determined by the desired type, which is essentially the type we passed. It’s easier to look down here. The ToPrimitive method looks something like this.

/ * * *@obj Object to be converted *@type The original data type to which you want to convert, optional */
ToPrimitive(obj,type)
Copy the code
Description of different values of type
  • The type ofstring:
  1. First callobjthetoStringMethod, if is the original value, thenreturnOtherwise, proceed to Step 2
  2. callobjthevalueOfMethod, if is the original value, thenreturnOtherwise, proceed to Step 3
  3. throwTypeErrorabnormal
  • The type ofnumber:
  1. First callobjthevalueOfMethod, if is the original value, thenreturnOtherwise, proceed to Step 2
  2. callobjthetoStringMethod, if is the original value, thenreturnOtherwise step 3
  3. throwTypeErrorabnormal
  • The type parameter is null
  1. The object ofDate, type is set toString
  2. Otherwise, type is set toNumber
Date Data type special description:

For the Date data type, we expect more of a string after it is converted to a time than a millisecond value (timestamp). If it is number, the corresponding millisecond value is taken, which is obviously more of a string. For other types of objects, the operation is based on the value type.

ToPrimitiveconclusion

The type parameter is optional. If specified, the ToPrimitive type is converted to the specified type. If not specified, the ToPrimitive type is converted to the specified type. When type type is specified, it depends on the following two conversions.

toString

Object.prototype.toString()

The toString() method returns a string representing the object.

Each object has a toString() method, which is called automatically when the object is represented as a text value or when the object is referenced as a desired string.

Keep in mind that valueOf() and toString() will call themselves in certain situations.

valueOf

The object.prototype.valueof () method returns the original valueOf the specified Object.

JavaScript calls the valueOf() method to convert an object to a valueOf its primitive type (numeric, string, and Boolean). But we rarely need to call this function ourselves; valueOf methods are usually called automatically by JavaScript.

ValueOf implementations for different built-in objects:

  • String => Returns a String value
  • Number => Returns the Number value
  • Date => returns a number, the time value, and the content of the string is implementation-dependent
  • Boolean => Returns Boolean’s this value
  • Object => Returns this

The contrast code is a little clearer:

var str = new String('123');
console.log(str.valueOf());/ / 123

var num = new Number(123);
console.log(num.valueOf());/ / 123

var date = new Date(a);console.log(date.valueOf()); / / 1526990889729

var bool = new Boolean('123');
console.log(bool.valueOf());//true

var obj = new Object({valueOf:() = >{
    return 1
}})
console.log(obj.valueOf());/ / 1
Copy the code

Number

Number operator conversion rules:

  • nullConversion of 0
  • undefinedconvertNaN
  • trueConvert to 1,falseConversion of 0
  • String conversion follows the numeric constant rule, return on conversion failure NaN

The ToPrimitive conversion is called. If type is set to number, go back to the ToPrimitive conversion.

String

String operator conversion rules

  • nullconvert'null'
  • undefinedconvertundefined
  • trueconvert'true'.falseconvert'false'
  • Numeric conversion follows a general rule, using exponential form for extremely small numbers

Note: The object is converted to its original value first, and the ToPrimitive conversion is called, where type is specified as string. Continue back to ToPrimitive for conversion (there are conversion rules to ToPrimitive).

String(null)                 // 'null'
String(undefined)            // 'undefined'
String(true)                 // 'true'
String(1)                    / / '1'
String(-1)                   // '-1'
String(0)                    / / '0'
String(-0)                   / / '0'
String(Math.pow(1000.10))    // '1e+30'
String(Infinity)             // 'Infinity'
String(-Infinity)            // '-Infinity'
String({})                   // '[object Object]'
String([1[2.3]])            / / '1, 2, 3'
String(['koala'.1])          //koala,1
Copy the code

Boolean

ToBoolean operator conversion rules

All values are true except the following six:

  1. undefined
  2. null
  3. 0
  4. 0 or + 0
  5. NaN
  6. “(empty string)

Any value other than false is true. This includes that all objects (including empty objects) are converted to true, even the corresponding New Boolean(false) object is true

Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean(' ') // false

Boolean({}) // true
Boolean([]) // true
Boolean(new Boolean(false)) // true
Copy the code

Js conversion rules are applied in different scenarios

The interviewer asks: You know the rules of what to convert to, but what to convert under what circumstances?

When is it automatically converted to string

  • In the absence of an object

    Automatic conversion of strings occurs mainly during string addition operations. When one value is a string and the other is a non-string, the latter is converted to a string.

'2' + 1 / / '21'
'2' + true // "2true"
'2' + false // "2false"
'2' + undefined // "2undefined"
'2' + null // "2null"
Copy the code
  • When there are objects and objects+when
/ / the toString object
var obj2 = {
    toString:function(){
        return 'a'}}console.log('2'+obj2)
// output result 2a

// Regular objects
var obj1 = {
   a:1.b:2
}
console.log('2'+ obj1);// Output result 2[object object]

// Several special objects
'2' + {} // "2[object Object]"
'2' + [] / / "2"
'2' + function (){} // "2function (){}"
'2' + ['koala'.1] // 2koala,1
Copy the code

An example of the following ‘2’+obj2 is as follows:

  1. On the left forstring.ToPrimitiveThe original value does not change after conversion
  2. Same thing for the right-hand sideToPrimitivePerforms a raw value conversion because the specified type isnumber,ToPrimitiveConversion of callobj2.valueof(), not the original value, proceed to step 3
  3. calltoString() return 'a'
  4. Both sides of the symbolstring, and it is+The number operator is usedStringRule conversion tostringType concatenation
  5. The output2a

An example of the following ‘2’+obj1 is as follows:

  1. On the left forstring.ToPrimitiveConversion to the original value does not change
  2. Same thing for the right-hand sideToPrimitivePerforms a raw value conversion because the specified type isnumber,ToPrimitiveConversion of callobj2.valueof(),{ a: 1, b: 2 }
  3. calltoString() return [object Object]
  4. Both sides of the symbolstring, and the + operator is usedStringRule conversion tostringType concatenation
  5. The output2[object Object]

The conversion rules for several special objects in the code are basically the same, so you can think about the flow.

Note: Regardless of whether an object is an object or not, there is a conversion to the original value, known as the ToPrimitive conversion, but the original type does not change until the object type is converted.

What can go wrong with string conversion development:

var obj = {
  width: '100'
};

obj.width + 20 / / "10020"

Copy the code

Expected result 120 Actual result 10020

When is it automatically converted to Number

  • The addition operator, but no String, is preferentially converted to Number

    Example:

    true + 0 / / 1
    true + true / / 2
    true + false / / 1
    Copy the code
  • All operators, except the addition operator, automatically convert the operation to a number.

Example: “`javascript ‘5’ – ‘2’ // 3 ‘5’ * ‘2’ // 10 true – 1 // 0 false – 1 // -1 ‘1’ – 1 // 0 ‘5’ * [] // 0 false / ‘5’ // 0 ‘abc’ – 1 // NaN null + 1 // 1 undefined + 1 // NaN

/ / unary operator (attention) + 'ABC' / / NaN - 'ABC' / / NaN + 1 - false true / / / / 0 ` ` `Copy the code

Note: null is 0 when converted to a value, and undefined is NaN when converted to a value.

The equal sign is also placedNumberThere are special instructions

The == abstract equality comparison is different from the + operator in that it is no longer String first, but Number first. Here is an example of x == y

  1. ifx.yAre allnumberDirect comparison

Nothing more to explain

1= =2 //false
Copy the code
  1. If there are objects,ToPrimitive()The type ofnumberDo the conversion and then do the subsequent comparison
var obj1 = {
    valueOf:function(){
        return '1'}}1 == obj1  //true
// convert obj1 to its original value and call obj1.valueof ()
// return the original value '1'
//'1'toNumber gets 1 and compares 1 == 1[] = =! []//true
//[] as an object ToPrimitive gets"
/ /! [] converts to 0 as Boolean
/ / '= = 0
// Convert to 0==0 //true
Copy the code
  1. There arebooleanAccording to theToNumberwillbooleanConvert to 1 or 0, and then compare
// Boolean first converts to number, then returns 1
//3 == 1 false
//0 == 0 true
3= =true // false
'0'= =false //true
Copy the code

4. If x is string and y is number, x is converted to number for comparison

//'0' toNumber() gets 0
//0 == 0 true
'0'= =0 //true
Copy the code

When do Boolean conversions take place

  • Boolean comparison
  • if(obj) , while(obj) Equal-judgment or ternary operators can only contain Boolean values

Each value in the condition section is equivalent to false, which becomes true when the negation operator is used

if(!undefined&&!null&&!0&&!NaN&&!' '
) {
  console.log('true');
} // true

// The following two cases are also converted to Booleans
expression ? true : false!!!!! expressionCopy the code

Data type judgment in js

Interviewer asks: How do you determine data types? How do you determine whether a value is an array type or an object?

Three ways, typeof, instanceof respectively, and the Object. The prototype. The toString ()

typeof

The Typeof operator is used to determine which base type a value belongs to.

typeof 'seymoe'    // 'string'
typeof true        // 'boolean'
typeof 10          // 'number'
typeof Symbol(a)// 'symbol'
typeof null        // 'object' is not null
typeof undefined   // 'undefined'

typeof {}           // 'object'
typeof []           // 'object'
typeof(() = > {})    // 'function'
Copy the code

As you can see from the output of the code above,

  1. nullThere is an error in the judgment of the results obtained

If typeof is used, null results in object

  1. The operator determines the type of an object and its subtypes, such as functions (callable objects), arrays (ordered indexed objects), and so onobjectResults.

TypeOf has some limitations for determining types, in the case of object subtypes and null.

instanceof

Object types can also be determined by the instanceof operator, which tests whether the constructor’s prototype appears on the prototype chain of the object being tested.

[] instanceof Array            // true
({}) instanceof Object         // true
(() = >{}) instanceof Function   // true
Copy the code

Copy code Note: Instanceof is not a panacea. Here’s an example:

let arr = []
let obj = {}
arr instanceof Array    // true
arr instanceof Object   // true
obj instanceof Object   // true
Copy the code

In this case, the arR Array is an instance of new Array(), so arr.__proto__ === array. prototype. Array is an Object subtype. Array.prototype.__proto__ === Object.prototype, so the Object constructor is on the prototype chain of arR. So instanceof still can’t elegantly determine whether a value is an array or an ordinary object.

Object.prototype.__proto__ === null arr instanceof null should also be true. This confirms that the typeof NULL result as object is really just a javascript bug.

Object. The prototype. The toString () can be said to be the judge JavaScript data types in the ultimate solution, specific usage, please see the following code:

Object.prototype.toString.call({})              // '[object Object]'
Object.prototype.toString.call([])              // '[object Array]'
Object.prototype.toString.call(() = > {})        // '[object Function]'
Object.prototype.toString.call('seymoe')        // '[object String]'
Object.prototype.toString.call(1)               // '[object Number]'
Object.prototype.toString.call(true)            // '[object Boolean]'
Object.prototype.toString.call(Symbol())        // '[object Symbol]'
Object.prototype.toString.call(null)            // '[object Null]'
Object.prototype.toString.call(undefined)       // '[object Undefined]'

Object.prototype.toString.call(new Date())      // '[object Date]'
Object.prototype.toString.call(Math)            // '[object Math]'
Object.prototype.toString.call(new Set())       // '[object Set]'
Object.prototype.toString.call(new WeakSet())   // '[object WeakSet]'
Object.prototype.toString.call(new Map())       // '[object Map]'
Object.prototype.toString.call(new WeakMap())   // '[object WeakMap]'
Copy the code

We can see that this method returns the exact object type for any type of value passed in. The usage is straightforward, but there are a few points to understand:

  • The method is essentially a dependencyObject.prototype.toString() Method to get the internal properties of the object[[Class]]
  • Passing in the primitive type makes it possible to determine the result because the value is wrapped
  • nullundefinedThe ability to output results is handled by the internal implementation

NaN Summary

NaNThe concept of

NaN is a property of a global object, NaN is a special type of Number.

When to return to NaN (the second problem from the beginning has also been solved)

  • Infinity over infinity
  • Take the square root of any negative number
  • Arithmetic operators are used with operands that are not numbers or cannot be converted to numbers
  • Strings are parsed into numbers

Some examples:

Infinity / Infinity;   // infinity divided by infinity
Math.sqrt(-1);         // Take the square root of any negative number
'a' - 1;               // Arithmetic operators are used with operands that are not numbers or cannot be converted to numbers
'a' * 1;
'a' / 1;
parseInt('a');         // The string is parsed into numbers
parseFloat('a');

Number('a');   //NaN
'abc' - 1   // NaN
undefined + 1 // NaN
// Unary operator
+'abc' // NaN
-'abc' // NaN
Copy the code

myth

toStringandStringThe difference between

  • toString
  1. ToString () converts all data to strings, but null and undefined do not.

    console.log(null.toString())
    TypeError: Cannot read property 'toString' of null
    
    console.log(undefined.toString())
    TypeError: Cannot read property 'toString' of undefined
    Copy the code
  2. ToString () parentheses can contain numbers, representing the base system

    Binary:.tostring (2);

    Octal:.tostring (8);

    Decimal:.tostring (10);

    Hexadecimal:.tostring (16);

  • String
  1. String() can convert null and undefined to strings, but not to base strings

    console.log(String(null));
    // null
    console.log(String(undefined));
    // undefined
    Copy the code

communication

Follow the public account: “Programmer growth refers to north”, for more selected articles

Personal public number technology stack

Qr code of official account