JS data types — Concepts

1. What are the original data types of JS? What are the cited data? And how do they store it?

(1) There are seven original basic types in JS, which are:

Boolean 2. number 3. string 4. null 5. undefined 6. bigINT -- Is a numeric type of data. It can represent an integer in any precision format. The largest number can be stored and manipulated safely. Even if the number is outside the safe integer range that the number type can represent. 7. Symbol - represents unique and immutable data types created to resolve possible global variable conflicts.Copy the code

Bigint and Symbol are new data types in ES6

(2) Reference data types in JS:

The Object ---- contains the common Object Object Array Object -Array, function Object -function, Date Object -Date, regular Object -RegExp, and Math Object -MathCopy the code

(3) How to store data in JS:

Before introducing how data is stored, let's introduce the concept of stacks and heaps. The concepts of heap and stack exist in memory within data structures and operating systems:Copy the code
In data structures:
The data storage mode of stack is first in last out. The heap is a priority queue, sorted by priority, which can be specified by size. A complete binary tree is an implementation of a heap.Copy the code
In the operating system:
The stack area memory is automatically allocated and released by the compiler to store function parameter values, local variable values and so on. Heap memory is usually allocated and freed by programmers or reclaimed by garbage collection mechanisms.Copy the code
Now that you know about stacks and heaps, let’s take a look at how JS stores data.
Primitive data is stored in a stack (stack). Reference data is stored in a stack and in a heap, where variable identifiers are stored in the stack and Pointers to heap memory data are stored in the heap.Copy the code
So why does JS store data the way it does? Or why can’t reference data be on the stack?
A basic data type is created with a defined size, and no method can change the value of the base type (such as string). It is accessed by value, meaning you can manipulate the actual value stored in the variable. ② The size of a reference data type (object) cannot be determined when it is created, and we can change the value of the reference type. We can dynamically add attributes and methods to the reference type. (3) The size of stack memory is determined at creation time, because base data types are also determined at creation time (usually not large), and reference data types are not determined at creation time if they are too large. Will affect the stack of data storage, thereby affecting the performance of the program.Copy the code

2. Use actual code to understand data storage and operation

Take a look at the code below and explain why:

function test(person) {
  person.age = 26
  person = {
    name: 'hzj',
    age: 18
  }
  return person
}
const p1 = {
  name: 'fyq',
  age: 19
}
const p2 = test(p1)
console.log(p1) // -> ?
console.log(p2) // -> ?

Copy the code

Results:

P1: {name: "fyq", age: 26} p2: {name: "HZJ", age: 18}Copy the code

The reason:

The test argument is the memory address of person's P1 object. The call to Person. age does change the value of P1, but then Person becomes the address of another memory space and returns the address of that memory space to P2Copy the code

3. Is NULL an object? Why is that?

Although typeof NULL outputs object, this is a long-standing bug in JS, because js stores type information in the machine code at the bottom 1-3 bits: 000-- object 010-- float 100-- float 110-- Boolean 1: integer NULL: all machine code is 0, so typeof treats NULL as an object undefined :-2^30Copy the code

4. Why doesn’t 0.1+0.2 equal 0.3? How do I make them equal

Reason: Js stores data in binary form, so when the computer computs 0.1+0.2, it is actually calculating the binary sum of two numbers. And 0.1 binary is 0.00011001100... (1100 loop) 0.2 binary is 0.0011001100... The Number type can only use 64 bits of fixed length double floating-point numbers. Double floating-point numbers can hold up to 52 bits, truncating the Number of the infinite loop binary. ToFixed (num) = 0.30000000000000004Copy the code

5. What is the basic wrapper type of JS

In JS, the primitive type has no attributes and methods, but in order to facilitate the operation of the primitive type value, js will implicitly convert the primitive type value to object reference type and basic wrapper type in the background when calling the attribute or method of the primitive type attribute. The main difference is the object life cycle: Automatically created primitively wrapped type objects exist only for the moment a line of code is executed and then are destroyed immediately.Copy the code
var s1 = 'some text'; // => var s1 = new String('some text'); var s2 = s1.substring(5); // => var s2 = s1.substring(5); // s1 = null; Destroy the instance; Background automatic executionCopy the code
Js can also convert a primitive type to a wrapper type using the Object function explicit and new operators, or flip a wrapper type to a primitive type using the valueOf methodCopy the code
var a = 'abc'
var b = Object(a)//String{'abc'}
var c = b.valueOf() // 'abc'
Copy the code
Explain why “1”.tostring () can be called.
Var s = new Object('1'); var s = new Object('1'); var s = new Object('1'); s.toString(); s = null;Copy the code

6. Some methods for the base wrapper type String

ValueOf ()-- returns the original valueOf the string object toString()-- returns the string toLocalString()-- returns the local form string 2. CharAt --String. CharAt (subscript)-- Returns the subscript character charCodeAt --String. CharCodeAt (subscript)-- Returns the ASCII value of the String. IndexOf -- str.indexof (substr,start)-- return the position at which substr first appears in STR from start, 1 lastIndexOf-- str.lastIndexof (substr,start)-- function as indexOf, find from back to front. Search - STR. Search (substr | RegExp) - returns the substr position of the first appeared in the STR or regular expression The match - STR. Match (substr | RegExp) - returns the lookup in the the STR substr | rexgep value, if the regular global matching may be returned array. Substring --str.substring(start,end)-- returns a new string generated by intercepting the position of the string [start,end] -- same as the array method in slice substr-- str.substr(start,end) Lenght)-- returns the substring slice() split from the specified position to the specified length in STR --str.split(split character, limitLength)-- returns an array split with delimiters, Repeat --str.repeat(n)-- returns the string trim that repeats the original string n times --str.trim()-- returns the string with whitespace removed from the beginning and end of STR EndsWith () : includes() : returns a Boolean value indicating whether the parameter string is found. Returns a Boolean value indicating whether the parameter string is at the end of the source string.Copy the code

2. Js data type – detection section

1. Can typeof correctly determine the type?

For primitive types, except for NULL, typeof can be called to display the correct type.

typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'


Copy the code

But for reference data types, it says “object” except for functions.

typeof [] // 'object'
typeof {} // 'object'
typeof console.log // 'function
Copy the code

2.instanceof

How it works: Instanceof is determined by whether the type of prototype can be found in its prototype chain

3. Manually implement the Instanceof principle

4.. object.proyotype.toString.call()

Object. The prototype. ToString. The call Object prototype method toString (), to determine the data type

5.Object. Is () and ==, ===?

If the types of the two sides are not the same, the type conversion will be forced. If the types of the two sides are not the same, the type conversion will not be forced. False Object.is() is returned. It handles special cases where -0 and +0 are not equal, and two Nans are considered equal.Copy the code

JS data types — conversion section

1. [] = =! [] What was the result? Why is that?

The result is true

== both sides need to be converted to numbers in the comparison left empty array to number 0 right! [] is converted to bool. [] is a reference type with a Boolean value of true. [] is false. False converts to a number 0, so 0==0//trueCopy the code

2. There are several types of js conversions

In JS, there are only three types of conversions:

1. Convert to numbers 2. Convert to Booleans 3Copy the code

Specific rules:

3. What is the process for converting an object to a primitive type?

To prepare theCopy the code

Talk about the understanding of closures

What is a closure?

A closure is a function that has access to variables in the scope of another function. The most common way to create a closure is to create another function within a function that has access to local variables of the current function.Copy the code

Closures have two common uses

1. Closures allow us to access variables inside a function from outside. By using closures, you can call closure functions from outside, access variables inside the function from outside, and in this way, create private variables. 2. Closures can keep a variable object in the context of a finished function in memory. Because the closure function keeps a reference to the variable object, the variable object is not reclaimed in memory.Copy the code

The nature of closures?

The essence of a closure is a special application of a chain of scope where there is a reference to a parent scope in the current environment.Copy the code

What causes closures?

First, you need to understand the concept of scope chains.Copy the code

Understanding scope chains:

In ES5, there are only two types of scope ———— global scope and function scope. When accessing a variable, the interpreter first looks for the identifier in the current scope. If the variable is not found, it is a free variable. Until the identifier is found or the global scope window is accessed, this layer of relationship is called the scope chain. Understanding the scope chain allows you to understand why closures occur ———— that is, the current execution environment has references to the parent scope.Copy the code

Look at an example:

function f1() { var a = 2 function f2() { console.log(a); //2 } return f2; } var x = f1(); x(); At this point, the reference to the f2 function contains the scope of window,f1, and f2, so f2 has access to variables in the f1 scopeCopy the code

Is it only the return function that generates a closure? Going back to the essence of closures, we simply need the current environment to have a reference to the parent scope. Such as:

var f3; function f1() { var a = 2 f3 = function() { console.log(a); } } f1(); f3(); Assigning a value to F3 is equivalent to giving F3 access to the window, F1, and F3 scopes, so it still forms a closure. The form has changed, but the essence has not changed.Copy the code

What are the representations of closures?

Once you understand the nature, let’s see where we can use closures.

  1. Returns a function, as we just exemplified
  2. Passed as a function parameter
var a = 1; function foo(){ var a = 2; function baz(){ console.log(a); } bar(baz); } function bar(fn){// This is the closure, fn has the current scope and its parent scope access rights fn(); } // Print 2 instead of 1 foo();Copy the code

3. Whenever you use callbacks in timers, event listeners, Ajax requests, cross-window communication, Web Workers, or any asynchrony, you’re actually using closures. The following closures hold only the window and the current scope

// timer setTimeout(function timeHandler(){console.log('111'); }, 100) // Event Listener $('#app').click(function(){console.log('DOM Listener'); })Copy the code

4.IIFE(execute function expressions immediately) creates closures that hold both the global scope and the scope of the current function, so global variables can be used

Talk about the understanding of prototype chain

1. What is the relationship between the prototype object and the constructor

In JS, every time a function is defined, angel comes with a prototype property that points to the prototype object of the instance created by calling the constructor. Every object inherits properties from the prototype and when a function is called new, that function becomes a constructor, returns a new instance object, that instance object has a _proto_ property, GetPrototypeOf (obj)) this property points to the constructor's prototype object. So both the instance object and the constructor can point to the stereotype, so are there properties pointing to the constructor or the instance? Pointing to an instance is not, because a constructor can generate multiple instances, but stereotypes can point to constructors, and each stereotype has a constructor attribute pointing to the associated constructor.Copy the code

2. Understanding of prototype chain

Js points to the parent Object through _proto_ until it points to Object, thus forming a prototype-pointing chain, that is, a prototype-pointing chain. When an object property is read, if it cannot be found, it looks for the property in the stereotype associated with the object. If it cannot be found, it looks for the stereotype, all the way to the top levelCopy the code

Object hasOwnProperty() to check whether the object itself contains the property. Using in to check whether the object contains a property, if not in the object but in the prototype chain, also returns trueCopy the code

3. Does a real object inherit properties from its prototype?

Said that every object in front of the "inherit" from its prototype object attribute, actually inheritance means that copy operation, js doesn't make copies of the default attributes of the object, however, on the contrary js just create an association between two objects, such an object can be accessed through entrust another object's properties and functions, so its called inheritance, Delegation is more accurate.Copy the code

How does JS inherit first? By the way, talk about the disadvantages of each method

1. Prototype chain inheritance

function Parent(){ this.name='zw'; } parent.prototype.getName = function(){console.log(this.name)} Function Child(){} child.prototype =new parent () Var child1 = new child (); var child1 = new child (); var child1 = new child (); Console. log(child1.getName()) // zW uses the prototype chain to make the child inherit the attributes of the parent, and uses the prototype chain to make the child inherit the parent's prototypeCopy the code
Question:

1. Attributes of a reference type are shared by all instances, for example:

function Parent () { this.names = ['kevin', 'daisy']; } function Child () { } Child.prototype = new Parent(); var child1 = new Child(); child1.names.push('yayu'); console.log(child1.names); // ["kevin", "daisy", "yayu"] var child2 = new Child(); console.log(child2.names); // [" Kevin ", "Daisy ", "yayu"] Cause: ???? Take a look at what the new operator does: 1. Create a brand new object 2. This new object will be called by the [[prototype]] connection 3. This new object will bind to the function call this 4. If the function returns no other object, then the function call in the new expression will automatically return the new object, so both child new will go to Prototype and link to the new Parent.Copy the code

2. When creating a Child, do not pass any parameter to the Parent

2. Borrowed constructor inheritance (classical inheritance)

function Parent () {
    this.names = ['kevin', 'daisy'];
}

function Child () {
    Parent.call(this);
}

var child1 = new Child();

child1.names.push('yayu');

console.log(child1.names); // ["kevin", "daisy", "yayu"]

var child2 = new Child();

console.log(child2.names); // ["kevin", "daisy"]
Copy the code
Advantages:

2. You can pass a reference from child to Parent, for example

function Parent (name) {
    this.name = name;
}

function Child (name) {
    Parent.call(this, name);
}

var child1 = new Child('kevin');

console.log(child1.name); // kevin

var child2 = new Child('daisy');

console.log(child2.name); // daisy
Copy the code
Disadvantages:

Methods are defined in the constructor and are created each time an instance is created. (Method points to a different address in the instance)

3. Combinatorial inheritance

Archetypal chain inheritance and classical inheritance

 function Parent (name) {
    this.name = name;
    this.colors = ['red', 'blue', 'green'];
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child (name, age) {

    Parent.call(this, name);

    this.age = age;

}

Child.prototype = new Parent();
Child.prototype.constructor = Child;

var child1 = new Child('kevin', '18');

child1.colors.push('black');

console.log(child1.name); // kevin
console.log(child1.age); // 18
console.log(child1.colors); // ["red", "blue", "green", "black"]

var child2 = new Child('daisy', '20');

console.log(child2.name); // daisy
console.log(child2.age); // 20
console.log(child2.colors); // ["red", "blue", "green"]
Copy the code

Advantages: Combining the advantages of stereotype chain inheritance and constructors is the most common inheritance pattern in JavaScript.

4. Original type inheritance

function createObj(o) {
    function F(){}
    F.prototype = o;
    return new F();
}
Copy the code

Create is a mock implementation of ES5 Object.create that uses the passed Object as a prototype for the created Object.

Disadvantages: Attributes containing reference types always share corresponding values, as with stereotype chain inheritance.

var person = {
    name: 'kevin',
    friends: ['daisy', 'kelly']
}

var person1 = createObj(person);
var person2 = createObj(person);

person1.name = 'person1';
console.log(person2.name); // kevin

person1.firends.push('taylor');
console.log(person2.friends); // ["daisy", "kelly", "taylor"]
Copy the code

Parasitic inheritance

Create a function that encapsulates the procedure only, does the enhancement object internally in some form, and returns the object

   function createObj(o){
   
      var clone = Objcet.create(o);
      clone.sayname - function(){
          console.log('hi')'
      }
      return clone;
   }
Copy the code

Disadvantages: As with the borrowed constructor pattern, methods are created each time an object is created

Parasitic combinatorial inheritance