首页 > 其他分享 >JS中全局变量作为函数实参传入的问题

JS中全局变量作为函数实参传入的问题

时间:2022-10-26 15:25:53浏览次数:90  
标签:foo console log 形参 JS 实参 全局变量 函数

昨天面试时,被问到了以下的JS代码问题,对比两种情况的输出思考为什么会是这样的结果

第一种情况
var a=[1,2,3];
function foo(a){
    a=[4,5,6];
}
foo(a);
console.log(a); // [1,2,3]1234567
第二种情况
var a=[1,2,3];
function foo(a){
    a.push(4);
}
foo(a);
console.log(a); // [1,2,3,4]1234567

被问的时候也是蒙圈的,回来仔细查了相关资料,总结一下,希望也能帮助到你理解这个问题。

看以上两种情况,当全局变量作为函数的实参传入函数之后被重新赋值,然而,执行完函数之后全局变量并没有发生改变,这是为什么?

JS高级程序设计第三版70页有阐述。加上自己的理解总结如下:

原本的b=a有两种赋值方式,一种是按值,另一种是按引用。
    ECMAScript中所有的参数传递都是按值传递的,也就是说把函数外部的值复制给函数内部的参数,无论是基本类型还是对象类型,实参和形参都会指向不同的内存地址,并且作用域不同,形参的作用域仅仅在函数体内。
    我们看如下代码:

var a=[1,2,3],
var b=1;
function foo(a,b){
    a=[4,5,6];
    b=2;
}
foo(a,b);
console.log(a); // [1,2,3]
console.log(b); //1;123456789

我们看到全局变量a和b,被作为实参传给形参后,函数体内对变量a、b进行了重新的赋值,但是并没有改变全局变量a、b的值,即说明函数体内的a、b赋值都是对形参的赋值,形参与在函数中声明的变量一样有着相同的性质。

但是有一种情况比较特殊,但是不会违背参数按值传递的规律。看如下代码:

var a=[1,2,3];
function foo(a){
    a.push(4); //调用引用类型方法,改变了形参a,也改变了全局变量a
    console.log(a); // [1,2,3,4] 此时的a是形参变量的值
    a=[5,6,7];      // 形参重新赋值不会改变全局变量a
    console.log(a); // [5,6,7] 形参变量a
};
foo(a);
console.log(a); // [1,2,3,4]123456789

再来看如下代码:

var a=[1,2,3];
function foo(a){
    a=[5,6,7]; // 形参a被重新赋值,不会改变全局a
    a.push(4); // 此时只改变了形参a,不会改变全局a
    console.log(a); // [5,6,7,4]
};
foo(a);
console.log(a); // [1,2,3]12345678

引用数据类型,会发现在函数里,形参被赋值之前,对形参调用引用数据类型的属性(或方法)时,不仅会改变形参,还会改变全局变量。这大概是同名形参和全局变量的一种对应吧,通俗解释一下就是只有当你在函数里被重新赋值之后,你才是独立的。而在这之前我们是穿一条裤子的,属性和方法的调用会同时改变我们。
希望对你有帮助。

标签:foo,console,log,形参,JS,实参,全局变量,函数
From: https://www.cnblogs.com/guibi/p/16828482.html

相关文章

  • [JS真好玩] 图片文件没后缀,怎么判断图片类型?
    这是我的专栏​​《JS真好玩》​​,将教你用JS实现一些有趣的东西。JS可以直接在浏览器运行,也可以在Node中运行,你可以跟我学习用JS做好玩儿的事情。感谢大家关注~文章求赞噢!祝......
  • Nodejs相关ORM框架分析
    概述写这篇blog的原因,想找个node的ORM框架用用,确很难找到一篇对比分析这些ORM框架的文章,唯一找到了一篇,居然是通过star数来论英雄,我觉着很难服众,于是就找几个看看。后来又......
  • 在linux系统中安装Nodejs 的简单步骤说明
    一、首先我们要下载Nodejs安装包 1、可以从官网上https://nodejs.org/zh-cn/download/ ,下载合适自己的安装包。大家可以根据自己的服务器下载不同的安装包,通过uname......
  • Nodejs:ESModule和commonjs,傻傻分不清
    最近写nodejs脚本的时候遇到了commonjs和ESModule的问题,正好之前用得稀里糊涂的,这次好好学习一下。ESModule导出仅导出namedexports:命名导出,每次可以导出一个或......
  • js 加减乘除取余运算
    1.取整//丢弃小数部分,保留整数部分parseInt(5/2)//22.向上取整//向上取整,有小数就整数部分加1Math.ceil(5/2)//33.向下取整//向下取整,丢弃小数部分......
  • [RxJS] merge - build count down example
    import{interval,fromEvent,of,merge,empty}from'rxjs';import{scan,mapTo,takeWhile,takeUntil,tap,startWith,switchMap}from'rxjs/operators';/......
  • JSON Crack 数据可视化工具
    JSONCrack简介JSONCrack是一个很方便的JSON数据可视化工具。该项目不是简单的展示JSON数据,而是将其转化为类似思维导图的形式,支持放大/缩小、展开/收缩、搜索节......
  • JSP笔记以及理解
    时间:2020/4/21前言:课件笔记、JSP的缺点笔记来源:老师的课件一、课件笔记1JSP(Javaserverpages)是一种用于开发动态网页的技术,文件后缀名是.jsp在JSP页面中可以嵌套Java代码,为......
  • Vue 结合Sortablejs实现table行排序
    场景在一个列表展示页面上,使用了表格组件,原有组件本身不支持拖拽功能,需求要求在列表的基础上支持行拖拽排序。因此引入了www.sortablejs.com插件。问题引入Sortablejs后......
  • Qt使用QJson进行Http请求时序列反序列对象
    1.创建工程使用CMake创建工程cmake_minimum_required(VERSION3.20FATAL_ERROR)project(httprequestLANGUAGESCXX)set(CMAKE_AUTOUICON)set(CMAKE_AUTOMOCO......