1.題目1: 下面的代碼輸出多少?修改代碼讓 fnArri 輸出 i疲憋。使用 兩種以上的方法
var fnArr = [];
for (var i = 0; i < 10; i ++) {
fnArr[i] = function(){
return i;
};
}
console.log( fnArr[3]() ); //
- 方法一:
var fnArr=[];
for(var i=0;i<10;i++){
fnArr[i]=function(i){
var arr=function(){
return i
}
return arr
}(i)
}
console.log(fnArr[3]())
立即執(zhí)行函數(shù)表達式中的i 相當(dāng)于 var i=傳進來的參數(shù)i,此時外界的i改變望拖,已經(jīng)不能影響立即執(zhí)行表達式函數(shù)內(nèi)部的i,函數(shù)體內(nèi)部的i和外界的i不是一個渺尘,完全可以用a代替。
- 方法2
var fnArr=[]
for(var i=0;i<10;i++){
(function(i){
fnArr[i]=function(){
return i
}
})(i)
}
console.log(fnArr[3]())
兩種方法都是一個意思说敏,用立即執(zhí)行函數(shù)表達式鸥跟,解決閉包帶來的"負面"影響,根據(jù)作用域鏈的影響,我們找一個未命名的變量医咨,找不到了就去找他爸爸枫匾,找不著就去找他爺爺,直到找不到才返回undefined拟淮。
題目中代碼怎么了干茉?
- 變量提升,
i 是全局變量很泊,無論多少層嵌套角虫,只要找i,總能找到委造。 - 執(zhí)行循環(huán)體
fnArr[i]=一個函數(shù)戳鹅,只要沒有調(diào)用,fnArr[i]就是一個函數(shù)昏兆,不會去執(zhí)行函數(shù)體內(nèi)部的任何語句枫虏。for循環(huán)的執(zhí)行結(jié)果只能是 fnArr[0]=一個函數(shù),fnArr[1]=一個函數(shù).... -
fnArr=[3]()
這個時候亮垫,執(zhí)行了fnArr[3]()
這個函數(shù)模软,然后伟骨,執(zhí)行函數(shù)體內(nèi)部語句 return i - 函數(shù)體內(nèi)部并沒有這個i,沿著作用域鏈去尋找饮潦,找到了全局變量,全局變量i=10携狭;所以題目中的代碼是10 继蜡。
代碼一做了什么?
- 變量提升,跟上述一樣逛腿。
- 執(zhí)行循環(huán)體稀并,但是`fnArr[i]=一個立即執(zhí)行表達式,立刻執(zhí)行,把變量i的值立即傳遞進去单默,i=0 的時候傳遞的就是0 碘举,i=1的時候傳遞的就是1。
- 然后表達式內(nèi)部聲明了一個變量搁廓,這個變量是一個函數(shù)引颈,函數(shù)不執(zhí)行,函數(shù)表達式返回一個函數(shù)境蜕。函數(shù)表達式還做了一個重要的事情就是蝙场,,var i = i ; 第一個i 是函數(shù)體內(nèi)部事先聲明的粱年,第二個i是傳進來的i 售滤。第一個i 你完全可以亂改,叫 a, 叫b 都行,只要你后面返回的時候也返回 a完箩,返回b 就可以了赐俗。這個時候,fnArr[i]實際上仍然是一個函數(shù)弊知,
fnArr[0]=function(){var i=0;*****}
,fnArr[1]=function(){var i=1;*****}
秃励,只是同樣不執(zhí)行而已。 - 最后吉捶,執(zhí)行函數(shù)
fnArr[3]()
然后執(zhí)行的結(jié)果就是3.
題目2: 封裝一個汽車對象夺鲜,可以通過如下方式獲取汽車狀態(tài)
var Car = (function (spe){
var speed;
function setSpeed(spe){
speed = spe;
}
function getSpeed(){
console.log(speed) ;
}
function accelerate(){
speed += 10;
}
function decelerate(){
speed -= 10;
}
function getStatus(){
//speed > 0 ? console.log('running'):console.log('stop');
console.log(speed > 0 ? 'running' : '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';
3.下面這段代碼輸出結(jié)果是? 為什么?
var a = 1;
setTimeout(function(){
a = 2;
console.log(a);
}, 0);
var a ;
console.log(a);
a = 3;
console.log(a);
最終輸出,1 呐舔,3币励,2,
4. 下面這段代碼輸出結(jié)果是? 為什么?
var flag = true;
setTimeout(function(){//等待所有任務(wù)結(jié)束后執(zhí)行
flag = false;
},0)
while(flag){} //setTimeout會等待它執(zhí)行完畢珊拼,此時flag永遠是true食呻,無限循環(huán)。
console.log(flag);
5.下面這段代碼輸出澎现?如何輸出delayer: 0, delayer:1...(使用閉包來實現(xiàn))
for(var i=0;i<5;i++){
(function(i){
setTimeout(function(){
console.log('delayer:' + i );
}, 0);
console.log(i);
})(i)
}
6.如何獲取元素的真實寬高?
var lala=document.querySelector('.lala')
console.log(lala.offsetWidth)
console.log(lala.offsetHeight)//內(nèi)容+內(nèi)邊距+邊框
console.log(lala.clientWidth)//內(nèi)容+內(nèi)邊距
console.log(window.getComputedStyle(lala).width)//IE下用element.currentStyle.,真實內(nèi)容寬度
7. URL 如何編碼解碼?為什么要編碼剑辫?
首先弄懂url和uri是什么鬼東西干旧。
“URI可以分為URL,URN或同時具備locators 和names特性的一個東西。URN作用就好像一個人的名字妹蔽,URL就像一個人的地址椎眯。換句話說:URN確定了東西的身份,URL提供了找到它的方式胳岂”嗾”
URL 是URI的一個子集。
讓URI能成為URL的當(dāng)然就是那個“訪問機制”乳丰,“網(wǎng)絡(luò)位置”掌测。URL格式
典型Url的格式如上面所示。下面提到的Url編碼产园,實際上應(yīng)該指的是URI編碼汞斧。
-
為什么要編碼
- RFC3986文檔規(guī)定,Url中只允許包含英文字母(a-zA-Z)淆两、數(shù)字(0-9)断箫、-_.~4個特殊字符以及所有保留字符。
- 保留字符::Url可以劃分成若干個組件秋冰,協(xié)議仲义、主機、路徑等。有一些字符(:/?#[]@)是用作分隔不同組件的埃撵。例如:冒號用于分隔協(xié)議和主機赵颅,/用于分隔主機和路徑,?用于分隔路徑和查詢參數(shù)暂刘,等等饺谬。還有一些字符(!$&'()*+,;=)用于在每個組件中起到分隔作用的,如=用于表示查詢參數(shù)中的鍵值對谣拣,&符號用于分隔查詢多個鍵值對募寨。當(dāng)組件中的普通數(shù)據(jù)包含這些特殊字符時,需要對其進行編碼森缠。
RFC3986中指定了以下字符為保留字符:! * ' ( ) ; : @ & = +
$ , / ? # [ ]
總有情況讓URL編碼變得混亂不堪
情況1:網(wǎng)址路徑中包含中文
情況2:查詢字符串中包含中文
情況3:post和get請求中包含中文拔鹰,
情況4: Ajax調(diào)用的URL包含漢字。
而且贵涵,針對不同情況瀏覽器列肢,網(wǎng)頁,編碼的處理方式不同宾茂。所以瓷马,導(dǎo)致編碼混亂不堪。-
如果程序員要把每一種結(jié)果都考慮進去跨晴,是不是太恐怖了欧聘?有沒有辦法,能夠保證客戶端只用一種編碼方法向服務(wù)器發(fā)出請求坟奥?
我們可以在JavaScirpt中解決树瞭。
使用Javascript先對URL編碼,然后再向服務(wù)器提交爱谁,不要給瀏覽器插手的機會。因為Javascript的輸出總是一致的孝偎,所以就保證了服務(wù)器得到的數(shù)據(jù)是格式統(tǒng)一的访敌。
JS對URL編碼提供了三組函數(shù)escape,encodeURI衣盾,encodeURIComponent——都是用于將不安全不合法的Url字符轉(zhuǎn)換為合法的Url字符表示寺旺,它們有以下幾個不同點。- escape(69個):*/@+-._0-9a-zA-Z
- encodeURI(82個):!#$&'()*+,/:;=?@-._~0-9a-zA-Z
- encodeURIComponent(71個):!'()*-._~0-9a-zA-Z
從上面我們可以看到 encodeURI適合對整個URL進行編碼势决,因為阻塑,他不轉(zhuǎn)義各種URL中的保留字符,而encodeURIComponent范圍大果复,會編碼保留字符陈莽,所以使用于單個組件。
8.題目8:補全如下函數(shù),判斷用戶的瀏覽器類型
function isAndroid(){
return /Android/.test(navigator.userAgent);
}
funcnction isIphone(){
return /iPhone/.test(navigator.userAgent);
}
function isIpad(){
return /iPad/.test(navigator.userAgent);
}
function isIOS(){
return /(iPad)|(iPhone)/i.test(navigator.userAgent);
}