Skip to content

函数

1444字约5分钟

2024-07-07

函数的作用

类似于代码库,函数是提前定义的容器,方便重复调用

函数使用

//定义函数
function functionName(){
    //Your code
};
//调用函数
functionName();

作用域

全局作用域

全局作用域在程序中就是一块公共的区域,在全局作用域中定义的变量可以在任何地方使用 (全局变量)

提示

  1. window 对象动态添加的属性默认也是全局的,不推荐!

  2. 函数中未使用任何关键字声明的变量为全局变量,不推荐!!!

  3. 尽可能少的声明全局变量,防止全局变量被污染

局部作用域

局部作用域在程序中就是私有的区域,在局部作用域中定义的变量,只能在当前自己的作用域中使用(局部变量)

函数作用域

在函数内部声明的变量只能在函数内部被访问,外部无法直接访问。

<script>
  // 声明 counter 函数
  function counter(x, y) {
    // 函数内部声明的变量
    const s = x + y
    console.log(s) // 18
  }
  // 设用 counter 函数
  counter(10, 8)
  // 访问变量 s
  console.log(s)// 报错
</script>
  1. 函数内部声明的变量,在函数外部无法被访问
  2. 函数的参数也是函数内部的局部变量
  3. 不同函数内部声明的变量无法互相访问
  4. 函数执行完毕后,函数内部的变量实际被清空了

块作用域

在 JavaScript 中使用 {} 包裹的代码称为代码块,代码块内部声明的变量外部将【有可能】无法被访问。

{
  // age 只能在该代码块中被访问
  let age = 18;
  console.log(age); // 正常
}

// 超出了 age 的作用域
console.log(age) // 报错

let flag = true;
if(flag) {
  // str 只能在该代码块中被访问
  let str = 'hello world!'
  console.log(str); // 正常
}

// 超出了 age 的作用域
console.log(str); // 报错

for(let t = 1; t <= 6; t++) {
  // t 只能在该代码块中被访问
  console.log(t); // 正常
}

// 超出了 t 的作用域
console.log(t); // 报错

JavaScript 中除了变量外还有常量,常量与变量本质的区别是【常量必须要有值且不允许被重新赋值】,常量值为对象时其属性和方法允许重新赋值。

// 必须要有值
const version = '1.0.0';

// 不能重新赋值
// version = '1.0.1';

// 常量值为对象类型
const user = {
  name: '小明',
  age: 18
}

// 不能重新赋值
user = {};

// 属性和方法允许被修改
user.name = '小小明';
user.gender = '';
  1. let 声明的变量会产生块作用域,var 不会产生块作用域
  2. const 声明的常量也会产生块作用域
  3. 不同代码块之间的变量无法互相访问
  4. 推荐使用 letconst

相关信息

开发中 letconst 经常不加区分的使用,如果担心某个值会不小被修改时,则只能使用 const 声明成常量。

作用域链

// 全局作用域
let a = 1
let b = 2
// 局部作用域
function f() {
  let c
  // 局部作用域
  function g() {
    let d = 'yo'
  }
}

函数内部允许创建新的函数,f 函数内部创建的新函数 g,会产生新的函数作用域,由此可知作用域产生了嵌套的关系。

作用域链本质上是底层的变量查找机制,在函数被执行时,会优先查找当前函数作用域中查找变量,如果当前作用域查找不到则会依次逐级查找父级作用域直到全局作用域,如下代码所示:

// 全局作用域
let a = 1
let b = 2

// 局部作用域
function f() {
  let c
  // let a = 10;
  console.log(a) // 1 或 10
  console.log(d) // 报错

  // 局部作用域
  function g() {
    let d = 'yo'
    // let b = 20;
    console.log(b) // 2 或 20
  }

  // 调用 g 函数
  g()
}

console.log(c) // 报错
console.log(d) // 报错

f();
  1. 嵌套关系的作用域串联起来形成了作用域链
  2. 相同作用域链中按着从小到大的规则查找变量
  3. 子作用域能够访问父作用域,父级作用域无法访问子级作用域

函数参数

形参、实参、返回值

形参:函数名()中的变量 (a, b, c 就是函数的形参)

实参: 调用函数的时候()中的字面量

可以设置返回值也可以不用设置返回值

希望在函数外部使用函数内部变量的值,则必须加返回值

变量直接在函数声明时,不用加let

两个相同的函数新的会覆盖旧的

返回值

重要

如果希望在函数外部使用函数内部变量的值,则必须加返回值!!!

警告

一个函数中只能写一个 return

  1. 步骤 1

    在函数内部将需要返回的值前面加return

  2. 步骤 2

    在函数外部定义一个变量接收函数内部的返回值: let 变量 = 函数();

function fn() {
    let a = 123;
    // 将变量a设置为返回值
    return a;
}
// 接收函数中的返回值
let b = fn();
console.log(b);

Javascript内置函数

在讲输入输出语句、拼接字符串时,我们已经提前接触到一些Js内置函数

  • push(1, 2, 3);
  • unshift();
  • pop();
  • alert();
  • prompt();
  • confirm();
  • ……

匿名函数

字面意思,没有名字的函数

变量调用匿名函数
let fn = function(){
    console.log(test);
}
fn();