Javascript題之你還是不懂js
ES6入門系列四(測試題分析)
0、導言
ES6中新增了不少的新特性,來點測試題熱熱身。具體題目來源請看:http://perfectionkills.com/javascript-quiz-es6/。
以下將一題一題來解析what和why。
1、題目一
(function(x, f = () => x) { var x; var y = x; x = 2; return [x, y, f()]; })(1) A、 [2, 1, 1] B、 [2, undefined, 1] C、 [2, 1, 2] D、 [2, undefined, 2]
解析:本題主要考察的知識點是1、引數值與函式體內定義的重名變數的優先順序;2、ES6的預設引數;3、箭頭函式。 在本題中,先執行x的定義,然後函式引數x=1,接著是y = x = 1,接著再x = 2,第三個是執行f函式,箭頭函式如果只是表示式,那麼等價於return 表示式,由於箭頭函式的作用域等於定義時的作用域,那麼函式定義時x=1,所以最後的return x 等價於 return 1
2、題目二
(function() { return [ (() => this.x).bind({ x: 'inner' })(), (() => this.x)() ] }).call({ x: 'outer' }); A、 ['inner', 'outer'] B、 ['outer', 'outer'] C、 [undefined, undefined] D、 Error
解析:本題主要考察的是箭頭函式的作用域問題,箭頭函式的作用域等於定義時的作用域,所以通過bind設定的this是無效的。那麼結果就顯而易見了。
3、題目三
let x, { x: y = 1 } = { x }; y;
A、 undefined
B、 1
C、 { x: 1 }
D、 Error
解析:本題主要考察的是物件賦值,先定義x,然後在賦值的時候會執行一次y=1,最後返回y的值。
4、題目四
(function() { let f = this ? class g { } : class h { }; return [ typeof f, typeof h ]; })(); A、 ["function", "undefined"] B、 ["function", "function"] C、 ["undefined", "undefined"] D、 Error
解析:本題主要考察定義函式變數時,命名函式的名稱作用域問題。在定義函式變數時,函式名稱只能在函式體中生效。
5、題目五
(typeof (new (class { class () {} })))
A、 "function"
B、 "object"
C、 "undefined"
D、 Error
解析:本題主要考察物件的型別,和原型方法。該提可以分解如下:
// 定義包含class原型方法的類。
var Test = class{
class(){}
};
var test = new Test(); //定義類的例項
typeof test; //出結果
6、題目六
typeof (new (class F extends (String, Array) { })).substring
A、 "function"
B、 "object"
C、 "undefined"
D、 Error
解析:本題主要考察ES6中class的繼承,以及表示式的返回值和undefined的型別。題目其實可以按照如下方式分解:
//由於JS的class沒有多繼承的概念,所以括號被當做表示式來看
(String, Array) //Array,返回最後一個值
(class F extends Array); //class F繼承成Array
(new (class F extends Array)); //建立一個F的例項
(new (class F extends (String, Array) { })).substring; //取例項的substring方法,由於沒有繼承String,Array沒有substring方法,那麼返回值為undefined
typeof (new (class F extends (String, Array) { })).substring; //對undefined取typeof
7、題目七
[...[...'...']].length
A、 1
B、 3
C、 6
D、 Error
解析:本題主要考察的是擴充套件運算子...的作用。擴充套件運算子是將後面的物件轉換為陣列,具體用法是:
[...<資料>] 比如 [...'abc']等價於["a", "b", "c"]
8、題目八
typeof (function* f() { yield f })().next().next()
A、 "function"
B、 "generator"
C、 "object"
D、 Error
解析:本題主要考察ES6的生成器。題目可以如下分解:
function* f() { yield f }; //定義一個生成器
var g = f(); //執行生成器
var temp = g.next(); //返回第一次yield的值
console.log(temp); //測試,檢視temp,其實是一個object
temp.next();//對物件呼叫next方法,無效
9、題目九
typeof (new class f() { [f]() { }, f: { } })[`${f}`]
A、 "function"
B、 "undefined"
C、 "object"
D、 Error
解析:本題主要考察ES6的class,以及動態屬性和模板字串等。 實際上這個題動態屬性和模板字串都是煙霧彈,在執行new class f()的時候,就已經有語法錯誤了。
10、題目十
typeof `${{Object}}`.prototype
A、 "function"
B、 "undefined"
C、 "object"
D、 Error
解析:本題考察的知識點相對單一,就是模板字串。分解如下:
var o = {Object},
str = `${o}`;
typeof str.prototype;
11、題目十一
((...x, xs)=>x)(1,2,3)
A、 1
B、 3
C、 [1,2,3]
D、 Error
解析:本題主要考察的是Rest引數的用法,在ES6中,Rest引數只能放在末尾,所以該用法的錯誤的。
12、題目十二
let arr = [ ];
for (let { x = 2, y } of [{ x: 1 }, 2, { y }]) {
arr.push(x, y);
}
arr;
A、 [2, { x: 1 }, 2, 2, 2, { y }]
B、 [{ x: 1 }, 2, { y }]
C、 [1, undefined, 2, undefined, 2, undefined]
D、 Error
解析:本題看起來是考察let的作用域和of迭代的用法。實則是考察let的語法,let之後是一個引數名稱。所以,語法錯誤
13、題目十三
(function() {
if (false) {
let f = { g() => 1 };
}
return typeof f;
})()
A、 "function"
B、 "undefined"
C、 "object"
D、 Error
解析:本題非常有迷惑性,看似考察的let的作用域問題,實則考察了箭頭函式的語法問題。
14、題目答案
相信大家看過題目的解析,對題目答案已經瞭然。為了完善本文,還是在最後貼出所有題目的答案:
ABBAB CBDDB DDD
網頁中實現一個計算當年還剩多少時間的倒數計時程式,要求網頁上實時動態顯示“××年還剩××天××時××分××秒”
https://www.cnblogs.com/guanxiaoqing/p/3208731.html <script type="text/javascript">
function counter() {
var date = new Date();
var year = date.getFullYear();
var date2 = new Date(year, 12, 31, 23, 59, 59);
var time = (date2 - date)/1000;
var day =Math.floor(time/(24*60*60))
var hour = Math.floor(time%(24*60*60)/(60*60))
var minute = Math.floor(time%(24*60*60)%(60*60)/60);
var second = Math.floor(time%(24*60*60)%(60*60)%60);
var str = year + "年還剩"+day+"天"+hour+"時"+minute+"分"+second+"秒";
document.getElementById("input").value = str;
}
window.setInterval("counter()", 1000);
</script>