JavaScript中变量、指针和引用功能与操作示例
作者:夜色芜染 发布时间:2024-04-17 10:07:16
本文实例讲述了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程序设计有所帮助。
来源:https://blog.csdn.net/u012443286/article/details/79496742


猜你喜欢
- 引言语音端点检测最早应用于电话传输和检测系统当中,用于通信信道的时间分配,提高传输线路的利用效率.端点检测属于语音处理系统的前端操作,在语音
- 本文记录了mysql 5.7.18绿色版下载安装的详细过程1、先下载mysq5.7.18绿色版,然后解压出来,放在一个目录下,我的解压mys
- 一、MySQL-Proxy基础MySQL Proxy是一个处于你的Client端和MySQL server端之间的简单程序,它可以监测、分析
- 引言对 axios 二次封装,更加的可配置化、扩展性更加强大灵活通过 class 类实现,class 具备更强封装性(封装、继承、多态),通
- 注:本次实验的数据在文章最后面,我已上传至百度网盘一.json模块对数据进行处理 上面三个txt文本是这三个国家疫情爆发相关的数据
- Python 10进制数与16进制数相互转换10进制转为16进制在Python中,我们可以使用内置的hex()函数将10进制数转换为16进制
- 数据保存在csv文件中1.从csv文件中读取数据参数header=None的有无(1)没有header=None——直接将csv表中的第一行
- 正在看的ORACLE教程是:Oracle RMAN快速入门指南。前言: 这篇文章主要介绍RMAN的常用方法,其中包含了作者一些自己的经验,里
- OUTPUT是SQL SERVER2005的新特性,可以从数据修改语句中返回输出,可以看作是"返回结果的DML"。INS
- 1.window.location实例:http://www.myurl.com:8866/test?id=123&username
- mysql查询的控制语句字段去重**关键字:distinct**语法:select distinct 字段名 &nb
- Lambda函数,即Lambda 表达式(lambda expression),是一个匿名函数(不存在函数名的函数),Lambda表达式基于
- 一、数据预处理实验数据来自genki4k提取含有完整人脸的图片def init_file(): num = 0&n
- 简介要建立一个允许过滤和分页的列表页,你必须让一些独立的东西一起工作。Django的对象关系映射器(ORM)和内置的分页类使开发者在不了解如
- 一、%号占位符这是一种引入最早的一种,也是比较容易理解的一种方式.使用方式为:1、格式化字符串中变化的部分使用占位符2、变量以元组形式提供3
- 由于某些原因需要把函数直接放到 img 标签上的 onload 属性执行,比如:For some reasons we have to ex
- 组合数据类型分类组合数据类型分为三类,第一类是集合类型,第二类是序列类型,第三类是映射类型集合类型集合类型是一个元素集合,元素之间没有排列顺
- 一、概述变量的功能是存储用户的数据二、声明变量Go语言的每一个变量都拥有自己的类型,必须经过声明才能开始用变量的声明格式:var <变
- 这篇文章主要介绍了Python箱型图绘制与特征值获取过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需
- 在这篇文章中,我将介绍如何识别导致性能出现问题的查询,如何找出它们的问题所在,以及快速修复这些问题和其他加快查询速度的方法。你一定知道,一个