js变量 作用域与内存(上)

js变量 作用域与内存

前言

这是我人生中的第一篇文章,用作记录我读《jsvascript高级程序设计》,也就是红宝书,内容基础不会太深入研究。

原始值和引用值

在js中有六种原始值分别是(Undefined Null Boolean Number String和Symbol)原始值和引用值最为显著的区别就是访问方式的不同,原始值的变量是按值访问的也就是在操作原始值时候会直接操作变量的实际值,而引用值在操作对象的时候是操作的对象的引用而非对象本身也就是如图

在操作b的时候会通过b的引用访问到b的实际值,通过引用间接操作,这个概念对于下文的理解非常重要

原始值的创建区别

原始值有两种创建方式一种是通过new关键字创建,另一种是直接通过字面量创建

javascript 复制代码
  let str = new String("xxk");//new 关键字创建

  let str1 = "ddd";//字面量创建

  str1.age = 18;

  cansole.log(str1.age)//undefined

可以在上面的代码中看出通过字面创建的字符串添加属性并不会报错在下面访问会是undefined,js中只有引用值可以动态添加后面可以使用的属性,使用new关键字会直接创建一个Object的对象

参数的传递

变量的传递有两种方式 按值传递和按引用传递 在js中几乎所有的赋值都是按值传递(模块化导出模块是按引用传递)两种传递的值有什么不一样吗?

按值传递的时候变量的值会被直接的复制一份,并复制给新的变量,在函数的参数传递的时候值会被复制到一个局部变量(也就是arguments对象的一个槽位),这意味着对于本地变量的修改不会反应到外部函数

javascript 复制代码
  function add(num){

    num+=10;

    return num;

  }

  let count = 20 ;

  let res = add(count);

  cansole.log(count);//20

  cansole.log(res); //30

上面代码发现在函数内部的变量改变并不会影响函数传递的参数的值,这是基本数据类型,而引用类型由于他们的访问方式有所不同,结果也有所不同

javascript 复制代码
function test(obj){

    obj.name = "xxk";

    return obj;

}

    let person= new Object();

    test(person);

    console.log(person.name);// xxk

上面代码中将person变量传递给test函数,在局部作用域给obj添加了一个name的属性,为什么person会有name这个属性呢,这不是和上面说的不会改变函数外部的值自相矛盾了吗?事实究竟是怎么样呢?还记的上面第一节简绍的对象的访问方式吧

上图给出了解释,由于person存储的值为内存地址的引用,当person赋值给obj的时候person的引用会被复制一份给obj,他们的值(也就是引用)相同他们指向的是同一块物理地址,也就是说在操作obj的时候会根据引用操作到Object,而person也有相同的引用指向相同的地址,这也就是为什么obj的改变会引起person的改变

按引用传递:

由名字可以看出变量传递的时候是按引用传递的,也就是直接把地址复制一份,并复制给另一个变量,两个变量拥有着相同的地址

那如何证明js是按值传递而不是按引用传递的呢?

javascript 复制代码
function setname(obj){

    obj.name = "xxk";

    obj = new Object();

    obj.name = "djy"

    return obj;

}

    let person= new Object();

    test(person);

    console.log(person.name);// xxk

在上面的代码中obj被赋值给一个新的对象,并将name属性改为了djy,但是person的name打印出来的name是name。如果js是按照引用传递的话,person与obj都是相同的地址,obj改变了地址也会反应到person变量上面,person.name的值应为djy,但是是xxk,所以说js是按照值传递。

下一章

js的上下文,作用域链以及垃圾回收

相关推荐
swipe11 小时前
正则表达式入门到进阶:从表单校验到手写模板引擎
前端·javascript·面试
kyriewen11 小时前
前端错误监控最全指南:捕获 JS 异常、Promise 拒绝、资源加载失败,附上报代码
前端·javascript·监控
大家的林语冰11 小时前
ESLint 近期动态大全,新版本正式发布,antfu 大佬推荐的插件也更新了!
前端·javascript·前端工程化
胡志辉13 小时前
深入浅出 call、apply、bind
前端·javascript·后端
十九画生15 小时前
parentID ``` JavaScript 是区分大小写的,所以这两个不是同一个字段。 第二,`parent` 没有声明。 应该先写: `
javascript
怕浪猫16 小时前
Electron 开发实战(十六):总结与展望|生态现状、框架对比、行业趋势与学习指南
前端·javascript·electron
ZengLiangYi17 小时前
批量导入 1000 条对话的性能优化实战
javascript·后端·架构
竹林81817 小时前
用 wagmi v2 + viem 监听合约事件时踩的坑,我花了两天才把"遗漏事件"修好
javascript
小花酱酱17 小时前
QQ群里只有你一个人?邪门歪道破局之路——AstrBot
javascript
bonechips17 小时前
JS 数组指南:从内存原理到二维矩阵
前端·javascript