1.每个函数都有一个arguments属性,表示函数的实参集合,这里的实参是重点,就是执行函数时实际传入的参数的集合。

2.arguments不是数组而是一个对象,但它和数组很相似,所以通常称为类数组对象,以后看到类数组其实就表示arguments。

3.arguments有length属性,可以用arguments[length]显示调用:

 function func(){
for(var i=0;i<arguments.length;i++){
console.log(arguments[i]);
}
} func("a",17,[1,2,3],{name:"javascript",type:"language"}); /*
a
17
[1, 2, 3]
{name: "javascript", type: "language"}
*/

4.Array.prototype.slice.call(arguments):

首先我们看看call是干啥的,举个例子:

 var obj1={
name:"java"
} window.name="javascript";
var func=function(){
console.log(this.name);
} func(); //javasript
func.call(obj1); //java

我们可以很清楚的看到,call的一个作用是可以改变函数运行的作用域,func中的this指向了obj1,(call和apply的其他作用请参阅js中call和apply的用法

那Array.prototype.slice.call(arguments)是干啥的呢,首先我们猜测Array.prototype.slice是一个方法,将它call(arguments)之后,Array.prototype.slice中的this就指向了arguments对象了。

其实Array.slice是一个数组复制函数,它接受两个参数(strat,[end]);从下标为start复制到下标为end,举个栗子:

 var numArr=[1,2,3,4,5];
console.log(numArr.slice(0,4)); //[1,2,3,4]
console.log(numArr.slice()); //[1,2,3,4,5]
console.log(numArr.slice(1)) //[2,3,4,5]

我们可以大胆的猜测一下slice函数的内部实现:参阅http://www.cnblogs.com/littledu/archive/2012/05/19/2508672.html

 Array.prototype.slice = function(start,end){
var result = new Array();
start = start || 0;
end = end || this.length; //this指向调用的对象,当用了call后,能够改变this的指向,也就是指向传进来的对象,这是关键
for(var i = start; i < end; i++){
result.push(this[i]);
}
return result;
}

注意当中的result.push(this[i]),当Array.prototype.slice.call(arguments)后,就变成了result.push(arguments[i]),这样就将arguments转成了一个实实在在的数组了。

5.小练习:

一个给对象添加属性的函数。

思考一下:首先得传入一个实参,这个实参是要被添加属性的对象。

剩下的参数是属性键值对,可以用对象表示:

 var obj={};
 //先看执行函数
function addProp(){
var obj=[].shift.call(arguments); //shift()函数是将数组的第一个值删除,并返回,这里是得到obj
var propArray=[].slice.call(arguments); //此时的argument[0]已被删除,所以propArray=[{name:"gao",age:"18"},{setName:function(name){this.name=name;}]
for(var i in propArray){
//prop[0]={name:"gao",age:"18"}
//prop[1]={setName:function(name){this.name=name;}
for(var j in propArray[i]){
obj[j]=propArray[i][j];
//obj[name]="gao"
//obj[age]="18"
//obj[setName]=function(name){this.name=name;}
}
}
} //执行函数
addProp(obj,{name:"gao",age:"18"},{setName:function(name){
this.name=name;
}});
console.log(obj.name); //gao
obj.setName("xiang");
console.log(obj.name); //xiang

浅谈arguments与arguments的妙用的更多相关文章

  1. 浅谈JS的arguments对象

    在JavaScript中,arguments属于当前对象的一个内置属性,arguments非常类似于Array对象,但是又不是实例的Array.比如: Array.prototype.testArg ...

  2. 浅谈[].slice.call(arguments, 1)

    今天在跟踪调试项目的代码时,发现在一个function中用到了这么一段[].slice.call(arguments, 1) 的代码.心中便起了疑惑,对于slice 和 call 的方法,倒是不怎么陌 ...

  3. 浅谈js的类数组对象arguments

    类数组对象:arguments总所周知,js是一门相当灵活的语言.当我们在js中在调用一个函数的时候,我们经常会给这个函数传递一些参数,js把传入到这个函数的全部参数存储在一个叫做arguments的 ...

  4. 浅谈HTML5单页面架构(二)——backbone + requirejs + zepto + underscore

    本文转载自:http://www.cnblogs.com/kenkofox/p/4648472.html 上一篇<浅谈HTML5单页面架构(一)--requirejs + angular + a ...

  5. 浅谈javascript函数节流

    浅谈javascript函数节流 什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等 ...

  6. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  7. 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理

    [微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...

  8. 浅谈JS严格模式

    浅谈JS严格模式 简介 何为严格模式?严格模式(strict mode)即在严格的条件下运行,在严格模式下,很多正常情况下不会报错的问题语句,将会报错并阻止运行. 但是,严格模式可以显著提高代码的健壮 ...

  9. C学习笔记(11)--- 可变参数,浅谈内存管理 【C基础概念系列完结】

    1.可变参数(variable arguments): 可变参数允许您定义一个函数,能根据具体的需求接受可变数量的参数. int func(int, ... )             (函数 fun ...

  10. [转载]浅谈JavaScript函数重载

     原文地址:浅谈JavaScript函数重载 作者:ChessZhang 上个星期四下午,接到了网易的视频面试(前端实习生第二轮技术面试).面了一个多小时,自我感觉面试得很糟糕的,因为问到的很多问题都 ...

随机推荐

  1. php 逐行读取文本文件

    在读取文本时,我们要注意一个事情,那就是换行符,应为我们在写文档时会手动换行,这个换行符需不需要保存就要看自己的需求了. 这里封装了两个方法,一个保留换行,一个不保留.$path为文件路径+文件名 1 ...

  2. 将参数传递给ASP.NET Core 2.0中的中间件

    问题 在ASP.NET Core的安装过程中,如何将参数传递给中间件? 解 在一个空的项目中添加一个POCO类来保存中间件的参数, publicclass GreetingOptions { publ ...

  3. 4. C++11非受限联合体

    在C/C++中,联合体是一种构造类型的数据结构.在一个联合体内,我们可以定义多种不同的数据类型,这些数据类型共享相同的内存空间,可以达到节省内存空间的目的. 1. 取消数据类型的限制 在C++98中, ...

  4. 华南理工大学“三七互娱杯”程序设计竞赛 HRY and codefire(概率期望DP)

    https://ac.nowcoder.com/acm/contest/874/A 题目:有两个账号 , 一开始都为0级 , 求任意一个账号升级到N的期望 要求:如果当前账号嬴了 , 就继续沿用当前的 ...

  5. solr 服务搭建

    1.  linux 中 安装jdk,  tomcat, 2. 下载 solr-4.10.3.tgz.tgz 并解压 解压后文件夹:solr-4.10.3 3. 将 solr-4.10.3/dist 下 ...

  6. 【GIS新探索】算法实现在不规则区域内均匀分布点

    1 概要 在不规则区域内均匀分布点,这个需求初看可能不好理解.如果设想一下需求场景就比较简单了. 场景1:在某个地区范围内,例如A市区有100W人口,需要将这100W人口在地图上面相对均匀的标识出来. ...

  7. Android中自定义组合控件

    Android中自定义控件的情况非常多,一般自定义控件可以分为两种:继承控件及组合控件.前者是通过继承View或其子类,重写方法实现自定义的显示及事件处理方式:后者是通过组合已有的控件,来实现结构的简 ...

  8. Ubuntu 下 unzip用法

    unzip [参数] <压缩文件> 参数: -P <密码> zip 压缩包的密码-f 覆盖原有文件-d <路径> 指定解压路径-n 解压缩时不覆盖原有文件-o 不经 ...

  9. SPSS学习系列之SPSS Statistics导入读取数据(多种格式)(图文详解)

    不多说,直接上干货! SPSS Statistics导入读取数据的步骤: 文件  ->  导入数据 成功! 欢迎大家,加入我的微信公众号:大数据躺过的坑     免费给分享       同时,大 ...

  10. Android组件--碎片(fragment)

    1. 基本概念 参考资料:http://blog.csdn.net/lmj623565791/article/details/37970961/ 一.什么是事务: 事务是应用程序中一系列严密的操作,所 ...