转:《JavaScript—之对象参数的引用传递》
转自:博客园 Wayou http://www.cnblogs.com/Wayou/p/javascript_arguments_passing_with_reference.html
变量
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:
转:《JavaScript—之对象参数的引用传递》的更多相关文章
- 转《在浏览器中使用tensorflow.js进行人脸识别的JavaScript API》
作者 | Vincent Mühle 编译 | 姗姗 出品 | 人工智能头条(公众号ID:AI_Thinker) [导读]随着深度学习方法的应用,浏览器调用人脸识别技术已经得到了更广泛的应用与提升.在 ...
- face-api.js:一个在浏览器中进行人脸识别的 JavaScript 接口
Mark! 本文将为大家介绍一个建立在「tensorflow.js」内核上的 javascript API——「face-api.js」,它实现了三种卷积神经网络架构,用于完成人脸检测.识别和特征点检 ...
- TensorFlow.js之安装与核心概念
TensorFlow.js是通过WebGL加速.基于浏览器的机器学习js框架.通过tensorflow.js,我们可以在浏览器中开发机器学习.运行现有的模型或者重新训练现有的模型. 一.安装 ...
- 在Java中直接调用js代码(转载)
http://blog.csdn.net/xzyxuanyuan/article/details/8062887 JDK1.6版添加了新的ScriptEngine类,允许用户直接执行js代码. 在Ja ...
- 第十一章:WEB浏览器中的javascript
客户端javascript涵盖在本系列的第二部分第10章,主要讲解javascript是如何在web浏览器中实现的,这些章节介绍了大量的脚本宿主对象,这些对象可以表示浏览器窗口.文档树的内容.这些章节 ...
- 在Java中直接调用js代码
JDK1.6版添加了新的ScriptEngine类,允许用户直接执行js代码. 在Java中直接调用js代码 不能调用浏览器中定义的js函数,会抛出异常提示ReferenceError: “alert ...
- TensorFlow.js入门(一)一维向量的学习
TensorFlow的介绍 TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理.Tensor(张量)意味着N维数组,Flow(流)意味着 ...
- JavaScript权威指南--WEB浏览器中的javascript
知识要点 1.客户端javascript window对象是所有客户端javascript特性和API的主要接入点.它表示web浏览器的一个窗口或窗体,并且可以用window表示来引用它.window ...
- 解决webkit浏览器中js方法中使用window.event提示未定义的问题
这实际上是一个浏览器兼容性问题,根源百度中一大堆,简要说就是ie中event对象是全局变量,所以哪里都能使用到,但是webkit内核的浏览器中却不存在这个全局变量event,而是以一个隐式的局部变量的 ...
- JS Date当前时间:获取日期时间方法在各浏览器中的差异
转自:http://www.feiesoft.com/00047/<script type="text/javascript"> // JS Date当前时间获取方法在 ...
随机推荐
- 对easyui datagrid组件的一个小改进
#对easyui datagrid组件的一个小改进 ##问题 在实际项目中使用datagrid时,受版面限制,有时候表格不能太大,这时候表格里面的内容就不能完全显示,用户需要经常拖动调整列宽才能看完整 ...
- Zookeeper,Hbase 伪分布,集群搭建
工作中一般使用的都是zookeeper和Hbase的分布式集群. more /etc/profile cd /usr/local zookeeper-3.4.5.tar.gz zookeeper在安装 ...
- 使用gulp、yeoman、bower建站
前端建站工具 标签 : 工具 *** 脚手架:yeoman 用途 快速搭建新项目 为项目增加新部分 创建模块或者包 引导新服务 ... 开始 安装yo和generator npm i -g yo np ...
- <转载>linux下内存泄露查找、BUG调试
先收藏着,抽空好好看看:http://www.ibm.com/developerworks/cn/linux/l-pow-debug/ 简介 调试程序有很多方法,例如向屏幕上打印消息,使用调试器,或者 ...
- POJ 1852 Ants (等价思考)
题意:在一根杆上有 n 只蚂蚁,速度为1,方向不定,如果相碰,则反向运动,问你最长的时间和最短时间,所有蚂蚁都掉下杆去. 析:换个方法想,如果两只蚂蚁相碰了,会有什么现象?其实就和没有碰撞是一样的,没 ...
- ssh+dwr 的使用源码案例
加入dwr.jar包 ======jsp=============== <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitiona ...
- python安装(windows)
1.python安装(windows) 1.1 下载安装包 https://www.python.org/downloads/ 1.2 安装 python2.7默认安装路径:C:\python27 注 ...
- Json.Net学习笔记
http://www.cnblogs.com/xiaojinhe2/archive/2011/10/28/2227789.html Newtonsoft.Json(Json.Net)学习笔记 http ...
- 关于C#中文本模板(.tt)的简单应用
这两天做项目突遇 .tt文件,之前没有接触过,so查询学习做笔记,帮助记忆和后来者. 在项目添加中点击选择文本模板 下面贴出代码,做了简单的注释 <#@ template debug=" ...
- CloudStack采用spring加载bean(cloud-framework-spring-module模块)
CloudStackContextLoaderListener /* * Licensed to the Apache Software Foundation (ASF) under one * or ...