被小看的面试题 - 传值 or 传引用

简介: 前几天一个正在找工作的朋友发来一个面试题,感觉挺有意思的今天发出来大家一起乐呵乐呵。

这个题其实不难,但是涉及到不只一个知识点,而且平时可能不会注意到。

来直接看题


de1f11b722d97be391bef9e485d59b04_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.jpg


得到这个题后也发给了自己的小伙伴儿一起研究了下,得出的很多种答案。

从各自的答案中也找到了一个相同的问题,也就是不能确定的值是 d 的值,

有的得出【4,5,6】,有的得出【1,2,7】。


你可以现在脑子里写出答案?


4fa6d76895d298f0adf2b7dd16236894_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.jpg


~~~


4fa6d76895d298f0adf2b7dd16236894_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.jpg


~~


4fa6d76895d298f0adf2b7dd16236894_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.jpg

~~


正确答案是: 1,3,[1,2,7],[1,2,7],[1,2,7]

如果答案一致请忽略本文


我们来一步一步的分析下。


1. 首先 a 和 b 的值我们都能确定的给出 a=1,b=3;


因为 console 是在全局作用域执行的,所以即便是这个自执行函数执行后 a 也不可能是函数内部的值。他们两个的作用域不同,所以 a=1;


2. b 的声明和赋值在全局存在,在自执行函数内也被赋值一次,所以 b=3;


3. 剩下的就是 cde 的值了


题目中的 c d e 的连等更多的是一种混淆,不用管它,当做是正常的赋值即可。


先来看 c 的值

c 在全局被赋值为一个数组,所以他是引用类型(大家都知道),

在函数中又被赋值一次c[2]=7,先不管后面的代码如何,这个时候 c 的值肯定是 [1,2,7]了,此时 d 和 e 的值也是[1,2,7]


因为 cde 指向的是同一块内存区域,修改后引用的数据就变成了[1,2,7]


8f75b6b215375ece382d09a04b004767_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.jpg

然而c 赋值后面还有d=[4,5,6]


那形参 d 的重新赋值会影响 c 的值吗?

答案当然是不会影响。


首先看清楚形参d对应的是实参 e,重新给 d 赋值其实在操作 e(不够准确,后面会说);

然而 e 是数组是引用类型,所以有的答案存在e =[4,5,6]或者d=[4,5,6];


其实这里首先要搞清楚一点,两个变量指向同一内存区域,如果其中一个变量重新赋值(而不是修改值),是不会影响另一个变量的,因为重新赋值会切断对原来内存地址的引用,从而指向新的地址。


c97377c51328be0a339d9275ee6830ab_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.jpg


所以肯定的是 c 的值不会受影响,所以 c=[1,2,7];


求 d 的值?


d 在函数内部被重新赋值,因为他是形参(对应的实参是 e),而且也是函数的局部变量,所以 全局d 的值不会因为重新赋值而改变,但是 c 对引用的数据做了修改,所以d 也会改变 d=[1,2,7]


求 e 的值?


e 是函数的实参,对应的形参是 d。

这里就要知道函数的参数传值的方式是怎样的-按值传递和按引用传递。

记得在高程里有提起过,js 中函数参数只有按值传递的方式,没有按引用传递。也就是传递的是变量的副本,其实就是两个变量。


所以在函数内部的 d 被重新赋值,其实修改的是 e 的副本,但是 d 被重新赋值了,所以d 和 e 就没有了关系。e 还是原来的指向。所以 e=[1,2,7]。


如果 d是这么修改值,d[2]=8 ,那么 c d e=[1,2,8]了。


按引用传递


如果参数是按引用传递,那么就不是副本了,会直接修改原变量,结果就可想而知了。


对比下其他语言


php

d282e8e9c55bab189cb8bf737fe19c3a_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.jpg


可以强制按引用传递

73e976759d83a629e5cb2c59b34d3fe1_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.jpg


C#

8ca45474f81c9f46e19366f467212f53_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


d9094cb024cb16a0a62ea9b3f740704a_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.jpg


java 肯定也是默认按值传递。


总结


这个面试题考点主要有:

作用域

基本类型和复杂类型的赋值和改值

函数参数传递的方式


后端语言也是默认按值传递,也就是处理的是变量的副本,如果变量是值类型,那么随便修改也不会影响原变量。


如果是引用类型(复合类型),若是修改的话那会直接影响原变量,如果是从新赋值就会重新分配内存区域对原变量无影响。


有些后端语言还可以强制按引用传递(按需处理)。

目录
相关文章
|
XML 前端开发 JavaScript
jQuery中ajax如何使用
jQuery中ajax如何使用
177 0
|
前端开发 JavaScript Java
现代化软件开发中的前后端分离模式
随着互联网技术的快速发展,现代化软件开发中的前后端分离模式逐渐成为主流。本文将介绍前后端分离的概念和优势,以及如何在不同的技术栈中实现这种模式。通过前后端分离,可以提高开发效率、降低耦合性,并且更好地满足用户需求。
451 0
|
存储 缓存 调度
虚拟存储
虚拟存储
630 0
|
运维 应用服务中间件 网络安全
运维系列.Nginx配置文件结构功能总结
运维系列.Nginx配置文件结构功能总结
241 0
运维系列.Nginx配置文件结构功能总结
|
IDE 开发工具 C++
⚡【C++要笑着学】(40) OF框架:OpenFrameworks 框架介绍 | oF 文件结构 | 图形基础 | 使用 ProjectGenerator 创建项目
⚡【C++要笑着学】(40) OF框架:OpenFrameworks 框架介绍 | oF 文件结构 | 图形基础 | 使用 ProjectGenerator 创建项目
523 0
|
弹性计算 安全 前端开发
阿里云服务器ECS通用型、计算型和内存实例区别、CPU型号、性能参数表
阿里云ECS实例有计算型(c)、通用型(g)和内存型(r)系列,区别在于CPU内存比。计算型1:2,如2核4G;通用型1:4,如2核8G;内存型1:8,如2核16G。实例有第五代至第八代,如c7、g5、r8a等,每代CPU型号和主频提升。例如,c7使用Intel Ice Lake,g7支持虚拟化Enclave。实例性能参数包括网络带宽、收发包能力、IOPS等,适合不同场景,如视频处理、游戏、数据库等
659 0
|
Android开发 芯片
Android源代码定制:移除无用lunch|新建lunch|自定义customize.mk
Android源代码定制:移除无用lunch|新建lunch|自定义customize.mk
692 3
|
存储 安全 网络安全
Windows操作系统中:共享文件夹以及防火墙介绍
Windows操作系统中:共享文件夹以及防火墙介绍
997 0
|
Android开发 iOS开发
一文了解图片降级方案
在做项目优化的时候,发现页面加载很慢。结果一看主要的问题就是就是图片的大小过慢,然后呢准备呢去做优化, 本来想去用webp,去优化的,但是呢这个图片是不是我们就用不了呢,然后看了下业界优化王,直接打开了淘宝网的首页。淘宝的首屏加载是很快的,然后 我就去看了下他图片的格式: 图片 这种图片其实是做了降级处理如果说 支持webp就使用, 如果不支持的话就使用jpg 为什么要做图片降级 图片的格式有很多 jpeg png webp等,我们经常使用webp格式的图片,因为webp格式的图片拥有无损压缩和有损压缩两种模式而且压缩率更高等优点。但是webp格式的图片同样也有缺点,ios webvie
一文了解图片降级方案

热门文章

最新文章