JavaScript 核心概念解析:闭包、原型链与匿名函数执行模式

作者:纸飞机时间:2026-10-29 15:35:38浏览:371

本文深入解析 JavaScript 三大核心概念:闭包、原型与匿名函数。通过具体代码示例,阐述闭包对变量作用域的保持机制及内存影响,解析原型链在面向对象设计中的实现与调用方式,并总结立即执行匿名函数的三种常见写法。内容涵盖 this 关键字在不同上下文中的指向变化,帮助开发者理解 JS 底层运行机制。

本文通过具体代码示例,详细介绍 JavaScript 中的闭包、原型以及匿名函数相关机制,详细内容见下文。

JavaScript 闭包机制与注意事项

一、关于闭包

理解闭包所需的基础知识

1. 变量的作用域

示例 1:


var n =99; //建立函数外的全局变量
function readA(){
  alert(n); //读取全局变量
}

readA(); // 执行此函数

示例 2:


function readB(){
  var c = 9;
  function readC(){
    console.log(c); //ok c可见
  }
  return readC;
}
alert(c); //error c is not defined.

注意:在函数内部声明变量 c 时,必须加上 var 关键字,否则 c 将变为全局变量。

因此,函数内部可以访问全局变量,但函数内的局部变量对外部不可见。JavaScript 的作用域是链式的,父对象中的变量对子对象可见,但子对象的变量对父对象不可见。当我们需要获取函数内部的变量时,

便有了示例 3:


function readB(){
  var c = 9;
  function readC(){
    console.log(c);
  }
  return readC();
}
readB();

闭包的概念正是基于此原理衍生出的变式。


function readB(){
  var c = 9;
  function readC(){
    console.log(c);
  }
  return readC;
}
var res = readB();
res();

注意事项:

1. 谨慎使用闭包,需注意内存占用,因为它会保存父函数的状态。 2. 不要随意修改父函数内部变量的值。

深入理解闭包

注意:this 关键字指向包含它的函数被执行时所属的对象。

示例 1:


var name = "The Window";

var object = {
  name : "My Object",

  getNameFunc : function(){  //此时this (这个执行函数)是属于object对象的,是object对象下的一个属性的值
    return function(){   //此时this (这个执行函数)是一个匿名函数,从根对象window生成,是属于window
      return this.name;
    };
  }
};
console.log(object.getNameFunc()()); //the window 

示例 2:


var name = "The Window";

var object = {
  name : "My Object",

  getNameFunc : function(){
    var that = this;
    return function(){
      return that.name;
    };

  }
};
console.log(object.getNameFunc()());  //My Object

匿名函数的定义与执行模式

二、匿名函数

直接定义一个匿名函数并立即调用,这种形式在 jQuery 插件定义中非常常见。

1. 通过函数字面量方式:先声明一个匿名函数,然后执行它。


( function(){
  console.log('excute self');
}) ();

2. 通过优先表达式方式:由于 JavaScript 执行表达式是从圆括号内部到外部,因此可以使用圆括号强制执行已声明的函数。


(
  function () {
    alert(2);
  }
  ()
);

3. void 操作符:使用 void 操作符去执行一个没有被圆括号包围的单独操作数。


void function(){ console.log('void') } ();

原型链与面向对象设计

三、关于 prototype

原型 prototype

理解 JavaScript 中的 prototype 首先需要明白 JS 的面向对象设计。


function People(name){
  this.name = name;

  console.log(this); //Window 或者 object { name: 'xxx' }
  this.introduce = function(){  //实例对象方法
    console.log(this.name);
  }
}
new People('leon').introduce();
//这里有一个非常有趣的现象,结合前面的来看的话,
//首先function people里的this指向的默认是Window对象
//当 调用 People();时 this 输出为 Window对象
//但一旦调用new People('xx')时, this 输出为 {name:'xx'}
//其实也很好理解,一旦new ,便新建了一个对象

实例对象方法只能通过 new People('leon').introduce(); 这种形式调用,因为使用前必须初始化。

类的静态方法


var People = {}; //等于一个对象 {} 或者 function 数组都可以 此时People需要是引用类型
People.sayhi = function(to_who){
  console.log('hi '+ to_who);
}
People.sayhi('lee'); //调用时这样调用

原型方法


var People = function(){};       // People 必须为一个 function(){} 即为一个类,不能是对象或值类型或其他引用类型
People.prototype.meet = function(meet_who) {
  console.log('I am '+this.name + ',going to meet ' + meet_who);
};
new People('lee').meet('xx');

原型方法只能由该类的对象调用。

A.prototype = new B();

原型看起来很像继承,但其实不是,它更像 clone(克隆)更准确。

如果父类和子类出现重名属性,采取就近原则;如果找不到,则一级一级向上查找。如果要指定调用上级的属性,使用 call 方法。


extendClass.prototype = new baseClass();
var instance = new extendClass();
var baseinstance = new baseClass();
baseinstance.showMsg.call(instance);
obj1.func.call(obj);

以上内容是小编给大家分享的学习 javascript 的闭包、原型和匿名函数之旅,希望对大家有用。

作者最新文章

相关标签: