javascript 学习之函数的参数详解

来源:互联网 发布:淘宝用户数量2016 编辑:程序博客网 时间:2024/05/16 13:56
javascript 函数的参数和C++之类的强类型语言有很大的差别。下面详细介绍了 javascript 函数参数的主要特点,一起来看看吧,希望对大家学习javascript有所帮助。
  显式参数和隐式参数
  · 显式参数(Parameters)
  // 函数定义的时候列出函数的显式参数function foo(parameter1, parameter2){}
  · 隐式参数(Arguments):函数的隐式参数是函数调用时传递给函数真正的值。javascript 中的参数在内部是用一个数组来表示的,函数接收到的始终都是这个数组,而不关心数组中包含哪些参数,在函数体内可以通过 Arguments 对象来访问这个参数数组。
  参数规则
  · 函数定义时显式参数没有指定数据类型。
  · 函数对隐式参数没有进行类型检测。
  · 函数对隐式参数的个数没有检测。(隐式参数个数和显式参数个数可以不同)
  默认参数
  如果函数在调用时没有提供隐式参数(也就是没有参数),参数会默认设置为: undefined
  一般是没有什么问题,但是建议最后为参数设置一个默认值:
  function a(x){
  if(x === undefined)
  x=0;
  }
  或者:
  function a(x){
  x = x || 0;
  }
  Arguments 对象
  如果函数调用的时候,传入的参数个数大于显式参数的个数,参数只能通过 Arguments 对象来调用。
  Arguments 对象是 javascript 函数内置的对象,它包含了函数调用时传入的参数数组。通过 Arguments 对象可以很容易的对每个传入的参数进行操作:
  function a(){
  var m = arguments[0]; // 第一个传入的参数
  var n = arguments[1]; // 第二个传入的参数,如果只传入一个参数,那么该值为 undefined
  var l = arguments.length; // 该值对应的函数调用时传入参数的个数
  var ll = a.length; // 该值对应的函数定义的参数个数
  }
  看起来 arguments 好像和数组一样,但是 arguments 是一个 object 对象,并不是数组,它是一个类数组对象,不能对它使用 push、join等方法。上面例子中的 arguments 中的 i 只是作为 arguments 对象的属性,并不能理解为数组的下标。
  内部属性
  ·callee:arguments 对象有一个 callee 属性,该属性是一个指针,指向拥有这个 arguments 对象的函数。
  下面是经典的阶乘函数:
  function factorial(num){
  if(num <= 1){
  return 1;
  }else{
  return num * factorial(num - 1);
  }
  }
  console.log(factorial(5));//120
  但是,上面这个函数的执行与函数名紧紧耦合在了一起,可以使用 arguments.callee 可以消除函数解耦:
  function factorial(num){
  if(num <= 1){
  return 1;
  }else{
  return num * arguments.callee(num - 1);
  }
  } console.log(factorial(5));//120
  但在严格模式下,访问这个属性会抛出
  TypeError 错误
  function factorial(num){  'use strict';
  if(num <= 1){
  return 1;
  }else{
  return num * arguments.callee(num - 1);
  }
  } //TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to themconsole.log(factorial(5));
  这时,可以使用具名的函数表达式
  var factorial = function fn(num){
  if(num <= 1){
  return 1;
  }else{
  return num * fn(num - 1);
  }
  };
  console.log(factorial(5));//120
  同步
  在形参个数和实参相同时,arguments 对象的值和对应形参的值保持同步:
  function a(m){
  console.log(m,arguments[0]); // 1 1
  arguments[0] = 2;
  console.log(m,arguments[0]); // 2 2
  m = 3;
  console.log(m,arguments[0]); // 3 3
  }
  a(1);
  注:虽然形参和对应 arguments 对象的值相同,但并不是相同的内存空间,它们是独立的内存空间,但是值会同步。
  不过在严格模式下,它们的值是独立的:
  function a(m){  'use strict'; // 严格模式
  console.log(m,arguments[0]); // 1 1
  arguments[0] = 2;
  console.log(m,arguments[0]); // 1 2
  m = 3;
  console.log(m,arguments[0]); // 3 2
  }
  a(1);
  当形参没有对应实参的时候,arguments 对象的值和形参并不同步:
  function a(m){
  console.log(m,arguments[0]); // undefined undefined
  arguments[0] = 2;
  m = 3;
  console.log(m,arguments[0]); // 3 2
  }
  a();
  参数传递
  javascript 中所有函数的参数都是按值传递的。也就是说,把函数外部的值复制到函数内部的参数,就和把值从一个变量复制到另一个变量一样。
  · 基本类型:向参数传递基本类型的值时,被传递的值会被复制给一个局部变量。
  · 引用类型:在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数的外部,当在函数内部重写引用类型的形参时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。

来源:简书
原创粉丝点击