函数和函数的作用域问题,arguments

this的值:在函数执行时,this关键字并不会指向正在运行的函数本身,而是指向调用该函数的对象.所以,如果你想在函数内部获取函数自身的引用,只能使用函数名或者使用argument.callee属性(严格模式下不可用),如果该函数是一个匿名函数,则你只能使用后者.

1.定义函数

三种方式:

1)函数声明 (function语句)

function name([param[, param[, ... param]]]) { statements }

name函数名.

param函数的参数的名称,一个函数最多可以有255个参数.

statements这些语句组成了函数的函数体.

2)函数表达式 (function操作符)

函数表达式和函数声明非常类似,它们甚至有相同的语法 (查看function操作符了解详情 ):

function [name]([param] [, param] [..., param]) { statements }

name函数名,可以省略,省略函数名的话,该函数就成为了匿名函数.

param函数的参数的名称,一个函数最多可以有255个参数.

statements这些语句组成了函数的函数体.

3)Function构造函数

和其他类型的对象一样,Function对象也可以使用new操作符来创建:

new Function (arg1, arg2, ... argN, functionBody)

arg1, arg2, ... arg
N一个或多个变量名称,来作为函数的形参名.类型为字符串,值必须为一个合法的JavaScript标识符,例如Function("x", "y","alert(x+y)"),或者逗号连接的多个标识符,例如Function("x,y","alert(x+y)")

functionBody一个字符串,包含了组成函数的函数体的一条或多条语句.

即使不使用new操作符,直接调用Function函数,效果也是一样的,仍然可以正常创建一个函数.

注意: 不推荐使用Function构造函数来创建函数.因为在这种情况下,函数体必须由一个字符串来指定.这样会阻止一些JS引擎做程序优化,还会引起一些其他问题.

2.arguments对象

在函数内部,你可以使用arguments对象获取到该函数的所有传入参数. 查看 arguments.

arguments 对象是函数内部的本地变量;arguments 已经不再是函数的属性了。

你可以在函数内部通过使用 arguments 对象来获取函数的所有参数。这个对象为传递给函数的每个参数建立一个条目,条目的索引号从 0 开始。例如,如果一个函数有三个参数,你可以通过以下方式获取参数:

arguments[0] arguments[1] arguments[2]

参数也可以被重新赋值:

arguments[1] = ‘new value‘;

arguments对象并不是一个真正的数组。它类似于数组,但没有数组所特有的属性和方法,除了 length。例如,它没有 pop 方法。不过可以将其转换成数组:

var args = Array.prototype.slice.call(arguments);

注:不应在 arguments 对象上使用 slice 方法,这会阻碍 JavaScript 引擎的优化 (比如 V8 引擎)。作为替代,应通过遍历 arguments 对象的方式来构建一个新的数组。

arguments 对象仅在函数内部有效,在函数外部调用 arguments 对象会出现一个错误。

如果你调用一个函数,当这个函数的参数数量比它显式声明的参数数量更多的时候,你就可以使用 arguments对象。这个技术对于参数数量是一个可变量的函数来说比较有用。 你可以用 arguments.length来得到参数的数量,然后可以用 argumentsobject 来对每个参数进行处理。 (想要得到当一个函数定义时的该函数的参数数量, 请使用 Function.length属性。)

function myConcat(separator) {
  var args = Array.prototype.slice.call(arguments, 1);
  return args.join(separator);
}
// returns "red, orange, blue"
myConcat(", ", "red", "orange", "blue");

// returns "elephant; giraffe; lion; cheetah"
myConcat("; ", "elephant", "giraffe", "lion", "cheetah");

3.递归

一个函数可以指向并调用自身。 有三种方法可以使一个函数指向自身:

  1. 函数名
  2. arguments.callee
  3. 一个指向函数的作用域内变量

例如, 考虑下面的函数定义:

var foo = function bar() {
   // statements go here
};

在函数体内, 下列语句是等价的:

  1. bar()
  2. arguments.callee()
  3. foo()

一个调用自身的函数称为递归函数. 在某些方面, 递归类同于一个循环. 都多次执行同一段代码, 并且都需要一个条件 (来避免无尽循环, 或者是无尽的递归). 例如,下面的循环:

function walkTree(node) {
   if (node == null) //
      return;
   // do something with node
   for (var i = 0; i < node.childNodes.length; i++) {
      walkTree(node.childNodes[i]);
   }
}

将每个递归算法转化为非递归的都是可能的,但通常逻辑会变得十分复杂,并且这样做需要用到栈。事实上,递归本身用到了栈:函数栈。(每次感觉都迷糊在这个栈里面

function foo(i) {
   if (i < 0)
      return;
   document.writeln(‘begin:‘ + i);
   foo(i - 1);
   document.writeln(‘end:‘ + i);
}
foo(3);
begin:3
begin:2
begin:1
begin:0
end:0
end:1
end:2
end:3

4.嵌套函数和闭包

你可以将一个函数嵌套在另一个函数内部.被嵌套的函数 (内部函数)是只属于嵌套它的函数(外部函数)的私有函数.这样就形成了一个闭包.

function addSquares(a,b) {
   function square(x) {
      return x * x;
   }
   return square(a) + square(b);
}
a = addSquares(2,3); // returns 13
b = addSquares(3,4); // returns 25
c = addSquares(4,5); // returns 41

由于内部函数形成了一个闭包,你可以把这个内部函数当做返回值返回,该函数引用到了外部函数和内部函数的两个参数:

function outside(x) {
   function inside(y) {
      return x + y;
   }
   return inside;
}
fn_inside = outside(3);
result = fn_inside(5); // returns 8

result1 = outside(3)(5); // returns 8

5.函数内的局部变量

arguments: 一个"类数组"的对象,包含了传入当前函数的所有实参.

arguments.callee : 指向当前正在执行的函数.

arguments.caller  : 指向调用当前正在执行的函数的函数,请使用arguments.callee.caller代替

arguments.length: 传入当前函数的实参个数.

arguments.callee.length:形参的个数

例子:检测一个函数是否存在

你可以使用typeof操作符来检测一个函数是否存在.下例中,首先检测window对象的noFunc属性是否是一个函数,如果是,则调用它,否则,进行其他的一些动作.

if (‘function‘ == typeof window.noFunc) {
   // 调用 noFunc()
 } else {
   // 进行其他动作
 }

注意在if语句中,使用的是对noFunc函数的引用,只有函数名,没有后面的括号"()",这样函数才不会被调用.

时间: 2024-10-22 19:48:38

函数和函数的作用域问题,arguments的相关文章

第 13 条:使用立即调用的函数表达式创建局部作用域

第 13 条:使用立即调用的函数表达式创建局部作用域这段程序(Bug 程序)输出什么? function wrapElements(a) { var result = [], i, n; for (i = 0, n = a.length; i < n; i++) { result[i] = function() { return a[i]; }; } return result; } var wrapped = wrapElements([10, 20, 30, 40, 50]); var f

[译]ES6箭头函数和它的作用域

原文来自我的前端博客: http://www.hacke2.cn/arrow-functions-and-their-scope/ 在ES6很多很棒的新特性中, 箭头函数 (或者大箭头函数)就是其中值得关注的一个! 它不仅仅是很棒很酷, 它很好的利用了作用域, 快捷方便的在现在使用以前我们用的技术, 减少了很多代码……但是如果你不了解箭头函数原理的话可能就有点难以理解. 所以,让我们来看下箭头函数, 就是现在! 执行环境 你可以自己去学习和尝试下, 你可以简单的把示例程序代码复制到你的浏览器控制

ES6箭头函数和它的作用域

原文来自我的前端博客: http://www.hacke2.cn/arrow-functions-and-their-scope/ http://es6rocks.com/2014/10/arrow-functions-and-their-scope/ 原文链接 译:@liningone 摇滚ES6中国站快要上线了,大家期待吧,也可以联系我或者ES6组织为这个活动做出点贡献! 在ES6很多很棒的新特性中, 箭头函数 (或者大箭头函数)就是其中值得关注的一个! 它不仅仅是很棒很酷, 它很好的利用了

读书时间《JavaScript高级程序设计》三:函数,闭包,作用域

上一次看了第6章,面向对象.这里接着看第7章. 第7章:函数表达式 定义函数有两种方式:函数声明.函数表达式 //函数声明 function functionName(arg0,arg1,arg2){ //code... } //函数表达式 var functionName = function(arg0,arg1,arg2){ //code... }; 函数声明有个重要的特征是函数申明提升.就是在执行代码前会先读取函数声明,意味着可以把函数声明放在调用它的语句后面. //函数声明提升 sayH

javascript回调函数,闭包作用域,call,apply函数解决this的作用域问题

在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实际上是一种对象,它可以“存储在变量中,通过参数传递给(别一个)函数(function),在函数内部创建,从函数中返回结果值”. 因为function是内置对象,我们可以将它作为参数传递给另一个函数,延迟到函数中执行,甚至执行后将它返回.这是在JavaScript中使用回调函数的精髓.本篇文章的剩余部

函数调用的几种方法 几种主流框架使用匿名函数模仿块级作用域的方式

函数调用的几种方法 js 里函数调用有4种模式:方法调用.正常函数调用.构造器函数调用.apply/call 调用.同时,无论哪种函数调用除了你声明时定义的形参外,还会自动添加2个形参,分别是 this 和 arguments.这里你既然问 this,那么就只谈 this.this 的值,在上面4中调用模式下,分别会绑定不同的值.分别来说一说:方法调用:这个很好理解,函数是一个对象的属性,比如 var a = { v : 0, f : function(xx) { this.v = xx; }

JS 字符串对象 数组对象 函数对象 函数作用域

一.内置对象 object对象:ECMAScript 中的所有对象都由这个对象继承而来:Object 对象中的所有属性和方法都会出现在其他对象中 ToString() : 返回对象的原始字符串表示.ValueOf() : 返回最适合该对象的原始值.对于许多对象,该方法返回的值都与 ToString() 的返回值相同 11种内置对象 包括: Array ,String , Date, Math, Boolean, Number  Function, Global, Error, RegExp ,

Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数

一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(First-Class Object)呢? 在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量.可以作为元素添加到集合对象中.可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的. 1.函数身为一个对象,拥有对象模型的三个通用属性:id.类型.和值.

JavaScript中的匿名函数及函数的闭包以及作用域

1. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85