JavaScript 面向对象编程:深入理解函数与方法

作者:青柠时间:2026-10-23 23:54:50浏览:290

本文深入解析 JavaScript 中函数的核心概念,涵盖有名函数、匿名函数及立即执行函数的定义与用法。重点讲解如何利用 arguments 对象模拟方法重载,以及通过匿名函数实现事件绑定、定时器和回调处理,帮助开发者掌握 JS 函数式编程技巧。

JavaScript 函数与封装基础

优秀的代码旨在服务于人类而非计算机。面对复杂逻辑时,应致力于简化与组件化,将独立的小功能封装为可复用的模块,通过灵活组合这些模块来构建多样化的复杂功能。函数(function)正是实现这种功能封装的关键工具。所谓封装,即隐藏具体实现细节,仅对外暴露调用接口,无论是方法还是类,均体现了这一核心思想。

在 JavaScript 中,函数既可用于定义方法,也可用于模拟类的创建(涉及闭包概念)。本节首先从基础的方法定义开始探讨。

JavaScript 中的函数主要包含三种形式:命名函数、匿名函数,以及基于匿名函数衍生的立即执行函数。

命名函数与方法重载模拟

普通函数是指通过 function 关键字直接声明的命名函数。

    function Hello() {
      alert("hello , everybody!");
    };
 
    Hello();
 
    function SayHelloTo(somebody) {
      alert("hello , " + somebody + "!");
    };
 
    SayHelloTo("张三");

上述代码分别定义了 Hello 和 SayHelloTo 两个方法。Hello 函数无需参数,直接调用 Hello() 即可执行;SayHelloTo 接收一个参数,用于指定问候对象,调用时需传入具体值,如 SayHelloTo("张三")。此类语法与 Java、C# 等语言相似,但在方法重载机制上存在显著差异。JavaScript 原生不支持传统意义上的方法重载,同一函数名仅对应一个实现。若重复定义同名函数,先前的定义将被后者覆盖。

    function Hello() {
      alert("hello , everybody!");
    };
 
    Hello();
 
    function Hello(somebody) {
      alert("hello , " + somebody + "!");
    };
 
    Hello("张三");

 

               image image

当第二个 Hello 函数定义后,第一个定义被覆盖。此时调用 Hello() 且未传参,将弹出 undefined;若调用 Hello("张三") 则正常执行。尽管 JS 不支持重载,但可通过类似 C# params 关键字的方式手动判断参数数量或类型来模拟重载效果。在 JavaScript 中,无需额外关键字即可传递任意数量的参数,这得益于函数内部的 arguments 属性。该属性可视为一个数组,按顺序保存所有传入参数,因此定义函数时甚至可以不声明形参名。

    function ShowArguments() {
      var args = "";
      for (var i = 0; i < arguments.length; i++) {
        args += arguments[i] + ",";
      };
      alert(args.substr(0, args.length - 1));
    };
 
    ShowArguments(1, 2, 3, 4, 5, 6, 7);

image 尝试利用 arguments 对象来模拟方法重载的效果。

    function Hello() {
      if (arguments.length == 0) {
        alert("hello , everybody!");
      }
      else {
        alert("hello , " + arguments[0] + "!");
      };
    };
 
    Hello();
    Hello("张三");

基于参数数量差异实现的重载逻辑。

    function Increase(arg) {
      if (typeof arg == "undefined") {
        alert("请输入参数");
      }
      if (typeof arg == "string") {
        alert(String.fromCharCode(arg.charCodeAt(0) + 1));
      }
      if (typeof arg == "number") {
        alert(arg + 1);
      }
    };
    Increase();
 
    Increase("a");
    Increase(1);

基于参数类型差异实现的重载逻辑。

匿名函数的应用与场景

除了命名函数,JavaScript 还支持匿名函数,即没有名称的函数。无论是否有名,它们都是完整的函数对象。匿名函数同样使用 function 声明,但无需指定名称,其参数处理等特性与命名函数无异。

    function() {
      ……
    };

匿名函数通常用于临时性的函数需求,无需变量引用(命名函数通常由变量引用)。例如,将函数作为值对象传入其他方法,或以编程方式为对象添加事件处理程序时,匿名函数能很好地胜任。当然,若将匿名函数赋值给变量,其作用与命名函数相同。

    function Each(array, fun) {
      for (var i = 0; i < array.length; i++) {
        fun(array[i]);
      };
    };
    var nums = [1, 2, 3, 4, 5, 6, 7];
    Each(nums, function(arg) {
      alert(arg);
    });

上述代码执行后,依次输出数组中的各个元素。

    //在窗体加载时,在标题上显示当前时间
    window.onload = function() {
      document.title = new Date().toString();
    };
 
    //也可以将匿名方法传入定时器中
    setInterval(function() {
      document.title = new Date().toString();
    }, 1000);

演示如何使用匿名函数绑定页面事件及执行定时操作。

    var Hello = function() {
      alert("hello , everybody!");
    };

立即执行函数(IIFE)

若将匿名函数赋值给变量,其表现与普通命名函数无异。然而,无论是变量引用还是普通命名函数,都会在内存中持续占用资源。若只需执行一次且无需复用,直接执行匿名函数是更优选择。将匿名函数包裹在括号中并立即调用,即构成了立即执行函数(IIFE)。

    (function() {
      alert("hello , everybody!");
    })();
 
    (function(somebody) {
      alert("hello , " + somebody + "!");
    })("张三");

立即执行函数在事件绑定、回调函数设置等场景中效果显著,能有效解决对象引用保持等问题。

    var student = {
      Name: "张三",
      Age: 20,
      Introduce: function() {
        alert("我叫" + this.Name + ",今年" + this.Age + "岁了!");
      } };
    window.onload = (function(obj) { return function() { obj.Introduce(); }; })(student);

凭借 JavaScript 函数的这些特性及其对象模型,我们可以编写出具有函数式编程风格(functional)的代码。在 JavaScript 中,函数确实扮演着核心角色。

    function Sum(fun, x) {
      if (x <= 0)
        return 0;
      return fun(x) + Sum(fun, x - 1);
    };
  
    alert(Sum(function(i) { return i * i; }, 100));

那么,接下来展示的代码结构代表什么呢?它是方法还是类?

    function Point() {
      
    };

此处暂作介绍,后续章节将继续探讨类的实现。

作者最新文章