Skip to content
Netflix - 每月低至 25 元

第4章 函数

声明函数

函数声明

js
function 函数名() {
  函数体;
  return 需要返回的结果; // 只能返回一个值(最后一个值) 可返回数组
}

函数表达式

js
let 变量名 = function () {
  函数体;
  return 需要返回的结果; // 只能返回一个值(最后一个值) 可返回数组
};

区别

  • 函数名称:在函数表达式中可省略它,从而创建匿名函数
  • 函数声明可以先调用再声明,而函数表达式必须先定义再调用

调用函数

直接调用

js
函数名();

立即执行函数

  • 立即执行函数:函数在定义完后,直接调用自身
  • 优点:外部无法访问内部代码,且内部形成自己的作用域,防止与外部变量命名冲突
js
var num1 = 10;
(function() {
    var num1 = 20;
    console.log(num1); // 20
})();

console.log(num1); // 10

变量和函数提升

提升可以让我们先使用,后声明

js
// 变量的提升
x = 6;
console.log(x); //6
var x;

// 函数的提升
console.log(divide(8, 4));

function divide(a, b) {
  return a / b;
}

默认参数

  • 调用时不加参数,使用默认参数
  • 调用时有参数,则使用调用时的参数
js
function greetings(name = '世界') {
  console.log('你好,' + name);
}

greetings(); // 你好,世界
greetings('中国'); // 你好,中国
  • 调用时如需要用默认参数 则可以使用 undefined 表示默认参数,不可使用 null
js
function greetingsWithWeather(name = '世界', weather) {
  console.log('你好,' + name + ',今天是' + weather);
}
greetingsWithWeather(undefined, '晴天'); // 你好,世界,今天是晴天

递归

js
// 需要一个递归出口
// 从1加到n的递归
function sum(n) {
  if (n === 1) return 1; // 递归出口
  return n + sum(n - 1);
}

console.log(sum(3)); // 6

Arguments

Arguments 的特点

  • 具有数组的 length 属性
  • 按照索引的方式进行存储
  • 没有真正数组的一些方法 pop() push() 等等
js
function getMax() {
  // arguments = [2,125,123,74,114,134]
  var max = arguments[0];
  for (var i = 1; i < arguments.length; i++) {
    if (arguments[i] > max) {
      max = arguments[i];
    }
  }
  return max;
}

console.log(getMax(2, 125, 123, 74, 114, 134));

rest 和 arguments 对象的区别

  • rest 只包含那些没有对应形参的实参,而 arguments 包含了传给函数的所有实参
  • rest 是真正的数组,而 arguments 对象不是一个真正的数组
  • arguments 对象还有一些附加的属性 (如callee属性)
js
function variousArgs(num1, ...args) {
  console.log(num1); // 1
  console.log(args); // [2, 3]
  console.log(arguments); // [Arguments] {'0': 1, '1': 2, '2': 3}
}

variousArgs(1, 2, 3);

作用域

  • 如果一个变量在当前作用域没有定义
  • 向上级作用域,一层一层一次寻找,直至被找到
  • 如果全局作用域都没有找到,则显示 not defined
  • 自由变量查找是在函数定义的地方,向上级作用域查找,而不是执行的地方
js
var x = 5;

function add(a) {
  var y = 10;
  console.log(y);
  return a + x;
}
console.log(add(8)); // 13

x = 20; // 修改全局作用域变量的值

console.log(add(8)); // 28

console.log(y); // 局部作用域的变量无法在外面使用

箭头函数

介绍

  • 箭头函数为匿名函数
  • 当只有一个参数时,可省略 (),有零个或多个参数是不可省略
  • 当箭头函数有返回值且只有一行代码,可省略 {} 和 return

注意点

  • 箭头函数没有 Arguments
  • 箭头函数没有 this 指向
  • 不能用 new 关键字实例化对象
js
let greeting = () => {
  console.log('hello');
};

greeting();

this 指向

基本概念

  • 普通函数:this 指向调用所在函数的对象
  • 箭头函数:没有自己的 this 指向,this 指向包裹其作用域的对象

注意点

  • 在构造函数的方法中使用 this,this 指向这个构造函数
  • 当对象实例化时,this 指向实例化后的对象
  • 一般情况下,箭头函数不作为对象的方法
js
let zhangsan = {
  name: '张三'
};

// 使用普通函数定义时,this 指向的是zhangsan
zhangsan.sayHi = function () {
  console.log(this.name + '说Hi');
};

// 使用箭头函数定义时,this 指向Window对象(浏览器中)
zhangsan.sayHello = () => {
  console.log(this.name + '说Hello');
};

zhangsan.sayHi(); // 张三说Hi
zhangsan.sayHello(); // undefined说Hello

闭包

概念

  • 闭包是函数内部再定义函数
  • 闭包让开发者可以从内部函数访问外部函数的作用域。

优点

  • 私有化数据
  • 避免污染全局作用域

缺点

  • 变量不会被回收,可能会导致内存泄漏

返回值返回(高阶函数)

js
function create() {
  let a = 100;
  return function () {
    console.log(a);
  };
}
let fn = create();
let a = 200;
fn(); // 100

参数传入(回调函数)

js
function print(fn) {
  let a = 200;
  fn();
}
let a = 100;
function fn() {
  console.log(a);
}
print(fn); // 100

柯里化

  • 将一个接受多个参数的函数转化为一系列接受一个参数的函数
  • 优势:可以将其中几个参数先固定下来,单独修改一个参数
js
function addThreeNums(a, b, c) {
  return a + b + c;
}

// 柯里化后
function addThreeNumsCurry(a) {
  return function (b) {
    return function (c) {
      return a + b + c;
    };
  };
}

console.log(addThreeNums(1, 2, 3)); // 6
console.log(addThreeNumsCurry(1)(2)(3)); // 6

// 优势
let fixedTwo = addThreeNumsCurry(1)(2);
console.log(fixedTwo(3)); // 6

回调函数

js
// 回调函数就是一个被作为参数传递的函数
function request(cb) {
  console.log('请求开始');
  cb('success');
  console.log('请求结束');
}

// 回调函数(可含参)
function callback(result) {
  console.log('执行回调');
  console.log(result);
}

request(callback);

// 用箭头函数简写(不可复用)
request((result) => {
  console.log('执行回调');
  console.log(result);
});
关注微信公众号搬瓦工 - 美国 CN2 优化线路
你认为这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0

预览:

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3