不可变原始值和可变对象引用

不可变的原始值

原始值:undefined null boolen number string 
原始值不可变,既基本数据类型

var s="hello";
s.toUpperCase();//return value="HELLO"
s//原始值未改变
  • 1
  • 2
  • 3
  • 原始值是value的比较,字符串的比较是,长度相等并且每一个索引的字符都相等。
  • 基本类型的变量是存放在栈区的(栈区指内存里的栈内存)
  • 因此比较时只关注栈内存,不涉及到堆内存地址的比较
var name = 'jozo';
var city = 'guangzhou';
var age = 22;
  • 1
  • 2
  • 3

这里写图片描述

栈区存储变量的标识符和变量的值。

可变的对象引用

对象:可修改值可变的,是引用类型,即除基本数据类型外的

var o={x:1};//定义一个对象
o.x=2;//修改属性值
o.y=3;//增添属性值
  • 1
  • 2
  • 3
var a=[1,2,3]//定义一个数组
a[0]=0;
a[0]=4;
  • 1
  • 2
  • 3
var o={x:1},p={x:1};
o==p//=>flase
var a=[1,2],b=[1,2]
a==b//=>flase
  • 1
  • 2
  • 3
  • 4

对象为引用类型,一般和javascript中的基本类型分开,对象为引用的比较,当且仅当引同一基对象时相等

var a=[];//引用空数组的变量
var b=a;//引用同一数组 
b[0]=1;//通过变量b修改引用的数组
a[0];
a===b//=>ture
  • 1
  • 2
  • 3
  • 4
  • 5

将对象(arry)赋值给一个变量,仅仅是赋值的引用值,对象本身并没有复制一次,因此是引用值的比较

比较两数组的函数

function equalArrys(){
if(a.length!=b.length)
return false;
for(var i=0;i<a.length;i++)
    if(a[i]!==b[i])
    return false;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注意

a.length!=b.length;//数组长度的比较
a[i]!==b[i];//数组内元素的比较
a===b//两个完全相同的类型
  • 1
  • 2
  • 3

引用类型的值是同时保存在栈内存和堆内存中的对象 
javascript和其他语言不同,其不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间,那我们操作啥呢? 实际上,是操作对象的引用,所以引用类型的值是按引用访问的。 
准确地说,引用类型的存储需要内存的栈区和堆区(堆区是指内存里的堆内存)共同完成,栈区内存保存变量标识符和指向堆内存中该对象的指针,也可以说是该对象在堆内存的地址。 
假如有以下几个对象:

var person1 = {name:'jozo'};
var person2 = {name:'xiaom'};
var person3 = {name:'xiaoq'};
  • 1
  • 2
  • 3

这里写图片描述

栈区存储变量名和地址指针,堆区存储对象 
因此不能直接比较两相同元素,属性的对象,存在堆内存地址不同的问题

赋值

赋值基本类型 
在从一个变量向另一个变量赋值基本类型时,会在该变量上创建一个新值,然后再把该值复制到为新变量分配的位置上

var a = 10;
var b = a;

a ++ ;
console.log(a); // 11
console.log(b); // 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

此时,a中保存的值为 10 ,当使用 a 来初始化 b 时,b 中保存的值也为10,但b中的10与a中的是完全独立的,该值只是a中的值的一个副本,此后,这两个变量可以参加任何操作而相互不受影响。

这里写图片描述 
也就是说基本类型在赋值操作后,两个变量是相互不受影响的。

对象引用

当从一个变量向另一个变量赋值引用类型的值时,同样也会将存储在变量中的对象的值复制一份放到为新变量分配的空间中。前面讲引用类型的时候提到,保存在变量中的是对象在堆内存中的地址,所以,与简单赋值不同,这个值的副本实际上是一个指针,而这个指针指向存储在堆内存的一个对象。那么赋值操作后,两个变量都保存了同一个对象地址,则这两个变量指向了同一个对象。因此,改变其中任何一个变量,都会相互影响:

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

这里写图片描述 
因此,引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象,任何的操作都会相互影响。必须比较属性和元素

posted @ 2018-03-12 19:57  raindi  阅读(375)  评论(0编辑  收藏  举报