JavaScript—之对象参数的引用传递

变量

 

1.JavaScript hoisting

 

>>请看例子,我们拿Chrome的console作为JS的运行环境。

上面直接执行console.log(a), 不带一点悬念地抛出了not defined 错误。这是预料之中的。

看下面进化后的代码:

之前变量没有定义的错误没了,取而代之的是告诉我们a的值是 'undefined'。先不管a的值缘何为 'undefined' 了,至少可以知道现a这个变量是定义了,因为之前报的' a is not defined'的错误没有了。

这正是因为JavaScript 中的一个声明提前的特性起的作用。

JavaScript中可以提前使用在后面语句中声明的变量,这种特性叫被国外某网友(ben cherry)称为Hoisting (非官方术语) 。 可以理解为将变量的声明提前了,所以在变量声明前使用变量不会报错。而且这一特性不仅限于变量名,对于函数的声明也是同样的效果。

第一次对函数foo()的调用同样报 'not defined' 错误。这是合情合理同时是合法的。因为从头到尾就没有定义这么一个叫作foo() 的东西。

之后将函数调用写在最前面,但函数的定义我们写在了之后。

 

>> 再来看上面对a的输出值为'undefined'的问题。

这里需要深入理解Hoisting这一特性。它的提前只是将声明提前,而对变量的赋值并没有跟着提前。这点很关键。也就是为什么我们可以在第一句使用变量a但它的值却是 'undefined'。 JavaScript里面声明了但还未赋值的变量其值默认便是 'undefined'。

 

按照Hoisting来解释,最终生成的等价代码其实差不多应该就是这样的:

 

2.直接对字符串字面量调用其方法

 

可以直接对字符串字面量调用方法,JS解析器会自动把字符串变量转为一个字符串类型暂存,然后调用字符串上的方法,完了之后再将暂存的字符串类型销毁。

所以你会看到下面这种用法。

我们可以理解为解析器在后台声明了一个变量暂存这个字符串然后再调用的length方法。

 

函数

 

1.匿名函数无法在声明前调用

 

正如上面介绍的Hoisting特性,函数可以定义在调用之前也可以定义在调用之后:

但仅限于上述这种方式定义的函数。对于匿名函数上述规则不适用。

 

2. 参数变更影响到函数外部

 

当传递给函数的参数是一个数组或对象时,在函数体内对这个传入的参数的更改会影响到函数体外的原传入值。

一般说来,对参数的更改不会影响到原来变量的值,更改只在函数体内起作用:

上述代码中,将name变量赋值为'Wayou Liu' 然后传入change() 函数。在函数体内将传入的参数值改为'Liu Wayou'。然后再输出,不出意外地,输出的是变量原来的值'Wayou Liu'。因为当name传入change函数后,在函数体内,相当于有一个name的副本,这个副本的值等于name,之后在函数体内对其做的操作是在这个副本上进行的。

但情况有所不同,当传入的参数是数组、对象时,在函数体内对参数所做的更改会反映到原变量上。

可以看出,上面代码中已经把friut数组的第一个元素更改了。

下面是关于对象的例子:

可以很明显地看到函数体内对参数的改动影响到了原来的变量,这与通常情况下的传参有质的区别了。需要特别注意。

But,当在函数体内对传入的数组或对象赋值时,这个更改不会反映到函数体外的原变量身上!

请看:

按照上面函数内部的更改会反映到原变量的理论,你肯定觉得执行完change()后person变量的name属性的值已经变成'Tom'了吧。但结果让人有点难以接受。

原因在于,当在函数体内使用赋值操作时,系统就创建了一个变量名为p的变量。这个p是函数内部的变量,对它进行赋值当然只在函数体内起作用,外面的person还是原来的person。

这一步与原来代码的操作差别仅在于在函数体内是对参数赋新值呢还是对参数的属性或数组的元素进行更改。

 

3.使用arguments来接收个数未定的参数

 

有时候我们写了个函数但它接收的参数个数不确定,有时候我们在调用一个函数的时候或许也不确定要传多少个参数。参数需要变成动态的。

这时可以通过函数内arguments来接收传递到一个函数的所有参数。

具体说来,就是在函数体内默认有个arguments变量,它保存了调用这个函数时传递来的所有参数,总个数及每个参数的值。它是一个类似于数组的变量,每个参数会成为它的一个元素,可以通过游标来进行访问。

通过arguments.length可以知道参数个数。

下面这个例子来自MDN:

时间: 2024-09-26 08:03:49

JavaScript—之对象参数的引用传递的相关文章

JavaScript对象参数的引用传递_javascript技巧

今天碰到一个问题,怎样把参数变更影响到函数外部,如: <script> var myname = "wood"; A(myname); document.write(myname); function A(n) { n = "Yao"; } </script> 输出结果还是wood,说明当myname传入A函数后,在函数体内,相当于有一个myname的副本,这个副本的值等于myname,之后在函数体内对其做的操作是在这个副本上进行的. 但情况

深入分析C++ 值传递、指针传递、引用传递

而关于值传递,指针传递,引用传递这几个方面还会存在误区, 所有我觉的有必要在这里也说明一下~ 指针与引用的相同点与不同点: ★ 相同点: 1. 都是地址的概念: 指针指向一块内存,它的内容是所指内存的地址:引用是某块内存的别名. ★ 区别: 1. 指针是一个实体,而引用仅是个别名: 2. 引用使用时无需解引用(*),指针需要解引用: 3. 引用只能在定义时被初始化一次,之后不可变:指针可变: 引用"从一而终" ^_^ 4. 引用没有 const,指针有 const,const 的指针不

java只有值传递,不存在引用传递

今天,我在一本面试书上看到了关于java的一个参数传递的问题: 写道 java中对象作为参数传递给一个方法,到底是值传递,还是引用传递?  我毫无疑问的回答:"引用传递!",并且还觉得自己对java的这一特性很是熟悉! 结果发现,我错了! 答案是: 值传递!Java中只有按值传递,没有按引用传递!   回家后我就迫不及待地查询了这个问题,觉得自己对java这么基础的问题都搞错实在太丢人!   综合网上的描述,我大概了解了是怎么回事,现在整理如下,如有不对之处望大神提出!   先来看一个

php函数传值的引用传递注意事项分析_php技巧

本文实例讲述了php函数传值的引用传递注意事项.分享给大家供大家参考,具体如下: Strict standards: Only variables should be passed by reference 网上查到资料有这么一句话: 在php5.3以上版本会出这个问题,应该也和php的配置有关,只要把这一句拆成两句就没有问题了.因为array_walk的参数是引用传递的,5.3以上默认只能传递具体的变量,而不能通过函数返回值.当然你也可以修改php.ini 里的 error_reporting

javascript克隆对象深度介绍_基础知识

js一般有两种不同数据类型的值: 基本类型(包括undefined,Null,boolean,String,Number),按值传递: 引用类型(包括数组,对象),按址传递,引用类型在值传递的时候是内存中的地址. 克隆或者拷贝分为2种: 浅度克隆:基本类型为值传递,对象仍为引用传递. 深度克隆:所有元素或属性均完全克隆,并于原引用类型完全独立,即,在后面修改对象的属性的时候,原对象不会被修改. 复制代码 代码如下: function cloneObject(obj){ var o = obj.c

php函数的传值如果需要引用传递注意的细节

  Strict standards: Only variables should be passed by reference 网上查到资料有这么一句话: 在php5.3以上版本会出这个问题,应该也和php的配置有关,只要把这一句拆成两句就没有问题了.因为array_walk的参数是引用传递的,5.3以上默认只能传递具体的变量,而不能通过函数返回值.当然你也可以修改php.ini 里的 error_reporting = E_ALL | E_STRICT,但这终究不符合规范.         

javascript setTimeout()传递函数参数(包括传递对象参数)_javascript技巧

于是,上网查找了一下,用了另一种写法setTimeout("fun("+参数+")", 1000),还是不行,但是以上写法在传递form表单的textarea是可以的,比如hml是这样: 复制代码 代码如下: <body> <div class="main"> <div id="showpane" class="showpane"> </div> <di

javascript window.setTimeout可传递参数和对象参数

/* 功能:修改 window.setTimeout,使之可以传递参数和对象参数 (同样可用于setInterval) 使用方法: setTimeout(回调函数,时间,参数1,...,参数n) (FF已经原生支持,IE不支持) */  代码如下 复制代码 var __sto = setTimeout; window.setTimeout = function(callback,timeout,param){ var args = Array.prototype.slice.call(argum

请教关于JavaScript中的对象是按照值传递还是引用传递

问题描述 请教关于JavaScript中的对象是按照值传递还是引用传递 function SetName(obj){ obj.name="Tom";//执行之前,此时的obj和Person的name属性均为undefined obj1=new Object(); obj1=obj;//声明一个全局对象,那么obj.obj1和Person此时应该是同一个对象 }//SetName函数执行完之后,obj对象销毁,其余对象仍然存在 Person=new Object();//声明Person