JavaScript引用类型数据

广告位招租
扫码页面底部二维码联系

引用数据类型的变量,是说在内存中保存的值【本文首发于唐霜的博客】本文作者:唐霜,转载请注明出处。是另外一个内存单位的地址的变量。当使用这【转载请注明来源】【关注微信公众号:wwwtangshuangnet】个变量的时候,实际上会使用它所保存的地址【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net所对应的值。javascript中除了基著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net本数据类型以外,所有的复杂结构数据都是由【本文首发于唐霜的博客】【作者:唐霜】object类型衍生而来,无论是数组,还著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。是函数,都属于引用数据类型,在ES6中,【版权所有,侵权必究】【作者:唐霜】引入了class,而class也是obj【本文受版权保护】【未经授权禁止转载】ect而来,因此引用数据类型的本质没有改【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】变。

转载请注明出处:www.tangshuang.net【本文受版权保护】原创内容,盗版必究。原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。

赋值和引用传递转载请注明出处:www.tangshuang.net

【未经授权禁止转载】未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。

在几乎所有的编程语言中都使用等号=进行赋【本文受版权保护】本文版权归作者所有,未经授权不得转载。值,当然,也有使用冒号:进行赋值的,但是【访问 www.tangshuang.net 获取更多精彩内容】【未经授权禁止转载】赋值操作是编程世界里面最常见的操作之一。【版权所有,侵权必究】【访问 www.tangshuang.net 获取更多精彩内容】给变量赋值有两种情况,一种是为变量开辟内【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net存空间,将变量的内容保存到该空间。例如:

【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。
var a = 1;
var b = "my string";

还有一种情况,是为变量开辟内存空间后,将【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。内容写到另外一块复杂的内存空间,将这块内【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。存空间的地址指针保存到变量的内存空间。例【作者:唐霜】【版权所有】唐霜 www.tangshuang.net如:

本文作者:唐霜,转载请注明出处。原创内容,盗版必究。【本文受版权保护】
var obj = {
  name : "Tom",
  age : 10,
  body : {
    head : 1,
    hand : 2,
    foot : 2
  }
};
var fun = function(param) {
  alert(param);
};

而后一种就是引用数据类型。我们通过画内存未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。示意图来表达一个引用数据类型的内存情况:
【本文受版权保护】未经授权,禁止复制转载。 javascript-object-memory

本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】【转载请注明来源】【原创内容,转载请注明出处】

堆和栈转载请注明出处:www.tangshuang.net

本文作者:唐霜,转载请注明出处。【作者:唐霜】未经授权,禁止复制转载。【原创内容,转载请注明出处】【未经授权禁止转载】

变量默认情况下会保存在栈内存中,当变量的【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。值为基本数据类型时,程序能较快的读取到栈【版权所有,侵权必究】【原创不易,请尊重版权】内存中保存的值。而堆内存中的内容则需要通【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。过栈内存中变量名对应的地址去找,因此性能未经授权,禁止复制转载。【作者:唐霜】上慢了很多。也正是因为这个原因,在性能优本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】化时,选择将一个堆内存中保存的数据直接引【作者:唐霜】【未经授权禁止转载】用给一个变量暂时放在栈内存中,例如:

【原创不易,请尊重版权】【作者:唐霜】【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】
var foot = object.body.foot;

当第二次使用foot时,就不必在堆内存中【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。找来找去,节省了很多时间。

【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】

undefined和null【本文首发于唐霜的博客】

【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。【转载请注明来源】

首先来解释null。当一个引用数据类型被未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。声明时,并没有立即为它开辟内存空间,例如著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。

【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。
var obj = new Object();

当没有为它开辟(堆)内存空间时,它的值为【关注微信公众号:wwwtangshuangnet】【访问 www.tangshuang.net 获取更多精彩内容】null,也就是没有保存任何内存地址信息【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。。当这个变量在程序进程中一直保持为nul【作者:唐霜】【版权所有】唐霜 www.tangshuang.netl时,说明它并没有被赋值,所以理论上会被【未经授权禁止转载】【转载请注明来源】垃圾回收机制回收内存。

【版权所有,侵权必究】【作者:唐霜】【作者:唐霜】本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。

接下来是undefined。和引用数据类【原创内容,转载请注明出处】原创内容,盗版必究。型对应,它是一个变量没有被定义时的值,没本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】有被定义的意思是它的数据类型也不确定。由【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net于Javascript中声明一个变量并没本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】有使用int, string, char转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】这种关键字进行声明,所以实际上在声明一个【未经授权禁止转载】未经授权,禁止复制转载。变量时,它默认是没有数据类型的,当初始化【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。它的值时,它也同时拥有了数据类型,用一个未经授权,禁止复制转载。未经授权,禁止复制转载。代码来说明:

【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】
var a;
alert(typeof a); // undefined

上面代码中a被声明,却没有确定数据类型,未经授权,禁止复制转载。原创内容,盗版必究。在内存中的表现就是开辟了内存空间,但还没有赋予具体的内容未经授权,禁止复制转载。。但是,在堆内存中,这个声明并不存在,我【访问 www.tangshuang.net 获取更多精彩内容】【转载请注明来源】们无法使用var b在堆内存中声明一个新【版权所有】唐霜 www.tangshuang.net【作者:唐霜】的变量,为它开辟一个新的空间,所以,下面本文作者:唐霜,转载请注明出处。【作者:唐霜】的情况会略有不同:

本文版权归作者所有,未经授权不得转载。转载请注明出处:www.tangshuang.net【转载请注明来源】
var a;
alert(typeof a);
alert(typeof b);
var c = {};
alert(typeof c.d);
alert(typeof e.f); // error

a和b本质不同,a的值是undefine【本文首发于唐霜的博客】未经授权,禁止复制转载。d,而b并未经声明,非严格模式下被认为是【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】window.b,所以会报undefin【本文受版权保护】【未经授权禁止转载】ed,和下面的c.d一样,但是当使用"use strict"声明为严格模式时,未经声明的b是会报错的未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。。c.d和e.f也不同,因为c是存在的,【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。而c.d并未声明,所以返回undefin原创内容,盗版必究。【作者:唐霜】ed,而e并未经声明,所以严格模式下本身【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。就是会报错,即便没有声明严格模式,e的值著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。为undefined,也不能使用e.f,本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】因为e不是一个引用数据类型。如果在这之前【未经授权禁止转载】未经授权,禁止复制转载。声明var e = null,则报错内容【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net不一样,报错会提示不能获取null.f。本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】这个地方还有一点可以探讨,就是c.d在使【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net用之前并没有执行var c.d来声明c.d,毕竟d也是一个变量,但正是本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】因为d是保存在堆内存中(如果存在的话),【版权所有,侵权必究】未经授权,禁止复制转载。所以并不能原创内容,盗版必究。声明,如果非要声明的话,只能用【版权所有,侵权必究】c.d = null这种形式,即对它进行赋值。【版权所有】唐霜 www.tangshuang.net

【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】【作者:唐霜】

从上面这个说法,你可以发现,如果在声明一【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net个引用数据类型时,可以使用var a = null。同时,undefined和null都可【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。以表示声明而不开辟内存空间。

【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net【版权所有,侵权必究】转载请注明出处:www.tangshuang.net

万能的引用:改变堆内存保存的值【未经授权禁止转载】

著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。

引用数据类型,不单单是为了解决复杂的变量转载请注明出处:www.tangshuang.net【原创不易,请尊重版权】(上下文)数据结构存储,引用传递可以帮助本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】我们完成很多复杂的数据操作。本文特别要介【原创不易,请尊重版权】【未经授权禁止转载】绍的,是跨作用域改变堆内存中的值。为了形原创内容,盗版必究。【作者:唐霜】象的了解这个情况,你可以先阅读一下《javascript中参数的内存引用关系【访问 www.tangshuang.net 获取更多精彩内容】【访问 www.tangshuang.net 获取更多精彩内容】及解决方案》这篇文章中我给出的一种情况。著作权归作者所有,禁止商业用途转载。

【访问 www.tangshuang.net 获取更多精彩内容】【未经授权禁止转载】【作者:唐霜】

简单的说,引用传递的过程就是这样:【版权所有,侵权必究】

【作者:唐霜】【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net
var object = {
  name : "tom",
  age : 10,
  body : {
    head : 1,
    hand : 2,
    foot : 2
  }
};
// =========================
var a = object,
  b = a,
  c = b,
  d = b;
c._origin = object;
// ==========================
c._origin.age ++;
alert(a.age); // 11
// --------
d.body = {
  eye : 2,
  nose : 1
};
alert(a.body.head); // undefined
alert(a.body.eye); // 2

这里面我们就利用到了引用传递的特性。首先【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。,在var a,b,c,d这块,其实所有【本文受版权保护】本文版权归作者所有,未经授权不得转载。的变量都保存了和object一样的内容,转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】也就是object所对应的对象堆内存的地【本文受版权保护】未经授权,禁止复制转载。址信息,所以实际上object,a,b,【版权所有,侵权必究】【本文受版权保护】c,d全部都是地址信息,他们的值是一样的本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】。接下来,我们执行了一个c._origin.age ++操作,看上去是对c进行操作,而实际上,跟本文作者:唐霜,转载请注明出处。【作者:唐霜】c一点关系都没有,c的内容仅仅是一个地址本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。信息,真正被操作的,是这个地址信息对应的【未经授权禁止转载】【原创不易,请尊重版权】堆内存中保存的对象的.age属性。不过这【版权所有,侵权必究】【未经授权禁止转载】里有一个._origin属性有点迷惑性,【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。但是你要知道,c._origin实际上也未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】只是一个地址信息,和a,b,c,d的内容著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】也是一样的。

本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。

所以,从上面的解释我们可以看出:【未经授权禁止转载】如果某个堆内存单元的内容发生了变化,保存【转载请注明来源】【版权所有】唐霜 www.tangshuang.net该堆内存单元地址信息的所有变量所引用的值【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。也相应发生变化,无论这个变量是保存于栈内【关注微信公众号:wwwtangshuangnet】【转载请注明来源】存还是堆内存。

【作者:唐霜】【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。【作者:唐霜】【本文受版权保护】

接下来,我们用上面的.body被改变来解未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】释。原本object.body其实也是一著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。个地址信息,它指向了堆内存中的另外一个存本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。储单元,但是当我们执行d.body = {}操作时,body保存的信息发生了变化,它【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】保存的内容不再是原来的内存地址信息,而是【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net我们新创建的一个对象的堆内存地址信息,这本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】其实也是一个赋值过程。那么原始的obje【本文首发于唐霜的博客】【转载请注明来源】ct.body所指向的堆内存信息去哪里了【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。呢?假如程序中没有另外一个变量指向这个内【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。存单元,那么它过段时间会被垃圾回收。

【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。

这看上去好像没有什么大不了的,不过如果我本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net告诉你,引用传递在函数参数中仍然有效,那未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】就不一样了,因为我们可以随时在函数的作用【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net域内,改变一个来自外部的对象就很方便了。

未经授权,禁止复制转载。【未经授权禁止转载】转载请注明出处:www.tangshuang.net

2016-07-15 7591

为价值买单,打赏一杯咖啡

本文价值75.91RMB
已有2条评论
  1. […] 这是非常容易理解的,如果你不是很理解,可以阅读我写的《JavaScript引用类型数据》一文。 […]

  2. 一只猫 2016-07-23 18:37

    没什么=w=,就是想说句\n谢谢~\n不需要回复= = 。。