闭包与this学习
最近刚好又遇到闭包知识,之前一直没弄懂,不过时间一久,慢慢就明白了。
正如很多大牛博客上说的,闭包就是能够读取其他函数内部变量的函数。
代码例子来自:阮一峰的网络日志---学习javascript闭包 也是我的参考资料
function f1(){ var n=999; nAdd=function(){n+=1} function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999 nAdd(); result(); // 1000
“
由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
”
博客最后抛出一个有关this的问题:
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ var that = this; return function(){ return that.name; }; } }; alert(object.getNameFunc()());
这里用了that来存储this。从而引起了我对this的关注。
于是乎google之下,见到又一大神博客:深入javascript之this关键字
才明白this的指向,是根据调用其所在函数调用时的上下文所决定的,即普通function的主人是window,此时this会指向window,而function如果是在某个对象中时,this则指向此对象。
博客中用的例子是以onclick事件函数作为例子,这里我加了点修改。同时也解答了正确指向this的用法;
事件处理函数:
dom.onclick = funtionMethod;
dom.onclick = function(){
//use this;
};
<input onclick="alert(this);" />
非事件函数:
functionN.call(obj, arg1, arg2);
functionN.apply(obj, args);
<html> <head> <title> function execute methods </title> </head> <body> <input type='button' value="button1" id='btn1' /> <input type='button' value="button2" id='btn2' /> <input type='button' value="button2.5" id='btn25' /> <input type='button' value="button3" id='btn3' onclick='buttonClicked();'/> <input type='button' value="button4" id='btn4' onclick='alert(this.value);alert(this.onclick);'/> <script type='text/javascript'> function buttonClicked(){ alert(this.value); alert(this.onclick); } //函数A var button1 = document.getElementById("btn1"); var button2 = document.getElementById("btn2"); var button25 = document.getElementById("btn25"); button1.onclick = buttonClicked; //赋值函数A到对象,所以此时函数属于对象 button2.onclick = function(){buttonClicked();}; //虽然是定义函数,但函数内是直接调用函数A,所以函数A是window的 button25.onclick = function(){alert(this.value);alert(this.onclick);}; // 定义函数,函数是input对象的。
// button3 的使用方式跟button2很像(还不确定)
// button4 引号内容就如button2.5 </script> </body> </html>
到了这里,本来一切都明了了。但又看了一下第一篇博客里面相关链接。
function Container(param) { var sercert = 3; this.member = param; var that = this; // 注意这行 function dec() { return (sercert > 0) ? --secret : false; } this.service = function() { return (dec()) ? that.member : null; } }
差点给误导的感觉,可能我一下子先入为主了,以为这里的that是必要的。但其实这里that不需要用。因为service定义的函数是直接使用this,则this应当指向的是service的主人,即Container的实例。
我也写下例子:
<html> <head></head> <body onload='board();'> <script type="text/javascript"> function Container0(param) { var sercert = 3; this.member = param; function dec() { return (sercert > 0) ? --sercert : false; } this.service = function() { return (dec()) ? this.member : null; //这里是直接定义函数,因此不需要var that保存 } } function Container(param) { var sercert = 3; this.member = param; var that = this; // 注意这行 function dec() { return (sercert > 0) ? --sercert : false; } this.service = function() { return (dec()) ? that.member : null; } } var usage = function(){ return this.member; }; function Container2(param) { var sercert = 3; this.member = param; var that = this; // 注意这行 function dec() { return (sercert > 0) ? --sercert : false; } this.service = usage; //直接赋值法,usage会成为Container2的成员函数,this则指向本身 } function Container3(param) { var sercert = 3; this.member = param; function dec() { return (sercert > 0) ? --sercert : false; } this.service = function() { return function(){ //函数体中返回的函数,属于外部函数,this指向windows // return (dec()) ? this.member : null; //--> undefined return this; //window not container3 object } } } function board(){ var t = new Container(1); alert(t.service()); var t2 = new Container2(2); alert(t2.service()); var t0 = new Container0(3); alert(t0.service()); var t3 = new Container3(4); alert(t3.service()()); } </script> </body> </html>
一切都明朗了的感觉。
再重新回来看,发现表述太过浅,迟点记录一下作用域链以及this的特殊性