JS进阶第二篇:函数参数按值传递

news2024/11/27 17:47:30

文章目录

  • 函数参数按值传递
    • 按值传递
    • 引用传递?
    • 应用

函数参数按值传递

按值传递

在 JavaScript 中,我们有函数以及传递给这些函数的参数。但是 JavaScript 对如何处理你传递的内容并不总是很清楚。当你开始进入面向对象开发的时候,你可能会发现自己为什么在函数中有时能访问到值,但有时无法访问到值。

传入基本数据类型例如字符串或数字时,参数是按值传入的。这意味着任何在函数中对该变量的更改与函数之外发生的任何事情无关。下面我们来看看下面这个例子:

var value = 1;
function foo(v) {
    v = 2;
}
console.log(value); //1
foo(value);
console.log(value) // 1

很好理解,当传递 value 到函数 foo 中,相当于拷贝了一份 value,假设拷贝的这份叫 _value,函数中修改的都是 _value 的值,而不会影响原来的 value 值。

引用传递?

拷贝虽然很好理解,但是当值是一个复杂的数据结构的时候,拷贝就会产生性能上的问题。
所谓按引用传递,就是传递对象的引用,函数内部对参数的任何改变都会影响该对象的值,因为两者引用的是同一个对象。

var obj = {
    value: 1
};
function foo(o) {
    o.value = 2;
    console.log(o.value); //2
}
foo(obj);
console.log(obj.value) // 2

这个时候很多小伙伴就很困惑了,《Javascript 高级程序设计》第三版中有这么一句话 ECMAScript中所有函数的参数都是按值传递的
但是从刚刚的例题中我们明显感觉到:就是按照引用传递的啊;首先我们都知道,js 中的类型分为值类型和引用类型,值类型保存在内存栈中,引用类型保存在内存堆中。

我们看下面的这段代码:

var a={
  name:'大雄'
};
var b=a;
b.name='小熊';
console.log(a.name);

最后的输出结果是小熊,这段代码的执行结果想必大家都知道,因为a保存的是一个堆指针,b赋值后指向了同一个堆内存:

alt

所以说:值传递可以理解为复制变量值,基本类型复制后俩个变量完全独立;引用类型复制的是引用(即指针),之后的任何一方改变都会映射到另一方。

下面我们看另一道题:

var a = [1,2,3]

function fn(b){
     b=[4,5,6];  
};
fn(a)
console.log(a);

按照我们刚才讲的,这道题是不是应该输出[4,5,6]呢?
错了,答案还是[1,2,3],因为这时我们并没有改变指针的内容;而是开辟了一个新的堆空间;所以a,b 就不相互影响了:

alt

结合图和代码,我们对程序的执行一目了然,相信大家都明白了。
所以说js中函数的参数都是按值传递的

应用

我们先看一道例题:

for (var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}

console.log(i);

只要你对 JS 中同步和异步代码的区别、变量作用域、闭包等概念有正确的理解,就知道正确答案是 5 -> 5,5,5,5,5

如果期望代码的输出变成:5 -> 0,1,2,3,4,且不使用let的前提下,该怎么改造代码?
熟悉闭包的同学很快能给出下面的解决办法:

for (var i = 0; i < 5; i++) {
    (function(j) {  // j = i
        setTimeout(function() {
            console.log(j);
        }, 1000);
    })(i);
}

console.log(i);

巧妙的利用IIFE(Immediately Invoked Function Expression:声明即执行的函数表达式)来解决闭包造成的问题,确实是不错的思路,但是初学者可能并不觉得这样的代码很好懂,还有其他的解决方法吗?

答案是有,我们只需要对循环体稍做手脚,让负责输出的那段代码能拿到每次循环的 i 值即可。该怎么做呢?利用 JS 中基本类型的参数传递是按值传递的特征,不难改造出下面的代码:

var output = function (i) {
    setTimeout(function() {
        console.log(new Date, i);
    }, 1000);
};

for (var i = 0; i < 5; i++) {
    output(i);  // 这里传过去的 i 值被复制了
}

console.log(new Date, i);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/42153.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Hack The Box】Linux练习-- Shibboleth

HTB 学习笔记 【Hack The Box】Linux练习-- Shibboleth &#x1f525;系列专栏&#xff1a;Hack The Box &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4c6;首发时间&#xff1a;&#x1f334;2022年11月27日&#x1f334; &#…

3.8 如何在小红书上蹭热点,这里有8个方法【玩赚小红书】

在小红书究竟能不能蹭到热点?有哪些热点可以蹭?怎么蹭?是很多小红书运营者关心的问题。在我看下&#xff0c;小红书热点分为官方热点、事件热点和账号热点三类&#xff0c;用好这8个方法&#xff0c;让笔记获得更多流量。 ​ ​ 一、官方热点 官方热点是小红书推出&#x…

RocketMQ 消费端如何监听消息?

前言 RocketMQ消息消费者是如何启动的&#xff0c;有一个步骤是非常重要的&#xff0c;就是启动消息的监听&#xff0c;通过不断的拉取消息&#xff0c;来实现消息的监听&#xff0c; 那具体怎么做&#xff0c;让我们我们跟着源码来学习一下~ 流程地图 源码跟踪 这一块的代…

ipv6地址概述——配置ipv6

个人简介&#xff1a;云计算网络运维专业人员&#xff0c;了解运维知识&#xff0c;掌握TCP/IP协议&#xff0c;每天分享网络运维知识与技能。个人爱好: 编程&#xff0c;打篮球&#xff0c;计算机知识个人名言&#xff1a;海不辞水&#xff0c;故能成其大&#xff1b;山不辞石…

加拿大留学一定要善用这八个服务系统

加拿大留学之所以如此受大家欢迎&#xff0c;主要也是由于其优质的教育、易移民等优势&#xff0c;而对于学生本人来说&#xff0c;满意的学习体验&#xff0c;也是留学生涯中不可缺少的重要一环。 加拿大大学都拥有成熟完善的学生服务系统&#xff0c;帮助学生们更好的学习、…

Code learning tools

这里写目录标题1. Code learning tools1.1. Chrome Sourcegraph plugin1.2. Print statements never go out of style1.3. When in doubt, PANIC1.4. Visit the past with GitHub blame1. Code learning tools I know what you are thinking. Brad, you are new to Kube and G…

有哪些电容笔值得推荐?值得买的电容笔测评

和苹果原装的电容笔不同&#xff0c;普通电容笔没有苹果电容笔的独特重力压感&#xff0c;只是给人一种倾斜的压感。不过&#xff0c;如果你对画画没有什么特别的需求&#xff0c;也不必买昂贵的Apple Pencil&#xff0c;平替电容笔就足够我们使用了。接下来&#xff0c;我会给…

全球133种语言自动翻译mishop大米外贸商城系统

提示&#xff1a;133种语言自动翻译&#xff0c;开源无加密。 文章目录介绍安装方法部分代码展示学习资料下载地址成品效果图片展示介绍 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 大米外贸商城系统 简称mishop 完全开源版&#xff0c;只需做一种语言一…

JXcore 打包在企业级项目里的合理运用和模块系统以及网络的配置详解【node.js】

文章目录 JXcore 打包模块系统netJXcore 打包 node.Js是面向服务器端和网络应用程序的开源跨平台运行环境。 JXcore是一个支持多线程的节点。对于js发行版,您可以在多个线程中安全运行,而无需对现有代码进行任何更改。 安装命令如下: $ curl https://raw.githubusercontent.…

Java语言学习全笔记保姆级学习

目录 文章目录一、Java基础篇1.接口和抽象类的区别2.重载和重写的区别3.和equals的区别4.异常处理机制5.HashMap原理6.想要线程安全的HashMap怎么办&#xff1f;7.ConcurrentHashMap原如何保证的线程安全&#xff1f;8.HashTable与HashMap的区别9.ArrayList和LinkedList的区别1…

Tauri 入门教程

Tauri入门教程1 简介2 创建Tauri项目(页面基于Vue)2.1 环境准备2.2 创建工程3 Tauri 工程目录介绍4 页面调用rust方法5 事件系统6 HTTP请求7 文件系统8 对话框9 窗口配置10 打包1 简介 Tauri:构建跨平台的快速、安全、前端隔离应用。Tauri 是一个相对较新的框架&#xff0c;允…

Apollo 应用与源码分析:Monitor监控-硬件监控-CAN监控

目录 基本概念 CAN Card CAN - 原始套接字 ESD CAN 监控分析 Socket Can监控分析 基本概念 CAN Card 首先需要直到CAN的一些基本的概念。 CAN 是Controller Area Network 的缩写&#xff08;以下称为CAN&#xff09;&#xff0c;是ISO国际标准化的串行通信协议。在汽车产…

Elastic Stack 环境配置与框架简介

目录 简介 什么是Elastic Stack Elasticasearch Logstash Kibana Beats 框架图 下载 配置 一、安装java环境 启动 Elasticsearch Kibana FileBeat Logstash 测验 简介 什么是Elastic Stack Elastic Stack缩写为elk&#xff0c;它由三个软件组成&#xff1a;E…

唯品会:高利润,慢增长?

配图来自Canva可画 近日&#xff0c;阿里、京东等互联网大厂纷纷发布了新一季度的财报&#xff0c;从其财报不难看出&#xff0c;国内头部电商平台已经告别了一路狂奔的时代&#xff0c;开始愈发稳健起来。唯品会虽然在体量和规模上都还不能和这两家巨头相比&#xff0c;但自其…

36、Java——吃货联盟订餐系统(JDBC+MySQL+Apache DBUtils)

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java案例分…

关于物联网你需要知道的一切

如果你想要一个更像 wiki &#xff08;维基百科&#xff09;的定义「什么是物联网&#xff1f;」&#xff0c;我们可以将其视为连接到 Internet 的全球对象网络&#xff0c;这些对象能够在没有人为干预的情况下&#xff0c;相互交互和交换数据。符合这一的一般定义的解决方案&a…

Java项目:基于jsp+sevlet+mysql日记系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目主要功能有&#xff1a; 写日记 查看日记 日记删除 日记修改 日记类别添加 日记类别修改 日记类别删除 个人信息查看 个人信息修改 分页…

java刷题day 05

一. 单选题&#xff1a; 解析&#xff1a; 5 >> 2 相当于 5除于2两次&#xff0c;等于1>>> 表示无符号右移&#xff0c;高位用 0 填充&#xff0c;0001右移两位 0000&#xff0c;所以选A解析&#xff1a;作对这道题的关键是要理解Java的值传递&#xff0c;关于值…

婚纱租赁系统毕业设计,婚纱租赁管理系统设计与实现,论文毕设作品参考

功能清单 【后台管理员功能】 广告管理&#xff1a;设置小程序首页轮播图广告和链接 留言列表&#xff1a;所有用户留言信息列表&#xff0c;支持删除 会员列表&#xff1a;查看所有注册会员信息&#xff0c;支持删除 资讯分类&#xff1a;录入、修改、查看、删除资讯分类 录入…

【Milvus的以文搜图】

0. 介绍 以文搜图指的是&#xff0c;根据文本描述&#xff0c;从图像数据库中检索与文本内容相似的图像数据并返回。通过在CSDN中搜索以文搜图&#xff0c;找到了如下两篇文章&#xff1a; 从零到一&#xff0c;教你搭建「以文搜图」搜索服务&#xff08;一&#xff09;_Zill…