ECMAScript tiene dos tipos de datos diferentes para las variables:Tipos básicos, tipos de referencia. También hay otras formas de llamarlos, por ejemploTipos primitivos y tipos de objeto,Tipos que tienen métodos y tipos que no pueden tener métodos, también se pueden dividir enTipos mutables y tipos inmutables, en realidad, estas denominaciones se basan en estos dos tipos paraCaracterísticas de los tiposnombrarlos, así que cada uno puede llamarlos como quiera o(╯□╰)o.

1. Tipos primitivos

Los tipos de datos primitivos son: undefined, boolean, number, string, null. El acceso a los tipos primitivos es por valor, es decir, puedes operar con el valor real almacenado en la variable. Los tipos primitivos tienen las siguientes características:

1. Los valores de los tipos primitivos son inmutables:

Ningún método puede cambiar el valor de un tipo primitivo, por ejemplo, un string:

var name = 'jozo';
name.toUpperCase(); // 输出 'JOZO'
console.log(name); // 输出  'jozo'

Se puede ver que el `name` original no ha cambiado; en cambio, al llamar al método `toUpperCase()`, se devuelve una nueva cadena.
Veamos otro ejemplo:

var person = 'jozo';
person.age = 22;
person.method = function(){//...};

console.log(person.age); // undefined
console.log(person.method); // undefined

Con el código anterior se puede ver que no podemos agregar propiedades ni métodos a los tipos primitivos, lo que demuestra nuevamente que los tipos primitivos son inmutables;

2. La comparación de tipos primitivos es una comparación de valores:

Solo son iguales cuando sus valores son iguales.
Pero puede que hagas esto:

var a = 1;
var b = true;
console.log(a == b);//true

¿No son iguales? En realidad, esto esConversión de tiposy==un asunto del operador. Es decir, al usar `==` para comparar dos variables de diferentes tipos, se realizan algunas conversiones de tipo. En la comparación anterior, primero se convierte `true` al número 1 y luego se compara con el número 1, por lo que el resultado es `true`. Esto ocurre cuando los tipos de los dos valores comparados son diferentes: el operador `==` realiza conversión de tipo. Pero cuando los tipos de los dos valores son iguales, incluso `==` equivale a `===`.

var a = 'jozo';
var b = 'jozo';
console.log(a === b);//true

3. Las variables de tipos primitivos se almacenan en la región de pila (la región de pila se refiere a la memoria de pila en la memoria).

Supongamos que tenemos las siguientes variables de tipos primitivos:

var name = 'jozo';
var city = 'guangzhou';
var age = 22;

Entonces su estructura de almacenamiento es como se muestra en la siguiente figura:

clipboard.png

La región de pila incluye el identificador de la variable y el valor de la variable.

2. Tipos de referencia

Los tipos de referencia son un poco más divertidos e interesantes.

En JavaScript, además de los tipos primitivos mencionados anteriormente,(number,string,boolean,null,undefined)el resto son tipos de referencia, que también se puede decir que son objetos. Un objeto es una colección de propiedades y métodos. Es decir, los tipos de referencia pueden tener propiedades y métodos, y las propiedades pueden contener tanto tipos primitivos como tipos de referencia. Veamos algunas características de los tipos de referencia:

1. Los valores de los tipos de referencia son mutables

Podemos agregar propiedades y métodos a los tipos de referencia, y también eliminar sus propiedades y métodos, por ejemplo:

var person = {};//创建个控对象 --引用类型
person.name = 'jozo';
person.age = 22;
person.sayName = function(){console.log(person.name);} 
person.sayName();// 'jozo'

delete person.name; //删除person对象的name属性
person.sayName(); // undefined

El código anterior muestra que los tipos de referencia pueden tener propiedades y métodos, y que pueden cambiarse dinámicamente.

2. Los valores de los tipos de referencia son objetos que se guardan simultáneamente en la memoria de pila y en la memoria de montón.

JavaScript, a diferencia de otros lenguajes, no permite acceder directamente a las posiciones de memoria, es decir, no se puede manipular directamente el espacio de memoria de un objeto. Entonces, ¿qué hacemos? En realidad, se manipula la referencia del objeto, por lo que los valores de los tipos de referencia se acceden por referencia.
Para ser precisos, el almacenamiento de los tipos de referencia requiere tanto la región de pila como la región de montón (la región de montón se refiere a la memoria de montón en la memoria). La memoria de la región de pila guarda el identificador de la variable y un puntero al objeto en la memoria de montón, que también se puede decir que es la dirección del objeto en la memoria de montón.
Supongamos que tenemos los siguientes objetos:

var person1 = {name:'jozo'};
var person2 = {name:'xiaom'};
var person3 = {name:'xiaoq'};

Entonces la situación de almacenamiento de estos tres objetos en memoria es como se muestra en la siguiente figura:

3. La comparación de tipos de referencia es una comparación de referencias

var person1 = '{}';
var person2 = '{}';
console.log(person1 == person2); // true

Cuando hablamos de la comparación de tipos primitivos, mencionamos que si los tipos de los dos valores comparados son iguales, equivale a usar `===`, por lo que la salida es `true`. Miremos ahora:

var person1 = {};
var person2 = {};
console.log(person1 == person2); // false

Quizás ya has notado el detalle: arriba se comparan dos strings, mientras que abajo se comparan dos objetos. ¿Por qué dos objetos que parecen idénticos no son iguales?

No olvides que los tipos de referencia se acceden por referencia. En otras palabras, se compara si las direcciones en la memoria de montón de los dos objetos son iguales. Es evidente que `person1` y `person2` tienen direcciones diferentes en la memoria de montón:

Por lo tanto, estos dos son objetos completamente diferentes, y por eso devuelve `false`.

3. Asignación simple

Al asignar un tipo primitivo de una variable a otra, se crea un nuevo valor en esa variable y luego ese valor se copia en la ubicación asignada para la nueva variable:

var a = 10;
var b = a;

a ++ ;
console.log(a); // 11
console.log(b); // 10

En este momento, el valor almacenado en `a` es 10. Cuando se usa `a` para inicializar `b`, el valor almacenado en `b` también es 10, pero el 10 en `b` es completamente independiente del de `a`; ese valor es solo una copia del valor en `a`. A partir de entonces, estas dos variables pueden participar en cualquier operación sin afectarse mutuamente.

Es decir, después de una operación de asignación de tipos primitivos, las dos variables no se afectan mutuamente.

4. Referencia a objetos

Al asignar un valor de tipo de referencia de una variable a otra, también se copia el valor del objeto almacenado en la variable y se coloca en el espacio asignado para la nueva variable. Como mencionamos antes al hablar de los tipos de referencia, lo que se guarda en la variable es la dirección del objeto en la memoria de montón. Por lo tanto, a diferencia de la asignación simple, esta copia del valor es en realidad un puntero, y ese puntero apunta a un objeto almacenado en la memoria de montón. Entonces, después de la operación de asignación, ambas variables guardan la misma dirección de objeto, por lo que ambas variables apuntan al mismo objeto. En consecuencia, cambiar cualquiera de las dos variables afecta a la otra:

var a = {}; // a保存了一个空对象的实例
var b = a;  // a和b都指向了这个空对象

a.name = 'jozo';
console.log(a.name); // 'jozo'
console.log(b.name); // 'jozo'

b.age = 22;
console.log(b.age);// 22
console.log(a.age);// 22

console.log(a == b);// true

Su relación es como se muestra en la siguiente figura:

Por lo tanto, la asignación de tipos de referencia es en realidad la asignación del puntero a la dirección del objeto guardada en la región de pila; así, las dos variables apuntan al mismo objeto y cualquier operación se afecta mutuamente.

Enlace original: https://segmentfault.com/a/1190000002789651