人は時に、
過去に執着する。
人は時に、
他人と比べ、妬む。
人は時に、
評価されようと躍起になる。
しかし、それらが自らの首を締め、
本来の自分を忘れさせる。
そんなあなたにjavascript禅問答を繰り返し、
「吾唯足るを知る」という言葉を思い出して欲しいと思い、
今回は筆をとりました。
具体的な内容としては、
javascriptにそんな触れたことがなかった僕が、
「こうなるの!!」と、
ときめきのようなものを感じて過去にqiitaに書いたクイズです。
その中で反応があったものをいくつかピックアップしてみました。
(クイズの中で、もしかしたら、ワードの使い方が間違えてるところがあるかもしれません。その時は・・・)
#1.問題「関数」
https://qiita.com/namitop/items/614346a8630d17b9cf5f
① 出力「?」は、何になるか?
function hoge(a,b){
return a + b
}
var sum = hoge;
sum(3,4)
// => 7
hoge(3,4)
// => ?
② 出力「?」は何になるか
var sum = function hoge(a,b){
return a + b
}
sum(3,4)
// => 7
hoge(3,4)
// => ?
#1.答え
① => 7
function hoge(a,b){
return a + b
}
var sum = hoge;
hoge(3,4)
// => 7
② => Uncaught ReferenceError
var sum = function hoge(a,b){
return a + b
}
hoge(3,4)
// => Uncaught ReferenceError: hoge is not defined
// at <anonymous>:1:1
2.問題「比較」
第1問
var s1 = "abc"
var s2 = "abc"
s1 == s2
//=> ?
第2問
var s1 = String("abc")
var s2 = String("abc")
s1 == s2
//=> ?
第3問
var s1 = new String("abc")
var s2 = new String("abc")
s1 == s2
//=> ?
#2.答え
第1問 true
文字列リテラルの比較になります
var s1 = "abc"
var s2 = "abc"
s1 == s2
//=> true
第2問 true
string関数呼び出しなので、stringの比較になります。
var s1 = String("abc")
var s2 = String("abc")
s1 == s2
//=> true
第3問 false
objectの比較になります。
var s1 = new String("abc")
var s2 = new String("abc")
s1 == s2
//=> false
3.問題「MAX_VALUE, INFINITYの計算」
MAX_VALUEはNumberの最大値を
POSITIVE_INFINITYは正の無限大を表します。
Number.MAX_VALUE
//=> 1.7976931348623157e+308
Number.POSITIVE_INFINITY
//=> Infinity
第1問
Number.MAX_VALUE*2
//=> ?
第2問
Infinity/2
//=> ?
第3問
Infinity*0
//=> ?
第4問
2/Infinity
//=> ?
第5問
Infinity/Infinity
//=> ?
第6問
2%Infinity
//=> ?
#3.答え
第1問
Number.MAX_VALUE*2
//=> Infinity
第2問
Infinity/2
//=> Infinity
第3問
Infinity*0
//=> NaN
第4問
2/Infinity
//=> 0
第5問
Infinity/Infinity
//=> NaN
第6問
2%Infinity
//=> 2
4.問題「NaNの比較」
[おさらい]NaNとは?
NaNは非数(Not-a-Number)を表す値である。
typeof NaN
//=> number
NaN*0
//=> NaN
第1問
NaN==NaN
//=> ?
第2問
NaN===NaN
//=> ?
第3問
NaN<NaN
//=> ?
第4問
NaN>NaN
//=> ?
第5問
isNaN(NaN)
//=> ?
#4.答え
第1問
NaN==NaN
//=> false
第2問
NaN===NaN
//=> false
第3問
NaN<NaN
//=> false
第4問
NaN>NaN
//=> false
第5問
isNaN(NaN)
//=> true
NaNは、
"NaN は別の NaN 値を含むあらゆる数と同じではないと比較されます"
らしいです。
5.問題「null,undefined,NaNのtypeof」
typeof null
//=> ?
typeof undefined
//=> ?
typeof NaN
//=> ?
5.答え
typeof null
//=> "object"
typeof undefined
//=> "undefined"
typeof NaN
//=> "number"
6.問題「ECMAScript第五版以前以後のundefined」
[おさらい]ECMAScript第五版以前以後のundefined
undefined値は明示的に値を代入していない変数の初期値である。
##第1問「ECMAScript第五版以前」
undefined = "abc"
undefined //=> ?
##第2問「ECMAScript第五版以後」
undefined = "abc"
undefined //=> ?
6.答え
##第1問「ECMAScript第五版以前」
undefined = "abc"
undefined //=> "abc"
##第2問「ECMAScript第五版以後」
undefined = "abc"
undefined //=> undefined
undefinedは、ECMAScript第五版の前後で動きが違います
7.問題「数値への変換」
参考:パーフェクトjavascript
第1問
Number('100x')
//=> ?
parseInt('100x')
//=> ?
Number('')
//=> ?
Number(true)
//=> ?
Number(false)
//=> ?
Number(null)
//=> ?
Number(undefined)
//=> ?
7.答え
Number('100x')
//=> NaN
parseInt('100x')
//=> 100
Number('')
//=> 0
Number(true)
//=> 1
Number(false)
//=> 0
Number(null)
//=> 0
Number(undefined)
//=> NaN
8.問題「文字列と数値」
第1問
"100" - "1"
//=> ?
"100" + "1"
//=> ?
第2問
typeof +"100"
//=> ?
第3問
"100"+NaN
//=> ?
100+NaN
//=> ?
8.答え
##第1問 文字列の数の計算
"100" - "1"
//=> 99
"100" + "1"
//=> "1001"
-
演算子を使った時は数値に変換し計算し、
+
演算子を使った時は文字列として結合する。
##第2問 符号つけたときのtypeof
typeof +"100"
//=> number
+
演算子をつけることで数値に変換され、typeofはnumberになる
##第3問
+
演算子を使った時は、文字列として結合します。
-
演算子を使った時は、数値に変換し計算するのでNaNになります。
"100"+NaN
//=> "100NaN"
100+NaN
//=> NaN
#9.問題「文字と数」
'x' * 0
//=> ?
+'x'
//=> ?
#9.答え
'x' * 0
//=> NaN
+'x'
//=> NaN
*0
や+
で、数字として変換されて処理しようとします。
その結果、xは数字で表せないのでNaN
となります。
#10.問題「プロトタイプ継承」
function MyClass() {}
MyClass.prototype.x = 1;
var obj = new MyClass();
obj.y = 2;
obj.x; //=> 1
obj.y; //=> 2
delete obj.x; //=> ?
obj.x; //=> ?
delete obj.y; //=> true
obj.y; //=> undefined
#10.答え
function MyClass() {}
MyClass.prototype.x = 1;
var obj = new MyClass();
obj.y = 2;
obj.x; //=> 1
obj.y; //=> 2
delete obj.x; //=> true
obj.x; //=> 1
delete obj.y; //=> true
obj.y; //=> undefined
プロトタイプ継承したプロパティはdeleteできません。
直感的には、delete obj.x; //=> false
になりそうですが、
xは削除できていないのに、trueが返ってきます
#11.問題「関数で不変オブジェクト化~Object.seal~」
var obj = {x:2, y:3};
Object.seal(obj);
obj.z = 4;
Object.keys(obj); //=>?
delete obj.y;
Object.keys(obj); //=>?
obj.x = 20;
obj.x; //=>?
#11.答え
var obj = {x:2, y:3};
Object.seal(obj);
//プロパティ追加はできない
obj.z = 4;
Object.keys(obj); //=>["x", "y"]
//プロパティ削除はできない
delete obj.y; //=> false
Object.keys(obj); //=> ["x", "y"]
//プロパティ値変更は可能
obj.x = 20;
obj.x; //=> 20
#12.問題「関数で不変オブジェクト化~Object.freeze編~」
var obj = {x:2, y:3};
Object.freeze(obj);
obj.z = 4;
Object.keys(obj); //=>?
delete obj.y;
Object.keys(obj); //=>?
//プロパティ値変更はできない
obj.x = 20;
obj.x; //=>?
#12.答え
var obj = {x:2, y:3};
Object.freeze(obj);
//プロパティ追加はできない
obj.z = 4;
Object.keys(obj); //=>["x", "y"]
//プロパティ削除はできない
delete obj.y; //=> false
Object.keys(obj); //=> ["x", "y"]
//プロパティ値変更はできない
obj.x = 20;
obj.x; //=> 2
#13.問題「eval」
このevalはA,Bどちらと同じになるでしょう?
eval('{x:1}') //=> 1
・A
x:1 //=> ?
・B
{x:1} //=> ?
#13.答え
このevalはA,Bどちらと同じになるでしょう?
eval('{x:1}') //=> 1
・A
x:1 //=> 1
・B
{x:1} //=> {x: 1}
答えはA。
#14.問題「比較」
#第1問
'10'>2 //=> ?
#第2問
'10'>'2' //=> ?
#14.答え
#第1問
'10'>2 //=> true
数として変換され比較します
#第2問
'10'>'2' //=> false
文字列として比較します
#15.問題「関数スコープ」
##第1問
var i = 1;
for(i=0; i<10; i++){
}
i //=> ?
##第2問
var i = 1;
for(var i=0; i<10; i++){
}
i //=> ?
##第3問
for(var i=0; i<10; i++){
}
i //=> ?
#15.答え
##第1問
var i = 1;
for(i=0; i<10; i++){
}
i //=> 10
##第2問
var i = 1;
for(var i=0; i<10; i++){
}
i //=> 10
##第3問
for(var i=0; i<10; i++){
}
i //=> 10
#16.問題「letとブロックスコープ」
##第1問
let i = 1;
for(i=0; i<10; i++){
}
i //=> ?
##第2問
let i = 1;
for(let i=0; i<10; i++){
}
i //=> ?
##第3問
for(let i=0; i<10; i++){
}
i //=> ?
#16.答え
letとvarの違いはこちらを参照。letとvarの違い
##第1問
let i = 1;
for(i=0; i<10; i++){
}
i //=> 10
##第2問
let i = 1;
for(let i=0; i<10; i++){
}
i //=> 1
##第3問
for(let i=0; i<10; i++){
}
i //=> Uncaught ReferenceError: i is not defined
#17.問題「this参照1」
var obj = {
x:3,
doit: function(){ console.log("method is called." + this.x); }
}
obj.doit(); //=> method is called.3
var fn = obj.doit;
var x = 5;
fn(); //=> ?
#17.答え
var obj = {
x:3,
doit: function(){ console.log("method is called." + this.x); }
}
obj.doit(); //=> method is called.3
var fn = obj.doit;
var x = 5;
fn(); //=> method is called.5
#18.問題「this参照4」
var x = 1;
var obj3 = {
x:3,
doit3: function(){ console.log("method is called." + x); }
}
obj3.doit3(); //=> ?
#18.答え
var x = 1;
var obj3 = {
x:3,
doit3: function(){ console.log("method is called." + x); }
}
obj3.doit3(); //=> method is called.1
あとがき
これらのクイズを出した時に、
修正箇所をしてくださった皆さま、
編集リクエストをくださった皆さま、
いいねをしていただいた皆さま、
ありがとうございました。