04-JavaScript函数

函数(重点)

1.为什么使用函数?

函数来解决代码重用的问题

2.函数的意义

函数其实就是封装,把可以重复使用的代码放到函数中,如果需要多次使用同一段代码,就可以把封装成一个函数。这样的话,在你需要再次写这些代码的时候,你只需要调用一次函数就行了。

3.定义函数的方式

3.1 使用字面量的形式定义函数

ECMAScript中的函数使用function关键字来声明,后面跟一组参数及函数体。函数的基本语法如下:

3.1.1 定义函数

复制代码
 function sum(num1, num2) {
    var num3 = num1 + num2;
     console.log(num3);
 }

3.1.2 函数的调用

这个函数的作用是把两个值加起来返回一个结果。函数必须通过调用才会执行,调用这个函数的代码如下:

复制代码
sum(5, 10); //15

3.1.3 函数的参数

  • 函数的参数分为实际参数(实参)和形式参数(形参);

  • 函数可以传递1个、3个甚至不传递参数,根据实际代码的需求传递。

3.2 使用函数表达式声明函数(匿名函数)

3.3 使用Function构造函数声明函数

3.4 自执行函数

先前咱们写的函数只有在调动的时候才会执行,如果像下面这样写的话,代码执行到这一行的时候,函数会自己执行(或者说自己调用自己)。

复制代码
(function(a){
    console.log(a);
})("abc")

4. 函数的返回值return

复制代码
function sum(num1, num2) {
    var num3 = num1 + num2;
    return num3;
}
//接受函数执行的返回值
var result = sum(5, 10); //15

注意点:

  • 函数在执行完return语句之后停止并立即退出。因此,位于return语句后面的任何代码永远都不会执行。

  • 一个函数中可以有多个return语句。

  • return语句也可以不带任何返回值。

5. arguments对象

arguments 是一个对应于传递给函数的参数的类数组对象。

可以使用arguments对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,第一个参数在索引 0 处。例如,如果一个函数传递了三个参数,你可以以如下方式引用他们:

复制代码
function func1(a, b, c) {
  console.log(arguments[0]);
  console.log(arguments[1]);
  console.log(arguments[2]);
}
​
func1(1, 2, 3);

6. 函数是一种数据类型

  • function数据类型

    function fn() {}
    console.log(typeof fn);//返回值是function

  • 函数作为参数

因为函数也是一种类型,可以把函数作为一个函数的参数,在一个函数中调用

复制代码
function fun() {
    console.log('函数哦');
 };
​
// 函数作为superfun的参数
function superfun(theFun) {
    theFun();
    console.log('执行了');
};
​
superfun(fun);

7. 作用域

作用域:指一个变量的作用范围。

目前的学习中,在Javascript将作用域分为 全局作用域函数作用域(局部作用域)。

7.1 全局作用域

代码在程序的任何地方都能被访问,window 对象的内置属性都拥有全局作用域。

7.2 函数作用域(局部作用域)

在固定的代码片段才能被访问

7.3 全局变量和局部变量

变量的作用域范围可分为全局变量和局部变量。

  • 全局变量:

在最外层声明的变量叫全局变量。

在函数体内部,没有使用var关键字声明的变量也是全局变量。(不推荐)

  • 局部变量:

在函数体内部,使用var关键字声明的变量叫作局部变量。

7.4 作用域规则

  • 函数允许访问函数外的数据。

  • 整个代码结构中只有函数可以限定作用域。

  • 作用域规则首先使用提升规则分析。

  • 如果当前作用规则中有名字了, 就不考虑外面的名字。

    注意点:

    局部变量退出作用域之后会销毁,全局变量关闭网页或浏览器才会销毁。

    //函数才有局部作用域
    var num = 123;
    function foo() {
    console.log( num );
    }
    foo();
    if ( false ) {
    var num = 123;
    }
    console.log( num ); // undefiend

7.5 作用域链(重点)

  • 只有函数可以制造作用域结构, 那么只要是代码,就至少有一个作用域, 即全局作用域。凡是代码中有函数,那么这个函数就构成另一个作用域。如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。

  • 将这样的所有的作用域列出来,可以有一个结构:在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链

  • 作用域链:采取就近原则的方式来查找变量最终的值。

    // 案例1:
    function f1() {
    function f2() {
    }
    }

    var num = 456;
    function f3() {
    function f4() {
    }
    }
    // 案例2
    function f1() {
    var num = 123;
    function f2() {
    console.log( num );
    }
    f2();
    }
    var num = 456;
    f1();

*我可以

什么是作用域和作用域链,请解释一下?

作用域(scope)

在 Javascript 中,作用域分为 全局作用域局部作用域

全局作用域:代码在程序的任何地方都能被访问,window 对象的内置属性都拥有全局作用域。

局部作用域:在固定的代码片段才能被访问。

作用域链(scope chain)

在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。

8. 预解析

JavaScript代码的执行是由浏览器中的JavaScript解析器来执行的。

JavaScript解析器执行JavaScript代码的时候,分为两个过程:预解析过程和代码执行过程。

预解析过程:

  1. 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。

  2. 把函数的声明提升到当前作用域的最前面,函数声明代表函数整体,所以函数提升后,函数名代表整个函数。

  3. 先提升var,再提升function。

  4. 预解析会把变量和函数的声明在代码执行之前执行完成。

8.1 变量预解析

预解析也叫做变量、函数提升。 变量提升(变量预解析): 变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升。

8.2 函数预解析

函数提升: 函数的声明会被提升到当前作用域的最上面,函数声明代表函数整体,所以函数提升后,函数名代表整个函数。

复制代码
fun();
​
function fun() {
    console.log('函数啊');
};

特殊情况--函数表达式声明函数问题

复制代码
fn();
var  fn = function() {
    console.log('想不到吧');
}
//结果:报错提示 "fn is not a function"
​
//解释:该段代码执行之前,会做变量声明提升,fn在提升之后的值是undefined;而fn调用是在fn被赋值为函数体之前,此时fn的值是undefined,所以无法正确调用

9.综合练习

复制代码
1.

var x;
console.log(x)
x=3;
2.//undefined

var a = 1;
function test(){
    console.log(a);
    var a = 1;
}
test();
3.//3 2 2

var b = 1;
function fun1() {
    b = 2;
    function fun2() {
        var b = 3;
        console.log(b);
    }
    fun2();
    console.log(b);
}
fun1();
console.log(b);
​
4.//2 1

var b = 1;
function fun1(b) {
    b = 2;//对形参进行的操作?
    console.log(b);
}
fun1('yy');
console.log(b);
​
5.//3 3

var b = 2;
function test2() {
    window.b = 3;
    console.log(b);
}
test2();
console.log(b);
6.//undefined 3 3

c = 5;
function test3() {
    window.c = 3;
    console.log(c);
    var c;
    console.log(window.c);
}
test3();
console.log(c);
相关推荐
腾讯TNTWeb前端团队6 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰9 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪10 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy10 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom11 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom11 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom11 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom11 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试