匿名函数
在JavaScript这门脚本语言中,默认的定义函数格式如下:
function fn(a,b){ console.log(a+b); }
某些情况下定义函数时会省略掉函数名称如下:
function (a,b){ console.log(a+b); }
这样的函数就叫做匿名函数。
而众所周知,函数是通过函数名来调用的,当没有名字时该如何调用,用在什么地方呢?
调用方式
一:放进变量中
let myfn = function(a,b) { console.log(a+b); }; myfn(1,2);
这样一来,这个变量就相当于函数名,因此这个函数就等于是个普通函数了
二:直接执行
常用方式
- (匿名函数)()
- (匿名函数())
(function(a,b){ console.log(a+b); })(1,2) (function(a,b){ console.log(a+b); }(1,2))
三:利用事件调用
let btn = document.getElementById("btn"); btn.onclick = function() { console.log("clicked!"); }
四:作为对象的方法调用
let myobj = { name:"yumefx", hello:function(){ console.log("hello,"+this.name); } }; myobj.hello();
这种方法与第一种方法赋予变量类似。
五:作为另一个函数的参数
function myfn(fn){ fn(); } myfn(function(){ console.log("yes"); });
变量作用域
在ES6之前,当使用var声明变量时,只有全局作用域和函数作用域。
以函数声明为界,函数内部变量和外部变量是两个不同的作用域,内部声明的变量不可以在外部被访问,而内部可以调用和覆盖外部声明的所有变量,即使外层函数已经执行完毕(作用域嵌套)。
var tmp = new Date(); function f() { console.log(tmp); if (false){ var tmp = "hello"; } } f(); //undefined
这段代码中,if代码块的外部使用外层的tmp变量,内部使用内层的tmp变量。但是由于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。
所谓变量提升,就是将函数和变量的声明提升到当前作用域的最顶端,因此要想变量不是全局变量,那么就得用函数包起来。变量提升的结果就是声明的变量在声明前调用值为undefined而不会报错。
除此以外还有内存泄漏问题,例如用来计数的循环变量泄露为全局变量。
var s = "hello"; for (var i = 0; i < s.length; i++){ console.log(s[i]); } console.log(i);
在ES6之后,有了一个新的变量声明符号let,可以声明块级作用域,只有在当前代码块内有效,并且无法在声明前调用(let不存在变量提升)。
a //undefined { var a = 1; let b = 2; } a //1 b //ReferenceError: b is not defined.
另外,let不能在同一作用域内,重复声明同一个变量,例如不能在函数内部重新声明传入的参数。因此,匿名函数的闭包功能,其实就是在let出现前,将某些变量变成类似块级作用域的方式。
优点是可以防止内部变量污染外部变量,但要小心this指向、变量作用域、内存泄漏等问题。
this指向
var object = { name: "object", getName: function() { return function() { console.info(this.name) } } } object.getName()() //undefined
因为里面的闭包函数是在windows作用域下执行的,因此,this指向windows。
变量作用域
function outer() { var result = []; for (var i = 0; i < 10; i++){ result[i] = function() { console.info(i) } } return result; }
看起来似乎是输出等差数列0,1,2,3,4,…,9,实际上因为每个闭包函数访问变量i是outer执行环境下的变量i,随着循环的结束,i已经变成10了,所以最后打印出的是10,10,10,…,10
解决这个问题如下:
function outer() { var result = []; for (var i = 0; i < 10; i++){ result[i] = function(num) { return function() { console.info(num) } } } return result; }
这样访问的num,是上层函数执行环境的num,数组有10个函数对象,每个对象的执行环境下的number都不一样。
内存溢出
function showId() { var el = document.getElementById("app"); el.onclick = function(){ alert(el.id); } }
上面这样写会导致闭包引用外层的el,当执行完alert后,el无法释放内存。修改如下:
function showId() { var el = document.getElementById("app"); el.onclick = function(){ alert(el.id); } el = null; //主动释放el }
使用闭包解决递归调用问题
function factorial(num) { if(num <= 1) { return 1; }else{ return num * factorial(num-1); } } var anotherFactorial = factorial; factorial = null; anotherFactorial(4);
这样写是有问题的,因为最后是return num* argument.callee(num-1),argument.callee指向当前执行函数,但是在严格模式下不能使用该属性也会报错。
借助闭包实现修改如下:
function factorial = (function f(num) { if(num <= 1) { return 1; }else{ return num * factorial(num-1); } })
这样实际起作用的是闭包函数f,而不是外面的函数factorial。
每个人都经历着受骗和伤痛,
最终掌握了在这条街道生活下去的本领。
《我的晃荡的青春》
——东野圭吾
评论
Hi there very cool blog!! Man .. Excellent .. Amazing .. I’ll bookmark your site and take the feeds additionally?KI’m glad to search out so many helpful info here in the publish, we’d like develop more strategies on this regard, thanks for sharing. . . . . .
https://www.circle13.com/professional-cell-phone-hackers-for-hire/
I believe this internet site has got very great composed articles articles.
https://youtu.be/iDr5L5b6cf4
I believe you have mentioned some very interesting details, thanks for the post.
https://youtu.be/VcnFTX_9418
I like what you guys are up too. Such clever work and reporting! Carry on the superb works guys I have incorporated you guys to my blogroll. I think it’ll improve the value of my site 🙂
https://youtu.be/5MByAPBSZeY
453510 337727Excellent blog here! Additionally your site rather a lot up fast! 512920
777478 137110Oh my goodness! a fantastic post dude. Thank you Even so I will be experiencing concern with ur rss . Dont know why Can not subscribe to it. Will there be any person obtaining identical rss difficulty? Anybody who knows kindly respond. Thnkx 49897
I really appreciate this post. I?¦ve been looking all over for this! Thank goodness I found it on Bing. You have made my day! Thank you again
https://www.oraclemobilesecurity.com/instagram-hackers-for-hire/
I’m not sure exactly why but this website is loading incredibly slow for me. Is anyone else having this issue or is it a issue on my end? I’ll check back later on and see if the problem still exists.
https://youtu.be/_ICvZZ2rrx4
I view something genuinely special in this internet site.
https://youtu.be/hmnlmKLJcEg
745521 457824Some genuinely good and utilitarian information on this website, as nicely I believe the style has got fantastic features. 719744
Way cool, some valid points! I appreciate you making this article available, the rest of the site is also high quality. Have a fun.
https://youtu.be/Or5frlWsqF8
989821 582167I identified your weblog web site on google and check several of your early posts. Continue to maintain up the superb operate. I just further up your RSS feed to my MSN News Reader. Looking for forward to studying extra from you in a although! 452832
58921 224951Really informative and fantastic bodily structure of content material , now thats user friendly (:. 77679
Hello.This post was extremely fascinating, especially because I was looking for thoughts on this subject last Sunday.
https://youtu.be/m0AeJGsYkz4
Hello! I just would like to give a huge thumbs up for the great info you have here on this post. I will be coming back to your blog for more soon.
https://youtu.be/tFw1gwkoe3I
166927 405034Many thanks I ought say, impressed together with your site. I will post this to my facebook wall. 38619
226584 285951I definitely enjoyed the method which you explore your experience and perception of the area of interest 751604
154632 438246Oh my goodness! a fantastic post dude. Thanks Nevertheless My business is experiencing issue with ur rss . Dont know why Not able to sign up for it. Possibly there is any person obtaining identical rss difficulty? Anyone who knows kindly respond. Thnkx 517066
You completed a number of good points there. I did a search on the subject matter and found a good number of people will agree with your blog.
https://youtu.be/bo-Jbk3gR2I
I am often to blogging and i really appreciate your content. The article has really peaks my interest. I am going to bookmark your site and keep checking for new information.
https://youtu.be/F4LBoHVpsCA
Excellent blog here! Also your web site loads up fast! What host are you using? Can I get your affiliate link to your host? I wish my web site loaded up as fast as yours lol
https://youtu.be/uD6FxvQSzpU
141515 667713I wish I had a dime for every bad write-up Ive read lately. I also wish other writers had your talent and style. Thank you. 185439
Hi there are using WordPress for your blog platform? I’m new to the blog world but I’m trying to get started and create my own. Do you need any coding expertise to make your own blog? Any help would be really appreciated!
https://www.tdsky.com/hire-a-hacker-for-iphone/
336226 302914Most what i read online is trash and copy paste but i feel you offer something different. Maintain it like this. 536601
Thank you for sharing superb informations. Your web-site is so cool. I am impressed by the details that you?¦ve on this web site. It reveals how nicely you understand this subject. Bookmarked this web page, will come back for extra articles. You, my pal, ROCK! I found simply the information I already searched all over the place and just could not come across. What a great website.
https://youtu.be/kUzZjRD_izY
528404 3327Superb post but I was wanting to know should you could write a litte far more on this subject? Id be quite thankful in the event you could elaborate a little bit more. Thanks! 354125
540805 949825A blog like yours need to be earning a lot funds from adsense.~::- 722554