js传参是按值传递还是按引用传递?

数据类型

基本数据类型

number、string、boolean、null、undefined   基本数据类型的值保存在栈中;

引用数据类型

array、object、function 等对象,引用类型的数据保存分为两部分:

  • 地址

其中栈中是保存地址的引用,堆中保存真正的值  如

什么是按值传递?什么是按引用传递?

按值传递(call by value):函数的形参是被调用时所传实参的副本,修改形参的值并不会影响实参。

按引用传递(call by reference)时,函数的形参接收实参的隐式引用,而不再是副本。这意味着函数形参的值如果被修改,实参也会被修改,同时两者指向相同的内存地址。

Js传递方式

参数是基本数据类型:

1     var a = 10;
2     function add(a) {
3         a = 20;
4         console.log(a);//20
5     }
6     add(a);
7     console.log(a);//10

变量a在add 内部改变了值,并没有影响到外部的a变量;

参数是引用类型:

1 //引用类型
2     var person = {name: ‘joel‘, age: 11}
3     function foo(o) {
4         o.name = ‘alen‘;//改变对象的值
5         o = {name: ‘elire‘}//改变对象的地址
6         console.log(o.name); //elire
7     }
8     foo(person);
9     console.log(person.name);//alen

如果是按照引用传递,传进去的o对象跟外部的person对象指向的内存应该是同一个,但是foo()内部o.name 是elire,外部的person.name 是alen,所以尽管是引用类型数据传递的时候也不是按引用传递;

继续看下面demo:

 1     var v1 = []
 2     var v2 = {};
 3     var v3 = {};
 4     function demo1(v1, v2, v3)
 5     {
 6         v1 = [1];
 7         v2 = [2];
 8         v3 = {a:3}
 9     }
10     demo1(v1, v2, v3);
11     console.log(v1); // 空白
12     console.log(v2); // [object Object]
13     console.log(v3.a); // undefined

由此可见:v1、v2、v3 都没有被改变,v1 仍然是零个元素的数组,v2、v3 仍然是空白的对象。即引用类型数据也是按照值传递的,先是拷贝了栈中的地址,然后在demo1()内部改变了地址的指向。

但是引用类型按值传递与基本类型数据按值传递还是有区别的。

基本数据类型,如数字、字符串是把值直接复制进去了,而引用类型 如数组、对象是把变量地址复制进去。

前面我们让 v1、v2、v3 作为参数进入函数后,就有了地址副本,这些地址副本的指向和外面的 v1、v2、v3 的地址指向是相同的。但我们为 v1、v2、v3 赋了值,也就是说我们把地址副本的指向改变了,指向了新的数组和对象。这样内部的 v1、v2、v3 和外部的 v1、v2、v3 就完全断了。
如果我们不赋新值,而是直接操作它,那么传进去的仍然是和外面的 v1、v2、v3 指向的同一块数组或对象,因为我们没有改变他们的指向。

如:

 1     var v1 = []
 2     var v2 = {};
 3     var v3 = {a:0};
 4     function demo2(v1, v2, v3)
 5     {
 6         v1.push (1);
 7         v2.a = 2;
 8         v3.a = 3;
 9     }
10
11     demo2(v1, v2, v3);
12     console.log(v1); // 1
13     console.log(v2.a); // 2
14     console.log(v3.a); // 3

总结

基本数据类型,如数字、字符串是把值复制进去,而引用类型 如数组、对象是把变量地址复制进去,

如果没有改变传进去的地址指向,那么它们都是指向同一个内存地址;

如果改变了地址指向那么它们跟外部的对象是两个独立的对象,互不干扰;

时间: 2024-08-28 21:35:42

js传参是按值传递还是按引用传递?的相关文章

JS传参中文乱码问题.NET

前台js代码 window.location.href = "/product.aspx?id=2&title=" +encodeURIComponent(strtitle) 后台代码 title = HttpUtility.UrlDecode(title); 很简单这样就解决了中文乱码问题

ios向js传参的方法

在  - (void)webViewDidFinishLoad:(UIWebView *)webView  ; 事件中 [self.webView stringByEvaluatingJavaScriptFromString: @"useLocalPaths()"];    调用html页面的js方法

关于js传参问题解决的小窍门

1.今天在做项目的时候遇到一个问题,就是使用  点击事件的时候,参数如果为全数字就会出现点击无反应的问题.但是当参数为字符串或者动态内容的时候就会出现事件无法响应.比如    解决办法:是用转移字符,onclick=\"add(\\\'abc\\\')\";这样在方法中就可以使用了. 2.还有一个是在做拼接字符串的时候,如果是循环比较多的情况下,建议使用var xxx = new StringBuffer(); xxx.append();   来拼接这样会比直接使用字符串来拼接要好很多

关于js 传参使用——转义字符

var infoTemplate = new esri.InfoTemplate("线索内容","问题发生地:"+address+" <br/> 问题摘要:"+content+"  <a href='#' onclick='showDetails(\""+yw_guid+"\")'>详情</a>"); 如果不使用转义字符,则会直接将yw_guid的值作

java的传参究竟是按值传递的还是按引用传递的

这里来弄清楚Java的传参究竟是按值传递的还是按引用传递的. 形参和实参 传参的概念里,有形参和实参的区分.形参是定义方法名和方法体的时候使用的参数,目的是用来接收调用该方法的时候传入的参数:实参是调用有参方法的时候传入的参数,方法名后面的括号中的参数就是实参.理解起来可能有点抽象,简单理解就是,形参是定义方法的参数,实参是调用方法时实际传入的参数,区别在于[定义]和[调用]. 简单举个例子,我定义了一个打印名字的方法,传入一个name的参数,这个参数就是形参. public void prin

webview的使用以及js调用OC传参

webview如何想要js和oc交互,需要使用代理方法 ,并且需要和后台协定规则 -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ NSString *url = request.URL.absoluteString; NSLog(@"========%@&quo

Vue入门十三、路由的传参和取参

1.查询参login?id=12345 配置:(传参):to="{name:'login', query:{id:'loginid'}}"获取:(取参)this.$route.query.id 2.路由参数 配置:(传参):to="{name:'login', params:{id:'loginid'}}"获取:(取参)this.$route.params.id 3.路径参数register/registerid/info 配置:(传参):to="{nam

JS是按值传递还是按引用传递

按值传递(call by value)是最常用的求值策略:函数的形参是被调用时所传实参的副本.修改形参的值并不会影响实参. 按引用传递(call by reference)时,函数的形参接收实参的隐式引用,而不再是副本.这意味着函数形参的值如果被修改,实参也会被修改.同时两者指向相同的值. 按引用传递会使函数调用的追踪更加困难,有时也会引起一些微妙的BUG.  按值传递由于每次都需要克隆副本,对一些复杂类型,性能较低.两种传值方式都有各自的问题. JS的基本类型,是按值传递的. 1 var a

学习笔记:JavaScript传参方式———ECMAScript中所有函数的参数都是按值传递

我们把命名参数(arguments)视为局部变量,在向参数传递基本类型值时,如同基本类型变量的复制一样,传递一个副本,参数在函数内部的改变不会影响外部的基本类型值.如: 1 function add10(num){ 2 num += 10 ; 3 return num ; 4 } 5 var count = 10 ; 6 var result = add10(count); 7 alert(count);// 10 8 alert(result); //20 在向参数传递引用类型的值时,会把这个