Переменные ECMAScript имеют два различных типа данных:Basic types, reference types. Также существуют другие названия, напримерPrimitive types and object types,Types with methods and types without methods, его также можно разделить наMutable types and immutable types, на самом деле все эти названия основаны на этих двухType characteristicsчтобы назвать их, каждый может называть их как угодно o(╯□╰)o .

1. Базовые типы

Базовые типы данных: undefined, boolean, string, null. Базовые типы — это типы по значению, то есть вы можете оперировать фактическим значением, хранящимся в переменной. Базовые типы имеют следующие характеристики:

1. Значения базовых типов неизменяемы:

Ни один метод не может изменить значение базового типа, например строки:

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

Вы обнаружите, что исходное имя не изменилось; вместо этого после вызова метода toUpperCase() возвращается новая строка.
Давайте рассмотрим другой пример:

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

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

Из приведённого выше кода видно, что мы не можем добавлять свойства и методы к базовым типам, что ещё раз показывает, что базовые типы неизменяемы;

2. Сравнение базовых типов — это сравнение значений:

Они равны только тогда, когда равны их значения.
Но вы можете сделать так:

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

Разве они не равны? На самом деле этоType conversionи==знание оператора ==. То есть, когда с помощью == сравниваются две переменные разных типов, выполняется некоторое преобразование типов. Например, в приведённом выше сравнении true сначала преобразуется в число 1, а затем сравнивается с числом 1, поэтому результат — true. Это потому, что когда типы двух сравниваемых значений различаются, оператор == выполняет преобразование типов, но когда типы обоих значений одинаковы, даже == эквивалентен ===.

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

3. Переменные базовых типов хранятся в области стека (область стека относится к стековой памяти в памяти)

Предположим, имеются следующие переменные базовых типов:

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

Тогда его структура хранения показана ниже:

clipboard.png

Область стека включает идентификатор переменной и значение переменной.

2. Ссылочные типы

Ссылочные типы интереснее и увлекательнее.

В JavaScript, помимо основных типов, перечисленных выше(number,string,boolean,null,undefined)всё остальное — это ссылочные типы, которые также можно назвать объектами. Объекты — это коллекции свойств и методов. То есть ссылочные типы могут иметь свойства и методы, а свойства могут содержать основные типы и ссылочные типы. Давайте рассмотрим некоторые характеристики ссылочных типов:

1. Значения ссылочных типов изменяемы

Мы можем добавлять свойства и методы к ссылочным типам, а также удалять их свойства и методы, например:

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

Приведённый выше код показывает, что ссылочные типы могут иметь свойства и методы, и их можно изменять динамически.

2. Значения ссылочных типов — это объекты, хранящиеся как в стековой памяти, так и в куче

JavaScript отличается от других языков тем, что не позволяет напрямую обращаться к позициям в памяти, то есть не может напрямую работать с пространством памяти объектов. Так с чем же мы работаем? На самом деле мы работаем со ссылками на объекты, поэтому доступ к значениям ссылочных типов осуществляется по ссылке.
Точнее говоря, для хранения ссылочных типов требуется совместная работа как области стека, так и области кучи памяти (область кучи — это куча в памяти). В стековой памяти хранятся идентификатор переменной и указатель на объект в куче, что также можно назвать адресом объекта в куче.
Предположим, есть следующие объекты:

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

Тогда расположение этих трёх объектов в памяти показано ниже:

3. Сравнение ссылочных типов — это сравнение ссылок

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

Когда выше говорилось о сравнении базовых типов, упоминалось, что если типы двух сравниваемых значений совпадают, это эквивалентно использованию ===, поэтому результат — true. Давайте посмотрим ещё раз:

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

Вы, возможно, уже заметили подвох. Выше сравниваются две строки, а ниже — два объекта. Почему объекты, которые выглядят совершенно одинаково, не равны?

Не забывайте: доступ к ссылочным типам осуществляется по ссылке. Иными словами, сравнивается, совпадают ли адреса двух объектов в куче. Очевидно, что person1 и person2 имеют разные адреса в куче:

Итак, это два совершенно разных объекта, поэтому возвращается false;

3. Простое присваивание

При присваивании значения базового типа из одной переменной другой в этой переменной создаётся новое значение, а затем это значение копируется в место, выделенное для новой переменной:

var a = 10;
var b = a;

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

В данный момент в a хранится значение 10. Когда a используется для инициализации b, в b также хранится 10, но 10 в b полностью независимо от 10 в a. Это значение — лишь копия значения в a. После этого обе переменные могут участвовать в любых операциях, не влияя друг на друга.

То есть после операции присваивания для базовых типов две переменные не влияют друг на друга.

4. Ссылка на объект

При присваивании значения ссылочного типа из одной переменной другой копия значения объекта, хранящегося в переменной, также помещается в пространство, выделенное для новой переменной. Как упоминалось ранее при обсуждении ссылочных типов, в переменной хранится адрес объекта в памяти кучи. Поэтому, в отличие от простого присваивания, эта копия значения на самом деле является указателем, и этот указатель указывает на объект, хранящийся в памяти кучи. После операции присваивания обе переменные содержат один и тот же адрес объекта, поэтому обе переменные указывают на один и тот же объект. Следовательно, изменение любой из переменных повлияет на другую:

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

Их взаимосвязь показана ниже:

Следовательно, присваивание ссылочных типов на самом деле является присваиванием указателя на адрес объекта, хранящегося в области стека. Поэтому обе переменные указывают на один и тот же объект, и любая операция повлияет на обе переменные.

Исходная ссылка: https://segmentfault.com/a/1190000002789651