題目1: 下面的代碼輸出多少?修改代碼讓 fnArr[i]()
輸出i
钉迷。使用 兩種以上的方法
var fnArr = [];
for (var i = 0; i < 10; i ++) {
fnArr[i] = function(){
return i;
};
}
console.log( fnArr[3]() ); //打印出10
/*
因為當i自增到10,才跳出for循環(huán),然后開始執(zhí)行fnArr[3](),匿名函數(shù)function(){return i;} 此時才被調(diào)用,
調(diào)用的時候i=10,所以返回10.
*/
解決辦法:
//方法1:
for (var i = 0; i < 10; i++) {
fnArr[i] = (function(i){ //這個括號里的i是自有變量,與外部for里的i毫無關(guān)聯(lián),只受傳入的參數(shù)影響
return function(){ //返回一個函數(shù)function(){}
return i;
};
})(i); //這個i為外部傳入的參數(shù)
}
console.log(fnArr[3]()) //打印結(jié)果為3.
//注意這里fnArr[3]()能調(diào)用,說明fnArr[i]是個函數(shù),所以上面需要需要返回一個函數(shù)function(){}
//方法2:
for (var i = 0; i < 10; i++) {
(function(i){
fnArr[i] = function(){
return i;
}
})(i)
}
console.log(fnArr[3]()) //打印結(jié)果為3.
//方法3:
for (let i = 0; i < 10; i++) { //let 語句聲明一個塊級作用域的本地變量
fnArr[i] = function(){
return i;
};
}
console.log(fnArr[3]()); //打印結(jié)果為3
總結(jié):
- 可以用立即表達式的方式在內(nèi)部再聲明一個內(nèi)部自有變量,形成新的作用域阻隔變量提升,來解決因為變量提升所產(chǎn)生的問題
題目2: 封裝一個汽車對象抓韩,可以通過如下方式獲取汽車狀態(tài)
var Car = (function(){
var speed = 0;
function setSpeed(s){
speed = s
}
/* 補充*/
function getSpeed(){
return speed;
}
function accelerate(){
speed += 10;
}
function decelerate(){
if(speed >= 10){
speed -= 10;
}else{
console.log('減速幅度大于當前最低速度,無法減速')
}
}
function getStatus(){
if(speed > 0){
console.log('running');
}else{
console.log('stop');
}
}
return {
setSpeed: setSpeed,
/*補充*/
getSpeed: getSpeed,
accelerate: accelerate,
decelerate: decelerate,
getStatus: getStatus
}
})()
Car.setSpeed(30);
Car.getSpeed(); //30
Car.accelerate();
Car.getSpeed(); //40;
Car.decelerate();
Car.decelerate();
Car.getSpeed(); //20
Car.getStatus(); // 'running';
Car.decelerate();
Car.decelerate();
Car.getStatus(); //'stop';
//Car.speed; //error
題目3:下面這段代碼輸出結(jié)果是? 為什么?
var a = 1;
setTimeout(function(){
a = 2;
console.log(a);
}, 0);
var a ;
console.log(a);
a = 3;
console.log(a);
解題思路:
//聲明前置
var a;
var a ;
a = 1;
setTimeout(function(){
a = 2;
console.log(a); //打印出2,但是由于setTimeout運行機制,需等到所有代碼執(zhí)行完,才會執(zhí)行
}, 0);
console.log(a); //打印出1,因為上面a被賦值為1
a = 3;
console.log(a); //打印出3,因為上面a被賦值為3
因為定時器的運行機制:將指定的代碼移出本次執(zhí)行,等到下一輪 Event Loop 時,再檢查是否到了指定時間痢站。如果到了,就執(zhí)行對應的代碼选酗;如果不到阵难,就等到再下一輪 Event Loop 時重新判斷時間
所以最終打印順序及結(jié)果是
1
3
2
題目4:下面這段代碼輸出結(jié)果是? 為什么?
var flag = true;
setTimeout(function(){ //由于setTimeout運行機制,要等到所有代碼執(zhí)行完,才會被執(zhí)行,所以這里也永遠不被執(zhí)行
flag = false;
},0)
while(flag){} /*while循環(huán)的特性,只要指定條件是true,循環(huán)就可以一直執(zhí)行代碼.因為flag為true,while無限循環(huán),不會執(zhí)行之后的代碼*/
console.log(flag); //不被執(zhí)行
代碼沒有任何輸出
題目5: 下面這段代碼輸出?如何輸出delayer: 0, delayer:1...(使用閉包來實現(xiàn))
for(var i=0;i<5;i++){
setTimeout(function(){
console.log('delayer:' + i );
}, 0);
console.log(i);
}
整理以上代碼:聲明提前,setTimeout代碼執(zhí)行置后
var i
for(i=0;i<5;i++){
console.log(i); //因為定時器執(zhí)行機制, 所以此行優(yōu)先執(zhí)行,先輸出0 1 2 3 4
setTimeout(function(){
console.log('delayer:' + i ); //執(zhí)行完所有代碼后開始執(zhí)行,i已經(jīng)自增到5,因為只有一個全局變量i,此時i的值為5,所以輸出5次 delayer:5
}, 0);
}
解題思路:可以在函數(shù)內(nèi)部再聲明一個內(nèi)部變量
for(var i=0;i<5;i++){
(function(i){ //這個i是函數(shù)自有變量 ,與外部變量i不是同一個變量,不受for循環(huán)里的i值影響,只受傳入的參數(shù)i影響
setTimeout(function(){
console.log('delayer:' + i ); // 這里的i也是自有內(nèi)部變量,當所有代碼執(zhí)行完后,開始執(zhí)行,傳入?yún)?shù)依次是0 1 2 3 4
}, 0);
console.log(i);
})(i); //i為傳入?yún)?shù) 傳入?yún)?shù)依次是 0 1 2 3 4
}
所以最終輸出結(jié)果是:
0
1
2
3
4
delayer:0
delayer:1
delayer:2
delayer:3
delayer:4
題目6: 如何獲取元素的真實寬高
主流瀏覽器通過window.getComputedStyle
來獲取真實style芒填,低版本IE通過element.currentStyle
來獲取真實style
<style>
.box{
border: 3px solid red;
height: 300px;
width: 500px;
}
</style>
<div class="box"></div>
<script>
var box = document.querySelector('.box') //獲取元素節(jié)點
//獲取元素的真實style
function trueStyle(element,pseudoElt){
return element.currentStyle ? element.currentStyle : window.getComputedStyle(element,pseudoElt);
}
var tureWidth = trueStyle(box).width;
var trueHeight = trueStyle(box).height;
題目7: URL 如何編碼解碼呜叫?為什么要編碼?
編碼方式:
encodeURI()
encodeURIComponent()
區(qū)別:
encodeURI
方法不會對下列字符編碼ASCII字母殿衰、數(shù)字朱庆、~!@#$&*()=:/,;?+'
encodeURIComponent
方法不會對下列字符編碼ASCII字母、數(shù)字闷祥、~!*()'
所以encodeURIComponen
t比encodeURI
編碼的范圍更大娱颊。解碼方式:
decodeURI()
decodeURIComponent()
編碼原因:
對于Url來說,之所以要進行編碼,是因為Url中有些字符會引起歧義箱硕。
比如說“name1=value1”,其中value1的值是“va&lu=e1”字符串拴竹,那么實際在傳輸過程中就會變成這樣“name1=va&lu=e1”。我們的本意是就只有一個鍵值對剧罩,但是服務端會解析成兩個鍵值對栓拜,這樣就產(chǎn)生了歧義。
又如斑响,Url的編碼格式采用的是ASCII碼菱属,而不是Unicode,這也就是說你不能在Url中包含任何非ASCII字符舰罚,例如中文纽门。否則如果客戶端瀏覽器和服務端瀏覽器支持的字符集不同的情況下,中文可能會造成問題营罢。
URL編碼的原則就是使用安全的字符(沒有特殊用途或者特殊意義的可打印字符)去表示那些不安全的字符.
預備知識:URI是統(tǒng)一資源標識的意思赏陵,通常我們所說的URL只是URI的一種。下面提到的URL編碼饲漾,實際上應該指的是URI編碼蝙搔。
[參考]https://www.cnblogs.com/jerrysion/p/5522673.html
題目8補全如下函數(shù),判斷用戶的瀏覽器類型
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.userAgent)
}