js中的数据
数据类型
基本数据类型:number、string、null、boolean、undefined 引用类型:Object、Function、Array 在此不做过多阐释。
null与undefined
undefined代表定义未赋值。 null代表定义并赋值,且值为null。
使用null的情况
1、null是基本类型,但是使用typeof null是object。一个值的特殊类型,表示一个空对象引用。可以这么理解:将变量初始值赋为null,表示将要赋值的值为对象。
let b = null
console.log(typeof b, b) // object null
b = { name: 'clying' }
console.log(b) // { name: 'clying' }
2、释放垃圾对象
b = { name: 'clying' }
b = null
让b执行的对象成为垃圾对象,被浏览器回收。
数据、内存、变量
数据:以二进制形式存储在内存中,代表一定信息的数字。
内存:内存条通电后产生的存储空间。内存又分为栈内存和堆内存。栈内存中存放的是全局变量或局部变量。而堆内存中存放的是对象。
变量:可变化的量,由变量名和变量值组成。每个变量都对应的一块小内存,变量名用来查找对应的内存,变量值就是保存在内存中的数据。
关系:「内存」是用来存储「数据」的空间,而「变量」是内存的标识。
引用变量赋值
变量修改
多个引用变量指向同一个对象,通过一个「变量修改对象内部数据」,其他所有的变量看到的是修改之后的数据。
let obj = { name: 'clying' }
let obj1 = obj
obj.name = '修改了'
obj1.age = 12
console.log(obj, obj1)
// { name: '修改了', age: 12 } { name: '修改了', age: 12 }
obj变量保存了{ name: 'clying' }
的地址值,而obj1保存了obj内容,只是obj中的内容是{ name: 'clying' }
的地址值。 在未修改属性之前,内存中的obj、obj1,都指向同一个地址。
在修改obj的name属性变量时,直接修改的就是它所指向的地址值。将name属性的值改为'修改了'。 同理,给obj1添加age属性变量,是在obj1指向内存对应的地方添加age属性。
所以,输出obj、obj1的值一样,均为{ name: '修改了', age: 12 }。
变量与函数
let obj = { name: 'clying' }
let obj1 = obj
obj.age = 22
function fun(o) {
o.age = 12
}
fun(obj)
console.log(obj, obj1)
// { name: 'clying', age: 12 } { name: 'clying', age: 12 }
执行fun(obj),将obj的值赋值给o。函数内部,修改o变量的age属性,就等同于修改了obj中age的属性。
引用变量修改
多个引用变量指向同一个对象,让其中一个「引用变量指向另一个对象」,另一引用变量依然指向前一个对象。
let obj = { name: 'clying' }
let obj1 = obj
obj = { name: 'dengdeng', age: 22 }
console.log(obj, obj1)
// { name: 'dengdeng', age: 22 } { name: 'clying' }
在obj未修改之前,依旧是obj、obj1均指向同一地址值。
此时,将obj修改成{ name: 'dengdeng', age: 22 }
,即obj指向的是{ name: 'dengdeng', age: 22 }
的地址值。obj1依然指向前一个对象,即{ name: 'clying' }
。
image.png
所以输出的obj、obj1两者指向的地址值不同,所以两者输出不同。
引用变量与函数
再看一个例子:
let obj = { name: 'clying' }
let obj1 = obj
obj = { name: 'dengdeng', age: 22 }
function fun(o) {
o = { age: 12 }
}
fun(obj)
console.log(obj, obj1)
// { name: 'dengdeng', age: 22 } { name: 'clying' }
对于obj1,依然指向前一个对象,输出{ name: 'clying' }
。而obj在第一次修改后,obj指向{ name: 'dengdeng', age: 22 }
的地址值。执行fun函数,将obj的值拷贝一份,赋值给变量o。此时,o变量存储的是{ name: 'dengdeng', age: 22 }
的地址值,而且obj的值并未发生改变!
然后执行函数内部,变量o又被重新指向了{ age: 12 }
的地址值。
实际指向如上图。而存在与fun函数内部的o变量,变成了垃圾对象,根本无法使用。
比较
可能会有一些疑惑:变量与函数中,修改了obj的值,为什么在引用变量与函数中,obj的值没有被修改?
首先需要明白,js函数传递变量参数时,是「值传递」(个人理解:传递的是变量的值)。执行函数fun,只是将obj的地址值赋值给o变量。
变量与函数中,o是直接被修改,修改的直接是obj内部age的属性变量。
引用变量与函数中, 「o存放的是obj的值」,即:o内部是{ name: 'dengdeng', age: 22 }
的地址值。函数内部,又将「o指向了另一个对象」,即{ age: 12 }
的地址值。但是指向另一个对象时,obj依旧指向的是前一个对象。
相关文章
- js高频手写题总结
- 使用 Dapr JS SDK 让 Nest.js 集成 Dapr(微软开源的分布式应用程序运行时)
- 使用 Dynatrace 对 Node.js 应用的性能数据进行分析
- html如何只刷新页面指定,js控制页面刷新 JS刷新当前页面的几种方法总结
- JS跳转代码_js中跳转页面路径
- php 中js跳转页面跳转页面,js跳转代码_PHP页面跳转 Js页面跳转代码[通俗易懂]
- 【说站】js中Array.of的使用
- 小程序js添加新对象(读取一维数组数据,动态生成二维对象)
- 百度高德地图JS-API学习手记:地图基本设置与省市区数据加载
- Mongoose v 4.9.6 发布,让node.js更优雅的操作MongoDB详解大数据
- 利用Node.js实现MongoDB数据导出功能(导出mongodb数据)
- 使用JS在网页中连接Oracle数据库(js网页链接oracle)
- Oracle中JS的优势让数据库性能提升(oracle中 js)
- JS实现浏览器菜单命令
- js实现右下角窗口弹出窗口效果
- js防止表单重复提交实现代码
- js连接数据库如何操作数据库中的数据
- js修改table中Td的值(定义td的单击事件)
- js实现json数据行到列的转换的实例代码
- 解决js数据包含加号+通过ajax传到后台时出现连接错误
- js整数字符串转换为金额类型数据(示例代码)
- js几秒以后倒计时跳转示例
- js四舍五入数学函数round使用实例
- js动态添加表格数据使用insertRow和insertCell实现
- js去除字符串第一位逗号的方法
- node.js操作mongoDB数据库示例分享
- JS中如何判断传过来的JSON数据中是否存在某字段