JavaScript 基础(六)

JavaScript 基础(六)

arguements

arguements 是一个类数组对象

后台语言会有一种函数重载现象。 就是函数名相同, 但是传递的参数不同,属于不同的函数。

JavaScript 中没有重载现象

JavaScript 中函数名相同,传递的参数不同,后面的函数会覆盖前面的。

function fun(x, y) {
  console.log(1);
}
function fun(x, y, z) {
  console.log(2);
}
fun(1, 2)
// 2
复制代码

当函数执行时,传递的实际参数会存入到 arguments 类数组对象中

arguments 可以通过数组下标获取任意一项

function sum(a, b) {
  return a + b + arguments[2];
}
console.log(sum(1, 2, 3, 4, 5, 6));
// a = 1, b =2, arguments[2] = 3
// 6

function sum(a, b) {
  console.log(arguments);
  console.log(arguments.length);
  console.log(arguments[0]);
  console.log(arguments[1]);
  console.log(arguments[2]);
  console.log(arguments[3]);
  console.log(arguments[4]);
  console.log(arguments[5]);
  console.log(arguments[6]);
  console.log(arguments[7]);
  console.log(arguments[8]);
  console.log(arguments[9]);
  // arguments可以通过数组下标进行赋值
  arguments[8] = 100;
  console.log(arguments[8]);
}
sum(1, 2, 3, 4, 5, 6, 7);
// [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, '6': 7 }
// 7
// 1 2 3 4 5 6 7 undefined undefined undefined
// 100

复制代码

arguments 可以通过数组遍历得到所有项

function sum() {
  for (var i = 0; i < arguments.length; i++) {
    console.log(arguments[i]);
  }
}
sum(1, 2, 3, 4, 5, 6, 7);
// 1 2 3 4 5 6 7 
复制代码

并不是所有的数组方法都适用于 arguments

function sum() {
  for (var i = 0; i < arguments.length; i++) {
    arguments.slice(2, 5) // 语法错误 Uncaught TypeError
  }
}
sum(1, 2, 3, 4, 5, 6, 7);
// arguments.slice is not a function
复制代码

我们根据传递的实际参数的个数的不同,函数执行不同操作。(模拟函数的重载现象)

案例1: 当函数传递2个参数时,求2个参数和;当传递3个参数时,先比较前两个参数较大值与第三个参数求和

// 方法1
function sum(a, b, c) {
  if (arguments.length === 2) {
    return a + b;
  } else {
    return (a > b ? a : b) + c;
  }
}
console.log(sum(1, 2));
// 3
console.log(sum(1, 2, 3));
// 5

// 方法2
function sum(a, b, c) {
  switch (arguments.length) {
    case 2:
      return a + b;
      break;
    case 3:
      return (a > b ? a : b) + c;
      break;
    default:
      return '参数错误';
      break;
  }
}
console.log(sum(1, 2));
// 3
console.log(sum(1, 2, 3));
// 5
console.log(sum(1, 2, 3, 4));
// 参数错误
复制代码

案例2:当传递1个参数时,判断这个数的奇偶;如果传递2个参数,判断这两个参数的奇偶性是否相同

function oddOrEven(a, b) {
  switch (arguments.length) {
    case 1:
      if (a % 2 === 0) {
        return a + '是偶数';
      } else {
        return a + '是奇数';
      }
      break;
    case 2:
      if ((a + b) % 2 === 0) {
        return a + '和' + b + '奇偶性相同';
      } else {
        return a + '和' + b + '奇偶性不同';
      }
      break;
    default:
      return '参数错误';
      break;
  }
}

console.log(oddOrEven(5));
// 5是奇数
console.log(oddOrEven(5, 6))
// 5和6奇偶性不同
console.log(oddOrEven(5, 7));
// 5和7奇偶性相同
复制代码

IIFE

IIFEImmediately Invoked Function Expression 的缩写, 意为立即调用函数表达式

IIFE 表示函数在定义的时候,就立即执行

// ①正常写法
function fun() {
  console.log(1);
}
fun();
// 1


// ②错误写法
function fun() {
  console.log(1);
}();  //错误写法
// Uncaught TypeError: Unexpected token )


// ③函数表达式可以立即执行(不推荐)
var fun = function haha() {
  console.log(2);
}();
// 2
复制代码

() 表示立即执行,但是不能直接跟在 function 定义函数的后面,() 只能跟在函数名或者函数表达式的后面

function 关键字定义的函数矮化为表达式

矮化方法: 在函数前面加数学运算符(常使用小括号)

// ④ 矮化为表达式 (+/-/!)
!function fun() {
  console.log(3);
}();
// 3

// ⑤完整版本
(function fun() {
  console.log(4);
})();
// 4

// ⑥简写方法(匿名函数)
(function () {
  console.log(5);
})();
// 5

// 传参写法
(function (a, b) {
  console.log(a+b);
})(3, 3);
// 6

复制代码

IIFE 能够关住自己的作用域

(function fun(a, b) {
  console.log(a + b);
})(1, 2);
// 3
fun(1,2)
// Uncaught TypeError:  fun is not defined
复制代码
(function (a) {
  a ++;
  console.log(a);
})(5);
// 6

(function (a) {
  a ++;
  console.log(a);
})(8);
// 9
复制代码

IIFE 中的匿名函数如果有返回值,可以直接作为值参与运算

function sum(a, b, c) {
  return (function (x, y) {
    return (x > y ? x: y)
  })(a, b) + c;
}
console.log(sum(1, 2, 3));
// 5
复制代码

结合数组观察闭包

闭包:能记住它定义时的内部语句和外部环境

数组中的数据可以是任何类型,现在让数组的每一项存入一个函数

var arr = [];
for (var i = 0; i < 10; i++) {
  arr[i] = function () {
    return i
  }
}
console.log(arr);
// [ [Function], [Function], [Function], [Function], [Function], [Function], [Function], [Function], [Function], [Function] ]
// 函数执行时 i已经变成了10
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]());
}
// 10 10 10 10 10 10 10 10 10 10
复制代码

要想每个函数输出的i不同,又两种方法

  • 采用ES6中的新的定义变量的方法 let

    // var 改为 let
    var arr = [];
    for (let i = 0; i < 10; i++) {
      arr[i] = function () {
        return i;
      }
    }
    for (let i = 0; i < arr.length; i++) {
      console.log(arr[i]());
    }
    // 0 1 2 3 4 5 6 7 8 9
    复制代码
  • 使用 IIFE 立即执行函数

    // 使用IIFE 立即执行函数
    var arr = [];
    for (var i = 0; i < 10; i++) {
      (function (x) {
        arr[x] = function () {
          return x;
        }
      })(i);
    }
    for (let i = 0; i < arr.length; i++) {
      console.log(arr[i]());
    }
    // 0 1 2 3 4 5 6 7 8 9
    复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享