JS——笔试点滴记录1——闭包与this及方法

本文深入探讨了JavaScript中闭包的实现方式与this的作用域,通过具体实例分析了闭包如何帮助保留变量状态,并详细解释了this在不同上下文中的指向问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

笔试点滴类记录一些笔试遇到的题目,不一定有难度,但一定有所收获与启发。


一、关于闭包与this的理解


1、题目:

编写一个函数mul,使下面成立:

alert(mul(3)(4)(5));//提示60
alert(mul(2)(4)(5));//提示40
分析:

结果为3个数的累积,且是用三个函数分次输入这3个数。要使后面的函数能使用前面的函数的参数,可采用典型的闭包实现。

当时的具体实现:(测试正确)

function mul(numb1){
	this.n1=numb1;
	return function(numb2){
		this.n1=n1;
		this.n2=numb2;
		return function(numb3){
			return n1*n2*numb3;
		}
	}
}

反思:

this的理解:

最初理解:因为之前对闭包及this的含义理解不够透彻,所以每个函数中我都存储了该函数的返回函数将用到的值,如mul中以n1存储了numb1,第一个匿名函数中使用n1与n2存储了第一个mul函数的n1与新输入的numb2,第二个匿名函数中因为没有再返回引用参数的函数,所以直接通过闭包使用参数返回结果。

修正理解:最初理解存在错误,根本在于对this的误解,认为mul函数中的this指mul对象自身,而return语句中的this指返回的函数体构建的对象,如此看来mul函数体中this有三个身份(mul函数对象,第一个匿名函数对象,第二个匿名函数对象),而实际上mul中所有的this,都只指mul函数对象。验证如下:

function mul(numb1){
	this.n1=numb1;//标记1
	return funtion(numb2){
		alert(this.n1);//调用mul函数后,此处将提示与numb1相同的值,说明此处this与标记1出this指同一个对象,mul函数对象。
	}
}
闭包的理解:

当前某个函数正在使用的变量,都不会被释放,从而可实现保护变量的目标和使用先输入的参数(即此题中)。前提是正在使用该变量的函数,须属于该变量所属函数。实例讲解:

<script>
var n=10;//全局变量
function test(numb){
	var n=numb;
	this.method=function(){alert(n);}//此处实现了闭包,提示的是test函数中的n,因为method函数与numb变量同属于test函数。
}
function method(){alert(n);}//显然提示的是全局变量的n
<script>

当初设计的改进:(测试正确)

function mul(numb1){			//因为返回的函数中使用了numb1,所以形成了闭包,numb1不会被释放,即使作为形参
	return function(numb2){		//同理
		return function(numb3){
			return numb1*numb2*numb3;
		}
	}
}

感悟:如果非要使用变量存储形参,最好使用私有变量,即通过var声明,而非使用this,这也是闭包达到保护变量的目的。



二、this与对象

此处所讨论对象只指函数对象与JSON 对象。


1、this与函数对象

this用在函数体中,声明或使用公有属性或方法。

function test(){
	var privateV=10;
	this.publicV=20;
	var privateMethod=fucntion(){	//注解1
		alert(privateV);	//私有方法可使用私有属性变量
		alert(typeof publicV+typeof publicV);//显示undefined,即私有方法不能引用公有属性(包括公有变量与公有方法)
	};
	this.publicMethod1=function(){
		alert(privateV);	//公有方法使用私有属性变量,不能通过this调用。提示10
		alert(this.publicV);	//公有方法使用公有属性变量,只能通过this调用。提示20
	};
	this.publicMethod2=function(){
		this.publicMethod1();	//公有方法使用公有方法,只能通过this调用。
		privateMethod();	//公有方法使用私有方法,不能通过shis调用。
	}
}
小结:

将函数中this声明的变量与方法理解为属性变量与属性方法,引用它们只能通过this。私有方法不能引用属性变量与属性方法,属性方法能引用属性变量、私有变量、属性方法、私有方法。(但有一个例外,即直接return的方法,该方法体中访问上层函数通过this声明的属性或方法可不通过this,直接使用,这也正是题目1的最初设计结果正确的重要原因)

注解1:

以var 声明方式声明的私有函数,其内部使用的this并非指该私有函数所属的对象,而是指全局对象(window)。如:

var n=10;	
function test(){
	this.n=20;
	var method1=function(){ alert(this.n);}	//1处
	this.method2=function(){ method1();}
}
var t=new test();
t.method2();//将提示10,而非20,var声明的函数的this并不指该函数所属的对象(此例中即t)。

另外,对于全局属性,var与this声明方式没有区别,都可直接使用(没有被局部变量覆盖时)或通过this调用。所以此例中this.n调用了全局变量n。

此外,还应注意,下面两种方法也都都形成了闭包:

var n=10;
//第一种
function test(){
	var n=20;
	return function(){alert(n);}
}
//第二种,与上一种本质一样
function test2(){
	var n=30;
	var method=function(){alert(n);}
	return method;
}
var t1=test();
t1();//提示20
var t2=test2();
t2();//提示30


2、this与JSON 对象

比较:

var x=10;
var test={
	x:20,
	method:function(){alert(x)}
};
test.method();//提示10
var test2={
	x:30,
	method:function(){alert(this.x)}
}
test2.method();//提示30

小结:

JSON 对象的方法使用自身的属性变量必须通过this。


JSON 对象方法与函数对象方法的另一个区别:能否复制

var x=10;
var test2={
	x:20,
	method:fucntion(){alert(this.x)}
};
test2.method();//提示20
var t=test2.method;
t();//提示10
//所以JSON 对象调用自身属性变量并未形成闭包
//与之对比的函数对象的属性方法
function test3(){
	var x=30;
	this.method=function(){x++;alert(x);}
}
var t3=new test3();
t3.method();	//提示31
var t=t3.method;
t();		//提示32
t3.method();	//提示33。说明一个函数对象的某个方法至始至终只有自身一个,没有复制品。

小结:

JSON 对象的属性方法与属性变量未形成闭包,实际上也不需要,因为JSON 对象就是为了能直接使用属性方法与属性变量的。JSON 对象的方法可“复制”给其它变量而不影响该JSON 对象的属性变量,但形成闭包的函数对象的方法不能如此(即它是将自身给了某个变量,而非一个复制品)。











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值