理解Javascript_14_函数形式参数与arguments


Posted in Javascript onOctober 20, 2010

注:在阅读本博文前请先阅读《理解javascript_13_执行模型详解》
注:本文的部分内容是自已的一些推论,并无官文文档作依据,如有错误之后,还望指正。
生涩的代码
我们先来看一段比较生涩的代码:

function say(msg,other,garbage){ 
alert(arguments[1]);//world 
var other = 'nice to meet you!'; 
var msg; 
alert(arguments.length); 
alert(msg);//hello 
alert(other);//nice to meet you! 
alert(arguments[1]);//nice to meet you! 
alert(garbage);//undefined 
} 
say('hello','world');

你能正确的解释代码的执行结果吗?思考一下.

我想代码运行的结果,应该会和你的想象有很大的出入吧!为什么msg正常输出为hello,而不是undefined呢?函数定义的参数和函数内部定义的变量重复了会发生什么呢?arguments和函数定义时的参数有什么关系呢?让我们来一一解答:
简单的内存图
理解Javascript_14_函数形式参数与arguments
注:虚线表示的是曾经引用的指向。

解答

首先,我们来了解两个概念,形式参数和实际参数。形式参数指的是定义方法时所明确指定的参数,由于Javascript语言的灵活性,javascript并不要求方法调用时,所传递的参数个数与形式参数一致.而javascript实际调用时所传递的参数就是实际参数。arguments指的就是实际参数。从say方法中可以看出,say定义了三个形式参数,而实际调用时只传递了两个值。因此arguments.length的值为2,而不是3.接着我们来看一下arguments的特殊行为,个人感觉arguments会将所有的实际参数都当作对象来看待,对于基本数据类型的实际参数则会转换为其对应的对象类型。这是根据在函数内定义与形式参数同名的变量并赋值,arguments对应的值会跟着改变来判断的。
接着我们来分析一下构建say方法执行上下文的过程,由于逻辑比较复杂,这里我写一些'伪代码'来进行说明:

function say(msg,other,garbage){ 
//先对函数声明的变量进行'预解析',内部执行流程,它是是不可见的 
var msg = undefined; 
var other = undefined; 
var garbage = undefined; 
//再对函数内部定义的变量进行'预解析' 
var other = undefined;//很明显,此时这个定义已经无意义了。 
var msg = undefined;//无意义 
//对实际参数进行赋值操作 
msg = new String('hello');//arguments的会将所有实际参数当作对象看待 
other = new String('world'); 
//正式进入函数代码部分 
alert(arguments[1]);//world 
other = 'nice to meet you!'; 
//var msg;这个已经被预解析了,因此不会再执行 
alert(arguments.length);//2 
alert(msg);//hello 
alert(other);//nice to meet you! 
alert(arguments[1]);//nice to meet you! 
alert(garbage);//undefined 
}

这段代码已经可以解释一面的所有的问题了。我就不多说了。
唯一强调的一点是在内部用var定义与形式参数同名的变量是无意义的,因为在程序'预解析'后,会将它们看作为同一个变量。

其它
关于arguments还有很多特性,我在《伪数组》一文中提到也提到了arguments,有兴趣的读者可以去看一下。arguments的实际应用你还可以参考一下这一篇文章 :
http://www.gracecode.com/archives/2551/

好了,也就这么多了。希望大家能多多指正,多提意见吧。

Javascript 相关文章推荐
关于javascript function对象那些迷惑分析
Oct 24 Javascript
浅谈javascript六种数据类型以及特殊注意点
Dec 20 Javascript
JQuery使用index方法获取Jquery对象数组下标的方法
May 18 Javascript
window.onload与$(document).ready()的区别分析
May 30 Javascript
jquery实现简单实用的弹出层效果代码
Oct 15 Javascript
js实现一键复制功能
Mar 16 Javascript
微信小程序wx.request实现后台数据交互功能分析
Nov 25 Javascript
Express的HTTP重定向到HTTPS的方法
Jun 06 Javascript
JavaScript事件发布/订阅模式原理与用法分析
Aug 21 Javascript
浅谈vue后台管理系统权限控制思考与实践
Dec 19 Javascript
layer弹出框确定前验证:弹出消息框的方法(弹出两个layer)
Sep 21 Javascript
vue如何在data中引入图片的正确路径
Jun 05 Vue.js
理解Javascript_13_执行模型详解
Oct 20 #Javascript
用jquery与css打造个性化的单选框和复选框
Oct 20 #Javascript
Jquery插件之多图片异步上传
Oct 20 #Javascript
jquery判断checkbox(复选框)是否被选中的代码
Oct 20 #Javascript
jQuery下扩展插件和拓展函数的写法(匿名函数使用的典型例子)
Oct 20 #Javascript
JQuery 拾色器插件发布-jquery.icolor.js
Oct 20 #Javascript
Javascript技巧之不要用for in语句对数组进行遍历
Oct 20 #Javascript
You might like
php实现的click captcha点击验证码类实例
2014/09/23 PHP
PHP GD库生成图像的几个函数总结
2014/11/19 PHP
js停止输出代码
2008/07/20 Javascript
javascript cookie操作类的实现代码小结附使用方法
2010/06/02 Javascript
JavaScript高级程序设计(第3版)学习笔记 概述
2012/10/11 Javascript
Jquery中"$(document).ready(function(){ })"函数的使用详解
2013/12/30 Javascript
JavaScript基本语法讲解
2015/06/03 Javascript
jQuery实现的超简单点赞效果实例分析
2015/12/31 Javascript
JS及PHP代码编写八大排序算法
2016/07/12 Javascript
jQuery实现的背景颜色渐变动画效果示例
2017/03/24 jQuery
从零开始学习Node.js系列教程六:EventEmitter发送和接收事件的方法示例
2017/04/13 Javascript
jquery.rotate.js实现可选抽奖次数和中奖内容的转盘抽奖代码
2017/08/23 jQuery
基于jQuery实现图片推拉门动画效果的两种方法
2017/08/26 jQuery
Express进阶之log4js实用入门指南
2018/02/10 Javascript
spring+angular实现导出excel的实现代码
2019/02/27 Javascript
详解如何运行vue项目
2019/04/15 Javascript
vue实现全匹配搜索列表内容
2019/09/26 Javascript
vuex分模块后,实现获取state的值
2020/07/26 Javascript
微信小程序获取当前时间及星期几的实例代码
2020/09/20 Javascript
python生成指定长度的随机数密码
2014/01/23 Python
Python多线程结合队列下载百度音乐的方法
2015/07/27 Python
神经网络python源码分享
2017/12/15 Python
详解python 注释、变量、类型
2018/08/10 Python
python与字符编码问题
2019/05/24 Python
python绘制已知点的坐标的直线实例
2019/07/04 Python
python openCV获取人脸部分并存储功能
2019/08/28 Python
python 读取数据库并绘图的实例
2019/12/03 Python
python、PyTorch图像读取与numpy转换实例
2020/01/13 Python
Python图像处理库PIL的ImageDraw模块介绍详解
2020/02/26 Python
Python greenlet和gevent使用代码示例解析
2020/04/01 Python
python实现canny边缘检测
2020/09/14 Python
Python调用高德API实现批量地址转经纬度并写入表格的功能
2021/01/12 Python
移动端Html5中百度地图的点击事件
2019/01/31 HTML / CSS
有趣的睡衣和礼物:LazyOne
2019/11/27 全球购物
介绍一下sql server的安全性
2014/08/10 面试题
穆斯林的葬礼读书笔记
2015/06/26 职场文书