JavaScript 根基类型 援用类型 简单赋值 对象援用

发布日期:2019-07-23 19:47:11 阅读数: 285次 来源: 作者:

ECMAScirpt 变量有两种分歧的数据类型:根基类型,援用类型。也有其他的叫法,好比原始类型和对象类型具有方式的类型和不克不及具有方式的类型,还能够分为可变类型和不成变类型,其实这些叫法都是根据这两种的类型特点来定名的,大师爱叫啥就叫啥吧 o(╯□╰)o 。

1.根基类型

根基的数据类型有:undefined,boolean,number,string,null。根基类型的拜候是按值拜候的,就是说你能够操作保留在变量中的现实的值。根基类型有以下几个特点:

1.根基类型的值是不成变得:

任何方式都无法改变一个根基类型的值,好比一个字符串:

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

会发觉原始的name并未发生改变,而是挪用了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

它们不是相等吗?其实这是类型转换== 运算符的学问了,也就是说在用==比力两个分歧类型的变量时会进行一些类型转换。像上面的比力先会把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'};

则这三个对象的在内存中保留的环境如下图:

clipboard.png

3.援用类型的比力是援用的比力

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

上面讲根基类型的比力的时候提到了当两个比力值的类型不异的时候,相当于是用 === ,所以输出是true了。再看看:

var person1 = {};
var person2 = {};
console.log(person1 == person亚博2); // 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,但b中的10与a中的是完全独立的,该值只是a中的值的一个副本,此后,这两个变量能够加入任何操作而彼此不受影响。

clipboard.png

也就是说根基类型在赋值操作后,两个变量是彼此不受影响的。

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

它们的关系如下图:

因而,援用类型的赋值其实是对象保留在栈区地址指针的赋值,因而两个变量指向统一个对象,任何的操作城市彼此影响。

本文由亚博手机app编辑整理亚博手机app