1. 程式人生 > >Javascript題之你還是不懂js

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>