JavaScript 核心概念解析:闭包、原型链与匿名函数执行模式
本文深入解析 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 的闭包、原型和匿名函数之旅,希望对大家有用。
JS动态构建复杂嵌套JSON对象的方法
2026-11-05 15:41:52
JS负数取余为什么是负数?详解余数与模运算区别
2026-11-05 13:34:41
JS 解压出现乱码或报错怎么解决?
2026-11-05 12:32:38
JS 中 startsWith、indexOf 与正则判断字符串前缀的对比
2026-11-04 22:19:43
JS解析Excel后怎么将数据转换为JSON格式
2026-11-04 20:58:28
相关标签:
