JS 基本类型与引用类型值

JS 基本类型与引用类型值

引入概念:基本类型和引用类型

1、可以感受到,JS 的变量及其松散,那么,正是 JS 变量松散 的本质,决定了:JS 变量名只是 一个在特定的时间用于保存特定值的一个名字 而已,也就是说,变量的值及其数据类型可以在脚本的生命周期内改变 ,尽管这个功能看起来有趣、强大,但是 JS 变量实际上是比较复杂。

2、ECMAScirpt 变量有两种不同的数据类型:基本类型 和 引用类型,另外还有其他的叫法,比如:原始类型和对象类型、拥有方法的类型和不能拥有方法的类型 等/0

3、将一个值赋值给变量时,解析器 必须确定这个值是基本类型值还是引用类型值

基本类型 指的是简单的数据段,而 引用类型 指的是可能由多个值构成的对象

基本类型:undefined、null、string、number、boolean、symbo(ES6)

引用类型:Object、Array、RegExp、Date、Function

两种类型的区别

存储:

基本类型的值是存放在 栈区 的,即内存中的栈内存

假如有以下变量:

var name = 'jozo';var city = 'guangzhou';var age = 22;

登录后复制

那么他们的存储结构如下:(栈区包括了变量的标识符和值)

微信截图_20200528102449.png

引用类型的值是同时保存在 栈内存和堆内存 的

假如有以下对象:

var person1 = {name:'jozo'};var person2 = {name:'xiaom'};var person3 = {name:'xiaoq'};

登录后复制

那么他们的存储结构如下:

微信截图_20200528102504.png

访问:

基本类型的值是 按值访问 的,因为可以操作保存在变量中的实际的值。

引用类型的值是 按引用访问 的,因为引用类型的值是保存在内存中的对象,而与其他语言不同的是,JavaScript 不允许直接访问内存中的位置,即不可以直接操作对象的内存空间,那么,在操作对象时,实际上是在操作对象的引用而不是实际的对象。

动态的属性:

对于引用类型的值,很明显,我们可以为其 添加、改变、删除 属性和方法:

var person = new Object();person.name = "Ozzie";console.log(person.name);    //"Ozzie"

登录后复制

上述过程中,我们创建了一个对象并为其添加了一个属性,如果对象不被销毁或者这个属性不被删除,那么这个属性将一直存在

但是,我们不可以给基本类型的值添加方法和属性

var name = "Ozzie";name.age = 19;consoe.log(name.age);    //undefined

登录后复制

尽管这样操作不会报错,但是仍然会被默默地挂掉

比较:

基本类型的比较是 值的比较 :

例如:

var a = 1;

var b = true;

console.log(a == b);    //true

引用类型的比较是 引用的比较 :

例如:

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

登录后复制

上文提到过,引用类型时按引用访问的,换句话说就是比较两个对象的堆内存中的地址是否相同,很明显,并不是同一个内存位置:

微信截图_20200528102516.png

复制变量值:

将一个基本类型的值复制给另一个变量,那么,会在新变量上创建一个新值,然后再把该值复制到为新变量分配的位置上:

例如:

var a = 10;var b = a;a++;console.log(a);    // 11console.log(b);    // 10

登录后复制

a 与 b 是完全独立的,该值只是 a 中的值的一个副本。

基本类型在赋值操作后,两个变量是相互不受影响的:

微信截图_20200528102526.png

那么,复制引用类型的值时,同样也会将一份存储在对象中的值复制到新变量的空间中,不同的是,这个值的副本实际上是一个 指针,指向的是存储在堆中的对象。也就是说,复制结束后,这两个变量将引用同一个对象。

例如:

var a = {}; // a保存了一个空对象的实例var b = a;  // a和b都指向了这个空对象a.name = 'jozo';console.log(a.name); // 'jozo'console.log(b.name); // 'jozo'

登录后复制

改变其中一个变量就会影响到另一个变量

微信截图_20200528102537.png

传递参数:

请记住,尽管在访问变量时有着按值访问和按引用访问这两种方式,但 ECMAScript 中所有的函数的参数都是按值传递的,即参数只能按值传递,也就是说,把函数外部的值复制给函数内部的参数,就类似于变量之间的值复制一样

基本类型的值的传递如同基本类型的变量的复制,被传递的值会被赋值给一个局部变量(即命名参数,用 ECMAScript 中的概念说,就是 arguments 对象中的一个元素),此处不再赘述…

但是向参数传递引用类型的值时,复制给局部变量的是 内存中的地址,因此这个局部变量的变化会被反映在函数的外部。

例如:

function setName(obj){      obj.name = "Ozzie";}var person = new Object();setName(person);console.log(person.name);    //"Ozzie"

登录后复制

我们可以看到,在函数内部,obj 和 person 引用的是同一个对象,换句话说,即使这个变量是按值传递的,obj 也会按引用来访问同一个对象,因为 person 指向的对象在堆内存中只有一个,而且是全局对象。

很多人会 错误地认为:参数是按引用传递的,因为在局部作用域中修改的参数会在全局作用域中反映出来,OK,那么我们再看一个例子:

function setName(obj){      obj.name = "Ozzie";      obj = new Object();      obj.name = "Nicholas"}var person = new Object();setName(person);console.log(person.name);    //Ozzie

登录后复制

如果是按引用传递参数的,那么显然 person 对象就会在函数内部自动修改 name 属性为 Nicholas,但结果仍然是 Ozzie,这说明,即使在函数内部修改了参数的值,但原始的引用仍然保持不变,实际上,在函数内部重写 obj 时,这个变量的引用就是一个局部对象了,而这个局部对象在函数执行完毕后立即被销毁。

推荐教程:《PHP教程》

以上就是JS 基本类型与引用类型值的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2728423.html

(0)
上一篇 2025年3月7日 23:55:54
下一篇 2025年3月7日 18:10:00

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • JS 中 setTimeout 和 setInterval 区别

    JS中 setTimeout 和 setInterval 区别 setTimeout方法的作用是在指定的毫秒数后执行函数或表达式,而setInterval方法则是在每隔指定的毫秒数循环执行函数或表达式,直到clearInterval方法将其…

    2025年3月7日
    200
  • js中的typeof和instanceof和===的区别

    js中的typeof和instanceof和===的区别 typeof:用于判断number/string/boolean/underfined类型/function,不能判断:null和object ,不能区分object和Array i…

    2025年3月7日
    200
  • js怎么移除css属性

    js怎么移除css的属性? 在工作中,经常需要使用Javascript来改变页面元素的样式。其中一种办法是改变页面元素的CSS类(Class),这在传统的Javascript里,我们通常是通过处理HTML Dom的classname特性来实…

    2025年3月7日
    200
  • js怎么实现字符串转数组

    js怎么实现字符串转数组? js字符串转数组的函数是”split()“,其用法如下 string.split(separator,limit) 登录后复制 参数值 参数描述separator 可选。字符串或正则表达式,从该参数指定的地方分割…

    2025年3月7日
    200
  • js如何实现页面跳转

    js怎么实现页面跳转? js实现页面跳转可以使用“window.location.href=”跳转地址“”方法; 具体用法如下: 首先创建一个html文件填入以下代码: window.location.href = …

    2025年3月7日
    200
  • js怎么清除定时器

    js怎么清除定时器? 在实现清除定时器之前,我们需要开启定时器 一、设置定时器   window对象提供了两个方法来实现定时器的效果,   分别是window.setTimeout()和window.setInterval。其中前者可以使一…

    2025年3月7日
    200
  • JS判断数组中是否包含某个值

    js如何判断数组中某个值? js中判断某个数组中是否含有某个值的函数是”indexOf“,具体用法如下: indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。 语法 stringObject.indexOf…

    2025年3月7日
    200
  • JavaScript 和 Dart 的区别

    什么是JavaScript? JavaScript通常被称为浏览器脚本语言,但它也已扩展到许多服务器端和移动应用程序开发环境。JS已经存在了将近20年,可以肯定地说它确实是一种成熟且稳定的编程语言。在Facebook发布React和Reac…

    2025年3月7日
    200
  • 简单实用的进度条加载组件loader.js

    本文提供一个简单的方法实现一个流程的进度条加载效果,以便在页面中可以通过它来更好地反馈耗时任务的完成进度。要实现这个功能,首先要考虑怎样实现一个静态的进度条效果,类似下面这样的: 这个倒是比较简单,两个div即可,bootstrap官方就提…

    2025年3月7日 编程技术
    200
  • JS 中排名前十的报错如何避免

    前言: 写代码的过程中,难免会发生各种错误,而发出去的代码也可能收到用户浏览器报回来的各种错误需要查问题。了解这些报错发生的原因以及出现的浏览器可以帮助我们更快的找到bug,下面就一起来看看排名前十的JS错误以及避免的方法吧。 一、 Unc…

    2025年3月7日 编程技术
    200

发表回复

登录后才能评论