Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
久以前看過一個老外寫的帖子,JavaScript Puzzlers!,直譯就是JavaScript難題,里面列舉了44道JavaScript選擇題,大部分都是讓人摸不著頭腦的題目,需要仔細琢磨一番才能得到正確答案。也有一些作者也沒有解釋清除,直接通過實驗給出答案了。
這44個問題是在ECMA 262(5.1)環境下,瀏覽器中試驗的,如果是node環境下可能不同。這是因為二者環境差異,比如node環境下頂層變量是global,瀏覽器環境下則是windows。
本文部分內容也參考了文章Javascript 變態題解析。
["1", "2", "3"].map(parseInt)結果是什么?
map方法指定一個回調函數,重新創建一個由回調函數返回值組成的新數組。該方法的原型是:
var new_array=arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])
map接受2個參數,一個是回調函數callback,一個是回調函數的this值。
解釋如下:
Number.parseInt接受兩個參數,原型Number.parseInt(string[, radix]),一個是要解析的值,一般是字符串,如果不是的話,使用toString方法將它轉化為字符串。參數radix,是一個介于2到36之間的整數,如果省略該值或者為0,則按照10進制來解析,也就是說默認值是10,如果是“0x”或者“0X”開頭,則以16進制為基數。如果小于2或者大于36,則parseInt返回NaN。
也就是說[].map(parseInt)這種寫法根本就是想當然的,本題相當于下面的三句:
parseInt('1', 0);parseInt('2', 1);parseInt('3', 2);
這三句只有第一句會把第二個參數0默認為10,剩下兩句都不滿足radix參數介于2到36之間,所有返回[1, NaN, NaN]。另外,如果想得到正確的結果,應該這樣寫["1", "2", "2"].map(i=> parseInt(i))。
運行[typeof null, null instanceof Object]這個表達式結果是什么?,這個主要考察typeof,instanceof兩個操作符,前者是返回一個字符串表示未經計算的操作數的類型,后者是判斷null的原型鏈中是否出現了Object的構造函數的property。
這兩個操作符用來判斷類型,前者常用來判斷字面量,后者用來判斷對象的類型,但是兩個都有缺陷,詳見另一篇文章《javascript中判斷數據類型》
但是null是一個比較特殊的值,type of null返回的是“objec”,這是因為JavaScript最初實現中,值是由一個表示類型的標簽和實際數值表示的。對象的類型標簽是0,由于null代表是空指針(大多數平臺下值為0x00),因此null的類型標簽是0,typeof null也就返回“object”。
null是所有原型鏈的最頂端,null instanceof Object返回false,假設null這個值有構造函數Null,obj instanceof Null才會返回true。
所以上面表達式返回["object", false]。
表達式[ [3,2,1].reduce(Math.pow), [].reduce(Math.pow) ]返回什么?
和第1題有些類似。arr.reduce方法對數組中每個元素執行一個自定義的reducer函數(升序執行),并將結果匯總為單個值,這個常常用來累加一個數組中的數字。原型如下:
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
注意:如果沒有提供initialValue,reduce 會從索引1的地方開始執行 callback 方法,跳過第一個索引。如果提供initialValue,從索引0開始。
回調函數第一次執行時,accumulator 和currentValue的取值有兩種情況:
如果調用reduce()時提供了initialValue,accumulator取值為initialValue,currentValue取數組中的第一個值;如果沒有提供 initialValue,那么accumulator取數組中的第一個值,currentValue取數組中的第二個值。如果數組為空且沒有提供initialValue,會拋出TypeError 。如果數組僅有一個元素(無論位置如何)并且沒有提供initialValue, 或者有提供initialValue但是數組為空,那么此唯一值將被返回并且callback不會被執行。
Math.pow(base, exponent),返回基數base的指數exponent次冪,即baseexponent。
上面表達式調用reduce方法的時候沒有提供initialValue,從索引1開始執行,第一次執行的時候accumulator取arr[0],這里是3,currentValue取第二個值,這里是2,傳給Math.pow,得到9。
第二個表達式是在空數組上調用reduce,并且沒有提供initialValue,所以拋出錯誤:VM146:1 Uncaught TypeError: Reduce of empty array with no initial value at Array.reduce (<anonymous>)。
最后整個表達式的結果還是拋出錯誤。
var val='smtg';
console.log('Value is ' + (val==='smtg') ? 'Something' : 'Nothing');
上面的表達式輸出結果是什么?這個問題考察的是加號和三元運算的優先級,由于加號的優先級高于三元表達式,所以實際執行的是:
console.log('Value is true' ? 'Something' : 'Nothing');
因此最后輸出“Something”。
var name='World!';
(function () {
if (typeof name==='undefined') {
var name='Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
上面表達式輸出什么?
這個是考察var變量提升問題,使用var申明的變量會提神到函數頂部,但是并不會初始化,這個是JavaScript內部機制。于是上面語句相當于:
var name='World!';
(function () {
var name=undefined;
if (typeof name==='undefined') {
var name='Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
name的聲明放在了函數頂部,但是值是undefined。因為代碼又放在一個閉包里,用外層那個name=“world”是不能訪問的,閉包有隔離變量的作用。最后,上面的語句輸出“Goodbye Jack”。
var END=Math.pow(2, 53);
var START=END - 100;
var count=0;
for (var i=START; i <=END; i++) {
count++;
}
console.log(count);
上面表達式輸出什么?
乍一看是100,其實是干擾,這考察的不是循環,var變量啥的,而是JavaScript能表示的最大的數字是253,即次冪表達式Math.pow(2, 53)。在這個最大數的基礎上加上一個整數得到的結果都是不準確的。看下面的例子:
題目只能有30個字,不能寫全,其實今天我們要學習的內容有三個,第一,下拉列表表單,第二,多行文字輸入表單,第三,數據集表單。
開始學習吧!
前天和昨天我們在《HTML表單元素初識1——零基礎自學網頁制作》和《HTML表單元素初識2——零基礎自學網頁制作》中基本上把<input/>標簽的type屬性里不同的值進行了講解與實踐,今天我們來學習其他包含在<form></form>之間的元素。
帶有下拉列表的表單
我們在一些網站填寫注冊信息時,經常會遇到選擇"生活所在地"的操作,因為中國的地名是固定的,因此頁面會為我們提供一個下拉列表選項,我們直接點選即可,就不需要輸入文字了,這樣操作的好處在于不會出現拼寫錯誤。例如:
寫這個功能我們需要介紹一組新標簽<select></select>。"select"(選擇)。在這個標簽中再添加<option></option>。"option"(選項)。這樣就可以寫出帶有下拉列表的表單了,示例代碼如下:
<select><option></option></select>
這段代碼我們繼續在昨天的"表單.html"文件中添加即可,在<input type="image" src="img/示例圖片/submit.jpg"/><br>這段代碼之前即可!與這個圖片提交按鈕共用一個<form></form>標簽!
下面我們為多選表單添加名稱,示例代碼如下:
請選擇省份<select><option></option></select>
下面我們添加不同選項,示例代碼如下:
請選擇省份
<select >
<option >河北</option>
<option >山東</option>
<option >河南</option>
<option >海南</option>
<option >江蘇</option>
<option >安徽</option>
</select>
<br><br>
為了規范起見,我們為表單信息添加name和value屬性,示例代碼如下:
請選擇省份
<select name="province">
<option value="Hebei">河北</option>
<option value="Shandong">山東</option>
<option value="Henan">河南</option>
<option value="Hainan">海南</option>
<option value="Jiangsu">江蘇</option>
<option value="Anhui">安徽</option>
</select>
<br><br>
大家要注意的是,在下拉列表表單中,name寫在<select>中,value寫在<option>中。
頁面效果如下:
這里告訴大家一個規律,下拉列表表單默認顯示第一個<option></option>中的文字內容。
如果您想改變這個默認顯示,請在需要顯示的<option>中添加selected屬性,并賦值為"selected"。
示例代碼如下:
請選擇省份
<select name="province">
<option value="Hebei">河北</option>
<option value="Shandong">山東</option>
<option value="Henan" selected="selected">河南</option>
<!--選中這個選項--><option value="Hainan">海南</option><option value="Jiangsu">江蘇</option><option value="Anhui">安徽</option></select><br><br>
頁面效果如圖:
多行文字輸入表單
我們在西瓜視頻上發布視頻時會被要求填寫視頻描述,頁面中的輸入框不是像下圖這么短的單行輸入框。
而是多行輸入框,如圖:
使用<textarea></textarea>標簽即可添加這樣的輸入框,不過要設置row(列)和cols(行)屬性的數值。示例代碼如下:
<br>請簡要描述您的劇本的情節<br><textarea row="3" cols="20"></textarea><br>
這段代碼添加到</select><br><br>之后,與其共同使用一個<form></form>標簽。
下面我們為這個多行輸入框添加一些提示和限制。
首先,添加提示文字,和type="text"的<input/>標簽一樣,都是使用placeholder屬性。
第二,我們限制一下字數,使用maxlength(最大長度)屬性。
第三,在頁面加載完成后,直接讓光標停留在輸入框中,使用autofocus屬性。
下面看看如何寫吧,示例代碼如下:(不要忘記寫好name屬性!)
<br>
請簡要描述您的劇本的情節<br>
<textarea row="3" cols="20" name="storyOutLine"placeholder="最多輸入80字"maxlength="80"autofocus></textarea><br>
頁面效果如圖:
如果刷新頁面不能正確顯示,請嘗試關閉后重新打開!
數據集表單
數據集表單實際上就是一個將不同選項或信息打包上傳的設置。
當一組表單元素放到 <fieldset> 標簽內時,瀏覽器會以特殊方式來顯示它們,它們可能有特殊的邊界、3D 效果,或者甚至可創建一個子表單來處理這些元素。(W3school)
這個數據集有三個部分組成,首先是<fliedset></fliedset>,這個標簽不會顯示,只是告訴瀏覽器這里的數據要打包。
第二是<legend></legend>,"legend"(說明),這里添加數據集名稱。
第三就是我們之前學到的那些標簽了。
示例代碼如下:
<fliedset> <legend>信息打包</legend> </fliedset>
下面我們使用這段代碼把form2打包一下吧。示例代碼如下:
<form>
<fieldset><!--開始-->
<legend>信息打包</legend><br>
<!--標題-->興趣愛好:<br>
<input type="checkbox" name="hobby" value="reading"/>讀書
<input type="checkbox" name="hobby" value="film"/>電影
<input type="checkbox" name="hobby" value="painting"/>繪畫
<input type="checkbox" name="hobby" value="music"/>音樂
<br>
最高學歷:<br>
<input type="radio" name="education" value="highSchool"/>高中
<input type="radio" name="education" value="bachelor"/>本科
<input type="radio" name="education" value="master"/>碩士
<input type="radio" name="education" value="doctor"/>博士
<br>
請選擇省份
<select name="province">
<option value="Hebei">河北</option>
<option value="Shandong">山東</option>
<option value="Henan" selected="selected">河南</option><!--選中這個選項-->
<option value="Hainan">海南</option>
<option value="Jiangsu">江蘇</option>
<option value="Anhui">安徽</option>
</select>
<br><br><br>
請簡要描述您的劇本的情節<br>
<textarea row="3" cols="20" name="storyOutLine"placeholder="最多輸入80字"maxlength="80"autofocus></textarea>
<br>
</fieldset><!--結尾-->
<input type="image" src="img/示例圖片/submit.jpg"/><br>
<input type="reset" /><br>
<input type="submit" value="submit"/>
</form>
頁面效果如下:
今天的內容結束了!
如果您喜歡我的教程請關注我,點贊也能讓我充滿動力!
HTML序章(學習目的、對象、基本概念)——零基礎自學網頁制作
HTML是什么?——零基礎自學網頁制作
第一個HTML頁面如何寫?——零基礎自學網頁制作
HTML頁面中head標簽有啥用?——零基礎自學網頁制作
初識meta標簽與SEO——零基礎自學網頁制作
HTML中的元素使用方法1——零基礎自學網頁制作
HTML中的元素使用方法2——零基礎自學網頁制作
HTML元素中的屬性1——零基礎自學網頁制作
HTML元素中的屬性2(路徑詳解)——零基礎自學網頁制作
使用HTML添加表格1(基本元素)——零基礎自學網頁制作
使用HTML添加表格2(表格頭部與腳部)——零基礎自學網頁制作
使用HTML添加表格3(間距與顏色)——零基礎自學網頁制作
使用HTML添加表格4(行顏色與表格嵌套)——零基礎自學網頁制作
16進制顏色表示與RGB色彩模型——零基礎自學網頁制作
HTML中的塊級元素與內聯元素——零基礎自學網頁制作
初識HTML中的<div>塊元素——零基礎自學網頁制作
在HTML頁面中嵌入其他頁面的方法——零基礎自學網頁制作
封閉在家學網頁制作!為頁面嵌入PDF文件——零基礎自學網頁制作
HTML表單元素初識1——零基礎自學網頁制作
HTML表單元素初識2——零基礎自學網頁制作
HTML表單3(下拉列表、多行文字輸入)——零基礎自學網頁制作
HTML表單4(form的action、method屬性)——零基礎自學網頁制作
HTML列表制作講解——零基礎自學網頁制作
為HTML頁面添加視頻、音頻的方法——零基礎自學網頁制作
音視頻格式轉換神器與html視頻元素加字幕——零基礎自學網頁制作
HTML中使用<a>標簽實現文本內鏈接——零基礎自學網頁制作
最近看到一道跟Javascript中的setTimeout和Promise有關的面試題,感覺很有趣。題目循序漸進,不斷深入,雖然只是一道題目的簡單變形,卻考察了很多個知識點,今天我們就一起來看看這道題目吧。
Javascript
我們就直接看題目的代碼,首先是最簡單的原始題目。
原始題目
上述的代碼很簡單,輸出0,1,2,3,4。你可能會疑問,面試題會有這么簡單?放心,好戲還在后頭呢。
我們將上述的代碼加上setTimeout,再進行輸出,看看會輸出什么?
變形1
上述代碼每隔一秒會輸出一個5。
這道題考察的是函數的閉包,如果不太清楚閉包知識的,可以去看看我寫的這篇文章《前端面試中不可逃避的閉包問題,你真的了解嗎?》。
那么如果我們想要每間隔一秒輸出從0到4,該如何實現呢?
如果了解閉包知識的話,可以很容易想出通過立即執行函數解決。
變形2
通過上述的代碼,就可以很容易達到我們的要求。
那么我們繼續對題目做變形,我們去掉這個立即執行函數中的i參數,看看結果會輸出什么?
變形3
通過在控制臺中運行,我們發現結果和變形1一樣,間隔一秒輸出一個5,那么為什么會這樣呢?
這是因為在立即函數內部并沒有對i的引用,實際的i仍然為外部作用域中的i,所以結果會和變形1相同。
我們繼續對這道題目做出變形,將setTimeout中函數改為一個立即執行函數,看看結果會是什么?
變形4
通過在控制臺運行上述代碼,得到的結果是立即輸出0, 1, 2, 3, 4。為什么會這樣呢?
根據setTimeout的用法,它接收的參數為函數或者函數的字符串表示,如果給setTimeout傳遞一個立即執行函數,則相當于傳遞了一個undefined,實際上是往定時器線程中添加了5個undefined。但是由于立即執行函數的存在,這個函數會立即執行,所以會立即輸出0, 1, 2, ,3 ,4。
如果以上的部分你都能知道,那么我們再來個更難一點的變形,將setTimeout配合Promise一起使用,看看以下的一段代碼會輸出什么?
變形5
通過在控制臺運行以上代碼,我們得到結果是立即輸出2, 3, 5, 4, 1,這是為什么呢?
首先在代碼的開頭,使用了setTimeout設置了一個定時器,雖然這個定時器的時間為0,但是根據Javascript中的事件隊列機制,會將這個定時器添加到專屬的定時器線程中,等到當前線程中的事件回調執行完后才能執行。不太懂Javascript的setTimeout機制的,可以去看看我寫的這篇文章《Javascript中的setTimeout黑魔法》。
然后是定義一個Promise,這個Promise會在setTimeout之前執行。在Promise中執行了兩個console.log(),所以會先輸出2,3。
在Promise中有一個for循環,當循環執行到i等于9999時,執行resolve回調函數,這個resolve函數就是后面輸出4的函數。但是由于Promise.then()的回調會在當前事件隊列的最后執行,因此4會在5的后面輸出。
在當前事件隊列執行完后,才會執行setTimeout中的函數,因此1是最后輸出的。
因此輸出結果是2, 3, 5, 4, 1。
由一道最簡單的題可以通過變形衍生出很多知識點的考題,看看你都會做嗎?
*請認真填寫需求信息,我們會在24小時內與您取得聯系。