函数与作用域

简介: 编程中的函数与作用域概念。函数是可重用的代码块,能提高代码的可读性、可维护性和复用性。基础用法包括定义、调用和返回值。高级用法涉及函数嵌套、匿名函数(lambda函数)和装饰器。装饰器能在不修改原函数代码的情况下添加功能。作用域决定了变量的可见范围,从内到外是局部、嵌套、全局和内置作用域。闭包是能访问外部函数变量的内部函数,即使外部函数执行完毕,闭包仍能保留其状态。闭包常用于实现特殊功能,如记忆化和延迟执行。立即执行函数表达式(IIFE)是JavaScript中的模式,用于创建私有作用域和防止变量污染全局。IIFE常用于封装变量、避免命名冲突以及实现模块化和函数作为参数传递。

函数与作用域

函数基础与高级用法

函数基础是编程中的一个重要概念,它是一段可重用的代码块,用于执行特定的任务或计算。函数可以接受输入参数,并返回输出结果。函数可以提高代码的可读性、可维护性和复用性。

函数的基本用法包括定义函数、调用函数和函数返回值。在Python中,函数可以使用def关键字来定义。函数的定义由函数名、参数列表和函数体组成。参数列表是函数的输入,函数体是函数的具体实现。函数的返回值可以使用return关键字指定。

下面是一个简单的函数示例:

def greet(name):
    return "Hello, " + name
result = greet("Alice")
print(result)

image.gif

这个函数接受一个参数name,并返回一个字符串。在调用函数时,需要传入一个参数,函数会根据参数生成相应的返回值。

函数的高级用法包括函数的嵌套、匿名函数和装饰器。

函数的嵌套是指在一个函数中定义另一个函数。内部函数可以访问外部函数的变量和参数。嵌套函数可以提供更好的代码封装和组织。

匿名函数是没有函数名的函数,也称为lambda函数。它通常用于定义简单的函数,特别是作为函数参数传递。

装饰器是一种特殊的函数,用于修改其他函数的行为。装饰器可以在不修改原始函数代码的情况下添加额外的功能,比如日志记录、性能分析和权限验证。

下面是一个使用嵌套函数、匿名函数和装饰器的示例:

def outer_func():
    x = 1
    
    def inner_func():
        y = 2
        return x + y
    
    return inner_func
func = outer_func()
result = func()
print(result)
square = lambda x: x * x
print(square(3))
def decorator_func(original_func):
    def wrapper_func():
        print("Before")
        original_func()
        print("After")
    
    return wrapper_func
@decorator_func
def hello():
    print("Hello")
hello()

image.gif

这个示例中,outer_func是一个嵌套函数,它定义了一个内部函数inner_func。嵌套函数可以访问外部函数的变量x,并返回x + y的结果。

square是一个匿名函数,它接受一个参数x,并返回x * x的结果。

decorator_func是一个装饰器函数,它接受一个原始函数original_func作为参数,并返回一个包装函数wrapper_func。包装函数在原始函数执行之前打印"Before",在原始函数执行之后打印"After"。

使用装饰器可以直接在函数定义之前添加@decorator_func来应用装饰器。在示例中,hello函数被decorator_func装饰,所以在调用hello函数时,会先执行包装函数的逻辑,再执行原始函数的逻辑。

作用域与闭包深入理解

作用域是指在程序中某个变量可以被访问的范围。Python中有四个作用域,从内到外分别是局部作用域、嵌套作用域、全局作用域和内置作用域。

局部作用域是在函数内部定义的变量的作用域,它只在函数内部可见。嵌套作用域是在函数内部的嵌套函数中定义的变量的作用域,它在函数内部和嵌套函数内部可见。

全局作用域是在函数外部定义的变量的作用域,它在整个程序中都可见。内置作用域是Python内置函数和模块中定义的变量的作用域,它在整个程序中都可见。

在Python中,变量的作用域由LEGB原则决定。LEGB分别代表局部作用域、嵌套作用域、全局作用域和内置作用域。当访问一个变量时,解释器首先在局部作用域查找,然后在嵌套作用域中查找,接着在全局作用域中查找,最后在内置作用域中查找。

闭包是指一个函数内部定义的函数,它可以访问外部函数的变量,并且这些变量在外部函数执行结束后仍然可用。闭包可以用来实现一些特殊的功能,例如记住函数的状态和延迟执行。

下面是一个闭包的示例:

def outer_func(x):
    def inner_func(y):
        return x + y
    
    return inner_func
add_2 = outer_func(2)
result = add_2(3)
print(result)

image.gif

在这个示例中,outer_func是一个外部函数,它接受一个参数x,并返回一个内部函数inner_funcinner_func可以访问外部函数的变量x。在调用outer_func(2)时,返回的是一个闭包函数add_2,它可以将传入的参数与外部函数的变量相加并返回结果。

闭包的特点是在定义时捕获了外部函数的状态,所以即使外部函数执行结束,闭包函数仍然可以使用外部函数的变量。这种特性可以用来实现一些高级的功能,例如装饰器、函数工厂和延迟执行。

立即执行函数表达式(IIFE)的应用

立即执行函数表达式(Immediately Invoked Function Expression,IIFE)是JavaScript中一种常见的模式,它允许我们创建一个立即执行的函数,并且它的作用域被限制在函数内部。

IIFE的应用有以下几个方面:

  1. 封装变量:使用IIFE可以创建一个私有的作用域,从而防止变量泄露到全局作用域。这在处理模块化的JavaScript代码时非常有用。
(function() {
    // 私有作用域
    var privateVar = "IIFE";
    console.log(privateVar); // 输出 "IIFE"
})();
console.log(privateVar); // 报错,privateVar不在全局作用域内可见

image.gif

  1. 避免命名冲突:当多个脚本文件在同一个页面中加载时,使用IIFE可以避免全局命名冲突。
// 脚本1
(function() {
    var name = "Script 1";
    console.log(name); // 输出 "Script 1"
})();
// 脚本2
(function() {
    var name = "Script 2";
    console.log(name); // 输出 "Script 2"
})();

image.gif

  1. 模块化开发:IIFE可以用来实现模块化的JavaScript开发。通过将模块代码放在IIFE中,可以创建私有的作用域,并且通过返回的对象来访问模块内部的方法和变量。
var module = (function() {
    var privateVar = "Private Var";
    
    function privateFunc() {
        console.log(privateVar);
    }
    
    return {
        publicFunc: function() {
            privateFunc();
        }
    };
})();
module.publicFunc(); // 输出 "Private Var"

image.gif

  1. 函数作为参数:IIFE可以用来将函数作为参数传递给其他函数。
var result = (function() {
    var num1 = 3;
    var num2 = 4;
    
    return function() {
        return num1 + num2;
    };
})();
console.log(result()); // 输出 7

image.gif

总结来说,IIFE是一种非常强大且常用的模式,在JavaScript开发中有许多应用场景,如封装变量,避免命名冲突,模块化开发和函数作为参数的传递等。它可以帮助我们更好地管理作用域和代码结构。

相关文章
|
5天前
|
编译器 C++
c++关于命名空间内变量和函数及全局变量的使用和作用域
c++关于命名空间内变量和函数及全局变量的使用和作用域
39 1
|
11月前
|
Linux 网络架构
暂时性死区以及函数作用域
暂时性死区以及函数作用域
115 0
|
设计模式 自然语言处理 JavaScript
一篇文章帮你真正理解javascsript作用域闭包
一篇文章帮你真正理解javascsript作用域闭包
62 0
|
自然语言处理 JavaScript 前端开发
作用域是什么
作用域是什么
85 0
|
JavaScript 前端开发
函数作用域和块作用域
函数作用域和块作用域
83 0
|
自然语言处理 前端开发 JavaScript
作用域闭包
作用域闭包
59 0
|
存储 JavaScript 前端开发
深入理解作用域和闭包(上)
深入理解作用域和闭包(上)
深入理解作用域和闭包(上)
|
存储 缓存 JavaScript
深入理解作用域和闭包(下)
深入理解作用域和闭包(下)
深入理解作用域和闭包(下)
|
自然语言处理 JavaScript 前端开发
这次写的不只是函数作用域,而是。。。。
这次写的不只是函数作用域,而是。。。。
84 0
这次写的不只是函数作用域,而是。。。。
7-5python函数-变量的作用域
局部变量是在函数内部定义的变量,只能在函数内部使用;
100 0