-
下面的代码输出多少?修改代码让fnArri 输出 i。使用两种以上的方法
var fnArr = []; for (var i = 0; i < 10; i ++) { fnArr[i] = function(){ return i; }; } console.log( fnArr[3]() ); //10
why output is 10?
代码在运行过程中,fnarr[i]是一个函数,保存的是一个对象,而我们知道对象是以heap保存的,而fnarr[i]仅仅保存了一个指针指向这个函数对象。当循环结束的时候,console.log中去invoke这个函数,则是依靠指针去寻找这个函数内部的变量,而这个时候,i早已经循环结束,变成了十,所以输出为10;
- solution
var a=[]; for(var i=0;i<10;i++){ a[i]=(function(){ var n=i; return function(){ return n; } })(i); } console.log(a[3]());
var a = []; for (var i = 0; i < 10; i++) { (function(n) { console.log(n); return a[i] = function() { return n } })(i) } console.log(a[3]());
var a = []; for (let i= 0; i < 10; i++) { a[i] = function(){ return i; } } console.log(a[3]()); // es6 syntax
- 闭包(closure):两个嵌套函数,内部函数可以访问外部函数作用域下的变量,而内部函数能被全局环境下的变量所引用,从而形成了closure;
- 其实质是函数作用链下的副产物
- 为什么闭包会导致内存泄露?
- 我们要了解一点就是js是如何存储数据的。
- 函数的执行上下文和作用链?
- js是如何进行垃圾回收的?
- 现在我们就能明白为什么closure会导致内存泄露了。
因为全局环境下的变量一直保存引用嵌套函数内部的函数,导致gc(garbage collection)认为这个是有用的,然后不对其进行回收。当内部函数的运算量过大的时候,内存无法存储庞大的数据的时候,就泄露出去了。解决方法,使用完,进行清除,只需要使用var 内部函数变量= null;这样就切断了作用域链,然后gc认为无用,对其进行回收
-
封装一个汽车对象,可以通过如下方式获取汽车状态
var Car = (function(){ var speed = 0; function setSpeed(s){ return (speed=s); } function getSpeed(){ return speed; } function accelerate(){ return speed+=10; } function decelerate(){ // console.log(speed); if(speed<=0){return speed;}else{return speed-=10;} } function getStatus() { if (speed>0) { return 'running'; } else { return 'stop'; } } return { setSpeed: setSpeed, getSpeed: getSpeed, accelerate:accelerate, decelerate: decelerate, getStatus:getStatus, }; })(); console.log(Car.setSpeed(30)); console.log(Car.getSpeed()); //30 console.log(Car.accelerate()); console.log(Car.getSpeed()); //40; console.log(Car.decelerate()); console.log(Car.decelerate()); console.log(Car.getSpeed()); //20 console.log(Car.getStatus()); // 'running'; console.log(Car.decelerate()); console.log(Car.decelerate()); console.log(Car.getStatus()); //'stop'; //Car.speed; //error
-
下面这段代码输出结果是? 为什么?
var a = 1; setTimeout(function(){ a = 2; console.log(a); }, 0); var a ; console.log(a); a = 3; console.log(a); 结果: 1 3 2,因为setTimeout的语句会放置代码执行队列后置中,所以先执行普通代码,最后在执行setTimeout中的代码。
-
下面这段代码输出结果是? 为什么?
var flag = true; setTimeout(function(){ flag = false; },0) while(flag){} console.log(flag); 结果:无输出。因为setTimeout语句会放置代码解析最后,所以在while中flag=true,则while语句陷入死循环中,则console.log(flag)和setTimeout语句无法执行
-
下面这段代码输出?如何输出
delayer: 0, delayer:1...
(使用闭包来实现)for(var i=0;i<5;i++){ setTimeout((function(s){ return function $ (){ console.log('delayer:' + s ); } })(i), 0); console.log(i); }
如何获取元素的真实宽高
主流浏览器通过window.getComputedStyle来获取真实宽高,低版本IE通过element.currentStyle来获取真实宽高。URL 如何编码解码?为什么要编码?
js提供两种编码方式:encodeURI,encodeURIComponent(范围更广)
解码方式:dencodeURI,decodeURIComponent;
原因: 因为URI中的部分字符会引起歧义,服务器会解析出错,则需要对出现歧义的字符进行编码-
补全如下函数,判断用户的浏览器类型
function isAndroid(){ return /Android/i.test(navigator.userAgent); } function isIphone(){ return /Iphone/i.test(navigator.userAgent); } function isIpad(){ return /Ipad/i.test(navigator.userAgent); } function isIOS(){ return /(Iphone)|(Ipad)/i.test(navigator.usrAgent); }