JavaScript中变量、指针和引用功能与操作示例


Posted in Javascript onAugust 04, 2018

本文实例讲述了JavaScript中变量、指针和引用功能与操作。分享给大家供大家参考,具体如下:

1、变量

我们可能产生这样一个疑问:编程语言中的变量到底是什么意思呢?

事实上,当我们定义了一个变量a时,就是在存储器中指定了一组存储单元,并将这组存储单元命名为a。变量a的值实际上描述的是这组存储单元中存放的具体信息。

例如,在JS中

var a;
a=10;

第一个语句在存储器中指定了一组存储单元,并命名为a;

第二个语句在这组存储单元中存储了数字10。

变量a的值为10实际上是说存储单元组a存储的信息是10。

假使我们再次对a进行复制操作:

a="hello";

这样a的值变成字符串”hello”。这很容易理解,我们将存储单元组a中存储的信息改为字符串”hello”,显然原先的数字10将被覆盖。

2、指针

假使我们在另一个变量b中存储变量a在存储器的地址,会发生什么?

我们很容易想到,直接访问b变量,得到的并不是变量a的值,而是变量a在存储器中的地址,变量b便被称为指针。

这样一个问题产生了:如何通过变量b访问到变量a的值呢?

在C语言中,常用的是用*,比如:

int c=10,b;
int *p;/*p是指向int类型的指针*/
p=&c;/* &c获取变量c的地址,然后赋值给变量p,这样p存储的是变量c的地址,即p是指向c的指针*/
b=*p;/* *p访问p指向的对象,然后将值赋值给b*/

在JS中,并没有指针这种变量类型,但指针的应用却无处不在。比如:

var o1={b:1};
var o2={b:1};
o1===o2;//false
o1==o2;//false

这里o1和o2都是相同的对象,为什么不相等呢?这就需要深入理解JavaScript中的引用类型和指针。

首先,我们需要明白:

给o1和o2赋值,并不是o1地址中存储对象{b:1},o2地址中也存储对象{b:1}

其次,我们要明白实际发生的操作:

var o1={b:1}实现了在堆内存中创建了一个对象{b:1},o1则存储了该对象在堆内存中的地址,即o1是一个指针,指向{b:1};

同理,var o2={b:1}也在堆内存中创建了一个对象{b:1},o2存储了该对象在堆内存中的地址,即o2也是一个指针,指向{b:1};

并且,由于两个相同的对象{b:1}是先后创建,在堆内存中也不是存储在相同的地址。

然后,我们还需要知道:

在JavaScript中,引用类型(对象、数组、正则、Date、函数)的比较,实际上是比较指针是否指向存储器中的同一段地址,只有指向同样的地址才能相等。

显然,o1这个指针指向堆内存中创建的第一个对象{b:1};

o2指针则指向堆内存中创建的第二个对象{b:1};

但两个对象相对独立,并不是同一个对象,故o1和o2并没有指向同样的堆内存地址,故而并不相等。

我们再看常见的应用:

var o={a:1};
o.__proto__===Object.prototype;//true

对象o的构造函数是Object,Object有一个prototype属性,并且prototype是一个指针,他指向存储器中的一个对象,此对象将会被由构造函数创建的对象实例所共享。

作为Object的实例,o也有一个指针__proto__,它也指向Object的prototype属性指向的对象。

这里的全等返回true,则清楚地表明了两者指向同样的堆内存地址,即指向的是同一个对象。

我们如果想主动让两个引用类型指向同样的对象,如何操作呢?

var obj1={b:1};
var obj2=obj1;
obj1===obj2;//true
obj1==obj2;//true

可以看到,对于引用类型,直接使用'='赋值实际上就是使两者指向同一个对象。
故而,我们猜测,如果通过obj1修改了对象的值,obj2再次访问时将看到修改后的对象:

obj1.name='ls';
obj1;//{b: 1, name: "ls"}
obj2;//{b: 1, name: "ls"}

的确如此。作为对比:

o1.name='ls';
o1;//{b: 1, name: "ls"}
o2;//{b: 1}

那么,对于基本类型呢?

var s1=1;
var s2=2;
s1===s2;//true

在JS中,对于基本类型,只需其值相等,则两个变量就相等。

3、引用

首先,我们要深入理解引用类型的值。

前面我们看到,obj1和obj2指向堆内存中存储的同一个对象。当我们访问obj1和obj2时,都会返回同一个对象。可以说:obj1的值和obj2的值相同。

对于o1和o2,他们指向堆内存中不同地址的两个{b:1}对象,o1和o2拥有不同的值。

因此,对于引用类型,我们所说的值,指的是保存在内存中的对象。如果是同一对象,则值相同,不同对象则值不同。

在JS中,传递参数都是按值传递的。比如:

var a1=1,b1=2;
function add(a,b){
  a++;
  b--;
  return a+b;
};
add(a1,b1);//3
a1;//1
b1;//2

这里,函数add中的形参a、b分别得到变量a1、b1的值的拷贝,这便是按值传递。

在add函数执行环境中对a、b操作不会影响到全局变量a1、b1。

再看引用类型:

function setName(obj){
   obj.name="Nicholas";
   obj=new Object();
   obj.name="Greg";
}
var person=new Object();
setName(person);
alert(person.name);//"Nicholas"

执行setName(person)时,person指向的内存中的地址便被传入obj,使得obj也指向同样的内存地址,即同一个对象。这里的按值传递,传递的是内存地址。

如果通过obj修改该对象,外部访问person便也能体现出来。

我们可能有一个疑问,既然是指向同一个对象,为什么不是按引用传递呢?

首先,我们看到函数内部对obj重新进行了赋值,使得obj指向新创建的对象。如果是按引用传递,那么外部person便也会指向新创建的对象。实际上,person还是指向原先的对象。

对于引用类型的按值传递,其实可以更加通俗地理解:

1、实参将指向的内存地址传递给形参 ,按值传递的值指的是内存地址;
2、形参修改了它和实参共同指向的对象后,外部的实参会反映出来;
3、但形参始终无法修改实参指向的内存地址,即如果将形参指向新的对象,实参并不会指向新的对象。

基于以上3点,我们就不难理解上面代码运行的结果了。

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
WebGame《逆转裁判》完整版 代码下载(1月24日更新)
Jan 29 Javascript
Jquery 表单验证类介绍与实例
Jun 09 Javascript
jQuery获取Radio,CheckBox选择的Value值(示例代码)
Dec 12 Javascript
Jquery实现点击按钮,连续地向textarea中添加值的实例代码
Mar 08 Javascript
在jQuery中处理XML数据的大致方法
Aug 14 Javascript
jQuery改变form表单的action,并进行提交的实现代码
May 25 Javascript
JS 循环li添加点击事件 (闭包的应用)
Dec 10 Javascript
vue.js将unix时间戳转换为自定义时间格式
Jan 03 Javascript
Bootstrap风格的zTree右键菜单
Feb 17 Javascript
详解JS模块导入导出
Dec 20 Javascript
Node.js API详解之 net模块实例分析
May 18 Javascript
Vue 解决在element中使用$notify在提示信息中换行问题
Nov 11 Javascript
webpack4.x开发环境配置详解
Aug 04 #Javascript
微信小程序实现收藏与取消收藏切换图片功能
Aug 03 #Javascript
解决mpvue + vuex 开发微信小程序vuex辅助函数mapState、mapGetters不可用问题
Aug 03 #Javascript
mpvue跳转页面及注意事项
Aug 03 #Javascript
JavaScript高级函数应用之分时函数实例分析
Aug 03 #Javascript
mpvue小程序仿qq左滑置顶删除组件
Aug 03 #Javascript
JavaScript中call和apply方法的区别实例分析
Aug 03 #Javascript
You might like
用PHP编程语言开发动态WAP页面
2006/10/09 PHP
php接口与接口引用的深入解析
2013/08/09 PHP
ThinkPHP实现ajax仿官网搜索功能实例
2014/12/02 PHP
php递归函数怎么用才有效
2018/02/24 PHP
用js判断用户浏览器是否是XP SP2的IE6
2007/03/08 Javascript
解决jquery中美元符号命名冲突问题
2014/01/08 Javascript
JavaScript调用浏览器打印功能实例分析
2015/07/17 Javascript
怎么通过onclick事件获取js函数返回值(代码少)
2015/07/28 Javascript
Bootstrap3制作图片轮播效果
2016/05/12 Javascript
基于jQuery实现中英文切换导航条效果
2016/09/18 Javascript
对Angular.js Controller如何进行单元测试
2016/10/25 Javascript
jQuery插件jquery.kxbdmarquee.js实现无缝滚动效果
2017/02/15 Javascript
vue+vuex+axios实现登录、注册页权限拦截
2018/03/09 Javascript
JS实现仿微信支付弹窗功能
2018/06/25 Javascript
基于Express框架使用POST传递Form数据
2019/08/10 Javascript
通过GASP让vue实现动态效果实例代码详解
2019/11/24 Javascript
Vue开发环境跨域访问问题
2020/01/22 Javascript
通过实例解析JavaScript for in及for of区别
2020/06/15 Javascript
vue使用swiper实现左右滑动切换图片
2020/10/16 Javascript
[57:18]DOTA2上海特级锦标赛主赛事日 - 1 败者组第一轮#3VP VS VG
2016/03/03 DOTA
Python中使用scapy模拟数据包实现arp攻击、dns放大攻击例子
2014/10/23 Python
Python使用scrapy采集数据过程中放回下载过大页面的方法
2015/04/08 Python
python实现C4.5决策树算法
2018/08/29 Python
Python中BeautifuSoup库的用法使用详解
2019/11/15 Python
Python3读取和写入excel表格数据的示例代码
2020/06/09 Python
PyCharm2019.3永久激活破解详细图文教程,亲测可用(不定期更新)
2020/10/29 Python
bonprix荷兰网上商店:便宜的服装、鞋子和家居用品
2020/07/04 全球购物
.NET里面如何取得当前的屏幕分辨率
2012/12/06 面试题
桥梁与隧道工程专业本科生求职信
2013/10/08 职场文书
模具设计与制造专业应届生求职信
2013/10/18 职场文书
护士自我评价范文
2014/01/25 职场文书
大型会议策划方案
2014/05/17 职场文书
小学教育见习总结
2015/06/23 职场文书
有趣的二维码:使用MyQR和qrcode来制作二维码
2021/05/10 Python
九大龙王魂骨,山龙王留下躯干骨,榜首死的最憋屈(被捏碎)
2022/03/18 国漫
漫画「古见同学有交流障碍症」第25卷封面公开
2022/03/21 日漫