(.+)\<\/div\>/.exec(div)[1])
divarray
//['about me']
```
**問224**
WIP
```js
var i = 0;
var array = [];
do {
array.push(Math.pow(2,i));
i += 1;
} while(i < 10);
```
**問225**
1980年8月1日5時55分を表すDateオブジェクトを生成してください
```js
var d = new Date('1980/8/1 5:55');
//Fri Aug 01 1980 05:55:00 GMT+0900 (JST)
```
**問226**
上で作成した日時を現地フォーマットで出力してください
```js
var d = new Date('1980/8/1 5:55');
d.toLocaleString();
//'2008/7/1 5:55:00'
//標準フォーマット
d.toStoring();
//'Tue Jul 01 2008 05:55:00 GMT+0900 (JST)'
```
**問227**
WIP
上で作成した時間を現地フォーマットで出力してください
```js
var d = new Date('1980/8/1 5:55');
d.toLocaleTimeString();
//'5:55:00'
//標準フォーマット
//'05:55:00 GMT+0900 (JST)'
```
**問228**
var ary = ['aaa', 'bbb', 'ccc'];に文字列'eee'を先頭に追加してください
```js
var ary = ['aaa', 'bbb', 'ccc'];
ary.unshift('eee');
//4
ary
//['eee', 'aaa', 'bbb', 'ccc']
```
**問229**
こちらの変数を使って
var ary = [0, 1, 2, 3 , 4, 5, 6, 7, 8, 9, 10];
2でも3でも割り切れない数を抽出した配列を生成してください
```js
var ary = [0, 1, 2, 3 , 4, 5, 6, 7, 8, 9, 10];
var newAry = ary.filter(function(elem){
if (elem % 3 !== 0 && elem % 2 !== 0){
return elem
}
});
newAry
//[1, 5, 7]
```
**問230**
ビルドインプロパティを3つ答えなさい
```js
Infinity
NaN
undefined
//グローバルオブジェクトに定義されているプロパティ
//ビルドインオブジェクトとは異なり、参照する際にオブジェクトを指定せずにプロパティ名を記述するだけ
```
**問231**
ビルドイン関数を9つ挙げてください
```js
decodeURL(str)
decodeURIComponent(str)
encodeURI(str)
encodeURIComponent(str)
eval(codeStr)
isFinite(num)
isNaN(value)
parseFloat(str)
parseInt(str,[radix])
```
**問232**
こちら
encodeURIComponenとencodeURIの違いを教えてください
```js
const url = 'https://tools.ietf.org/html/rfc2822#page-14';
encodeURIComponent(url)
//'https%3A%2F%2Ftools.ietf.org%2Fhtml%2Frfc2822%23page-14'
(;、 :、 /、 @、?、 &、 %、 $、 #、 =、 + 、 ,)はエンコードしない
encodeURI(url)
//'https://tools.ietf.org/html/rfc2822#page-14'
```
**問233**
```var s = 'aaa,bbb,ccc,ddd';```
を使って、,を/に置換した文字列```aaa/bbb/ccc/ddd```を出力してください。ただしreplaceメソッドは使用しないこととする
```js
while (s.indexOf(',') >= 0){
s = s.replace(',','/');
}
s
//'aaa/bbb/ccc/ddd'
※splitとjoinを使って生成する方法もあります
```
**問234**
下の変数sにある
```var s = 'aaa
bbb
ccc
ddd
eee';```
divの中にあるtextを全て出力してください
```js
var s = 'aaa
bbb
ccc
ddd
eee';
var divStringAry = [];
var regexp = /
.*?<\/div>/g;
var result = regexp.exec(s);
while(result != null){
var divStr = result[0]
divStr = divStr.substring('
'.length,
divStr.length - '
'.length);
divStringAry.push(divStr);
result = regexp.exec(s);
}
divStringAry
//['bbb', 'ddd']
divStringAry.join('\n')
//'bbb
//ddd'
```
**問235**
2の0乗〜10乗までを格納した配列を作成してください。インデックスはそれぞれ指数(0〜10)となるようにしてください
```js
var ary = [];
var i = 0;
do {
ary[i] = Math.pow(2, i);
i += 1;
} while(i <= 10);
ary
//[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
//別解
var ary = [];
for(var n = 0; n <= 10; n++){
ary[n] = Math.pow(2, n);
}
```
**問236**
今年の各月の最終日を配列に格納してくださいl。インデックスは各月と一致する数値とする。
```js
var ary = [];
var temp = new Date();
for (var i = 1; i <= 12; i++){
var d = 28;
temp.setMonth(i - 1, d);
while(temp.getMonth() == i - 1){//次の月になるまでroop
d++;
temp.setDate(d);
}
ary[i] = d -1; //次の付きになる直前の日付を配列に設定
}
ary
//[undefined × 1, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
//DateオブジェクトのsetDate()に日付を設定したさい、実際の日付より大きい数値を設定した場合は自動的に繰り上げられる
例えば1月のDateオブジェクトに対してsetDate(32)とすると自動的に2月1になる。その性質を利用する
```
**問237**
同一制限ポリシー(Same-Origin-Policy)の制限を受けるものを4つ答え、またオリジンを参照してください
```js
see : https://tools.ietf.org/html/rfc6454
・XMLHttpRwquest
・Canvas
・WebStorage
・X-Frame-Options
location.origin
document.origin
//制限を受けないものには
//Cookie
//HTTP認証
//document.domainを書き換えてのinnerHTMLの読み書き
//以下はlocationプロパティ
//例: http://www.google.com:80/search?q=devmo#test
host - www.google.com:80
hostname - www.google.com
href - http://www.google.com:80/search?q=devmo#test
pathname - /search (ホストからの相対)
protocol - http:
search = ?q=devmo
hash - #test
//用語
スキーム : http,https
同一オリジン : スキーム,ホスト,ポートが同じこと
クロスオリジン : 上記がいずれか一つでも違うこと
セッションハイジャック : サーバーから渡されるセッションIDを盗み正規ユーザーになりすますこと
```
**問238**
location.assignとlocation.replaceの違いを教えてください
```js
//replaceは画面遷移をWebブラウザの履歴に残さず遷移する
```
**問239**
Object.creteを使ってPersonのにthis.nameとthis.jobを参照して「'my name is' + this.name + '。' + '職業は' + this.job + 'です'」を出力するインスタンスメソッド「say」のみを持ち、それを継承してnameを自身のプロパティとして持つkenjiと、
kenjiを継承しjobを自身のプロパティとしてもつcompKenjiを作成して
```my name is morita。JavascriptEngneer``を出力してください、
```js
var Person = {
say: function(){
console.log('my name is' + this.name + '。' + '職業は' + this.job + 'です');
}
}
var kenji = Object.create(Person, {name :{value: 'kenji' }});
var compKenji = Object.create(morita, {job: {value: 'JavascriptEngneer'}});
compKenji.say()
'my name is morita。JavascriptEngneer'
//Object.crete()
第一引数・・・プロトタイプとなるべきobject
第二引数・・・省略可能。列挙可能なown property(プロパティ記述子を指定。あらたなobjectのプロパティに追加される。Object.definePropertyesの第二引数に対応するところ)
第一引数で渡されるObjetcが、内部で生成されるF.prototypeに割り当てられてnew F()とされた新たなinstanceが返される
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/create
```
**問240**
Object.createメソッドで以下と同じ記述をしてください。
```js
function Constructor(){}
o = new Constructor();
```
```js
o = Object.create(Constructor.prototype);
```
**問241**
```var o = Object.create({},{p: {value: 32}});```
を書き換えtrue、列挙true、変更trueとして新たにオブジェクトを生成してください。
```js
o2 = Object.create({},{p: {value: 32, writable: true, enumerable: true, configurable: true}});
書き換え
o2.p = 54;
//54
列挙
for (var prop in o2){
console.log(prop)
}
//p
変更
delete o2.p
//true
```
**問242**
Object.createとObject.definePropertyesとObject.definePropertyの引数、返り値を教えてください。
```js
//Object.create
//第一引数に任意のオブジェクトのprototypeを渡し、第二引数に自身がもつプロパティディスクリプタを定義し、それを継承したインスタンスを返す.
//Object.defineProperty
Object.defineProperty(プロパティをsetする対象オブジェクト, プロパティ/関数名, {パラメータ, ...});
「一度作ったオブジェクト」に特別な内部属性をもったプロパティを1つ定義する//返り値は第一引数で渡ってきて再定義されたオブ稀有と
第二引数はpropety名、第三引数は定義したいディスクリプタをハッシュオブジェクトとして渡す
既存のプロパティは上書き
各種設定のdefaultはfalse
//Object.definePropertes
Object.defineProperty(プロパティをsetする対象オブジェクト,{プロパティ/関数名{パラメータ, ...}});
「一度作ったオブジェクト」に新たなプロパティを複数の定義できる
第二引数はpropertyeのキーとしてディスクリプタを持つオブジェクト
既存のプロパティは上書き
※プロパティの内容=デスクリプタ
```
**問243**
let n = '124';を数値に変換してください。
```js
let n = '124';
+n
//124
let n = '';
n
//0
//parseInt(n, 10)はから文字だとNaNが返るがこちらの方法は必ず数値が返る
```
**問244**
こちらの評価は
```
var n = {value: 0};
if(n.value){
//something
}
```
value値が0にもかかわらずfalseが返ります。(valueが空文字でもfalse)
nullやundefinedの場合のみfalseが返るような条件式にしてください
```js
if(n.value != null){//something}
```
**問245**
オブジェクトの存在チェックをしてあったら実行している。
```js
var o = {f: function(){console.log('JS')}};
if(o){
if(o.f){
o.f();
}
}
```
より端的な記述をしてください。
```js
var o = {f: function(){console.log('JS')}};
o && o.f && o.f();
//同じ様なイデオムで代入の際に括弧でくくらないとエラーが起きることに注意してください
//o && o.options && o.options.players > 50 && (flag = true);
```
**問246**
```var v```の値を確実に数値にしたい。
'a'が入ってきた場合NaNではなく0を代入するようにしてください。
```js
var n = +v || 0;
```
**問247**
```var v ```を整数化してください
```js
var i = v | 0;
```
**問248**
下の様な場合、
```js
var insEmp1 = new Emp();
var insEmp2= new Emp();
insEmp2.name = "kenji";
insEmp2.name;
//"kenji"
insEmp1.name;
//undefined;
//更新されない
```
Empがnameを持っていない場合Emp1は即座に更新されない。
プロトタイプからプロパティを継承する全オブジェクトにそのプロパティ(name)を値("kenji")を追加してください。
```js
function Emp(){};
var insEmp1 = new Emp();
var insEmp2 = new Emp();
Emp.prototype.name = "kenji";
insEmp1.name
//"kenji";
insEmp2.name
//"kenji"
```
**問249**
ObjectとMapの違いを教えてください
```js
・Objectのkeyはstring型、Mapは任意の型を指定できる
・Objectのsizeは手動で調べる必要がある、MapはMap.size()
・Objectの反復は順番を保証しない,Mapの反復は要素の挿入順
・Objectはデフォルトでプロパティを持つ(var map = Object.create(null)で回避できる)
//ObjectかMapか、使うべきところ
//Mapを使う
・実行時までキーが不明な時、全てのkeyが同じ型の時、全ての値が同じ型の時、
//Objectを使う
・個々の要素に操作できるロジックがある時、
参照
http://programmers.stackexchange.com/questions/285881/any-point-in-using-es6-map-when-keys-are-all-strings
http://stackoverflow.com/questions/18541940/map-vs-object-in-javascript
Object:
var o = {};
var o = Object.create(null);
o.key = 1;
o.key += 10;
for(let k in o) o[k]++;
var sum = 0;
if('key' in o);
if(o.hasOwnProperty('key'));
delete(o.key);
Object.keys(o).length
Map:
var m = new Map();
m.set('key', 1);
m.set('key', m.get('key') + 10);
m.foreach((k, v) => m.set(k, m.get(k) + 1));
for(let k of m.keys()) m.set(k, m.get(k) + 1);
var sum = 0;
for(let v of m.values()) sum += v;
if(m.has('key'));
m.delete('key');
m.size();
```
**問250**
破壊的なメソッドをあげてください
```js
pop、push、reverse、shift、sort、splice、unshilft
```
問251〜問300
**問251**
```var arr = ['one', 'two', 'three']```においてarrを不変オブジェクトに変更してください。
```js
var arr = ['one', 'two', 'three']
Object.freeze(arr);
arr.sort();
//Uncaught TypeError: Cannot assign to read only property '1' of object '[object Array]'
//ex
const obj = Object.freeze({a: 1});
obj.x = 4;
//strict-modeだとエラーになるが、そうではない場合、代入はなかったものとされる
console.log(obj)
//{a: 1}
//ex2
//「子供」までは面倒みない
var obj2 = Object.freeze({a: 1, b : {a: 2}})
obj2.b.a = 4
console.log(obj2.b.a);
//4
//ex3
//子供も凍結させる
var obj3 = Object.freeze({a: 1, b: Object.freeze({a: 2})})
obj3.b.a = 4
console.log(obj3.b.a)
//2
```
**問252**
このようなobjがあります。
```js
var obj = {
'prop1': 'value1',
'prop2': 'value2',
'prop3': 'value3'
}
```
JSON.stringifyを使って
```
"{
"prop1": "value1",
"prop2": "value2"
}"
```
ように出力されるようにしてください(prop3が出力されていない。1タブ分インデントされていることに注意)
```js
var obj = {
'prop1': 'value1',
'prop2': 'value2',
'prop3': 'value3'
}
var str = JSON.stringify(obj, ['prop1', 'prop2'], '\t');
str
//
"{
"prop1": "value1",
"prop2": "value2"
}"
//ex
関数で出力を
function selectedProperties(key, val) {
// the first val will be the entire object, key is empty string
if (!key) {
return val;
}
if (key === 'prop1' || key === 'prop2') {
return val;
}
return;
}
var str = JSON.stringify(obj, selectedProperties, '\t');
str
//
{
"prop1": "value1",
"prop2": "value2"
}
```
**問253**
this呼び出しを4つとそれぞれのthis参照の参照先オブジェクトを答えてください
```js
・コンストラクタ呼び出し・・・コンストラクタが生成したオブジェクト
・メソッド呼び出し・・・レシーバオブジェクト(ドット演算子、ブラケット演算子でオブジェクトのメソッドを読んだとき、演算子の左辺に指定したオブジェクト)
e.g const obj = {add : function(){some}};
メソッドの呼び出し対象のオブジェクトがレシーバオブジェクト、この場合obj、addがメソッド
・apply,call呼び出し・・・apply、callの引数で指定したオブジェクト
※呼び出されたメソッドがnon strict modeの場合fn.apply(obj,[1,3])のobjがnullもしくはundefinedの場合グローバルオブジェクトに置き換えられプリミティブ型の変数はボックス化されます。
・それ以外の呼び出し ・・・グローバルオブジェクト
//this参照はコードのコンテキストに応じて自動的に参照先オブジェクトが変わる特別なもの
```
**問254**
var obj = { foo: 'bar', baz: 42 }; をMapオブジェクトに変換してください
```js
var obj = { foo: 'bar', baz: 42 };
var map = new Map(Object.entries(obj));
console.log(map); // Map { foo: 'bar', baz: 42 }
```
**問255**
```js
var Emiiter = {
callbacks : [],
register : function(fn){
this.callbacks.push(fn);
},
onOpen : function(){
this.callbacks.forEach(function(fn){
fn();
})
},
}
Emiiter.register(function(){console.log('1')});
Emiiter.register(function(){console.log('2')});
```
**問256**
こちらはcolorの条件でそれぞれの関数を実行する記述です。
```js
var color = "black";
function printBlack(){
console.log('black')
}
function printRec(){
console.log('red')
}
function printBlue(){
console.log('blue')
}
function printYellow(){
console.log('yellow')
}
if(color){
if (color === 'black') {
printBlack();
} else if (color === 'red'){
printRed();
} else if (color === 'blue'){
printBlue();
} else if (color === 'yellow'){
printYellow()
}
}
```
これをswitch文に変えたのがこちらですが、
```js
switch (color){
case 'black':
printBlack();
break;
case 'red':
printRed();
break;
case 'blue':
printBlue();
break;
case: 'yellow'
printYello();
}
```
デバッグしづらいのといくつかの評価をしなくてはならなくなった際につらくなります。
see: [https://toddmotto.com/deprecating-the-switch-statement-for-object-literals/](https://toddmotto.com/deprecating-the-switch-statement-for-object-literals/)
```js
switch(true) {
case (typeof color === 'string' && color === 'black'):
printBlack();
break
・
・
・
}
```
可能な限りswitch文を使用しないようにするためオブジェクトを介して上記のようにcolorに合った関数を実行してください
```js
var color = "black";
function printBlack(){
console.log('black')
}
function printRed(){
console.log('red')
}
function printBlue(){
console.log('blue')
}
function printYellow(){
console.log('yellow')
}
var colorObj = {
'black': printBlack,
'red': printRed,
'blue': printBlue,
'yellow': printYellow
};
if (color in colorObj) {
colorObj[color]();
}
//black
```
**問257**
こちら['a','b','c’]をこちら{0: 'a’, 1: 'b’, 2: 'c'}のようにしてください
```js
function toObject(arry){
var obj = {};
for(var i = 0; i < arry.length; i++){
obj[i] = arry[i];
}
return obj
}
toObject(arry);
//{0: 'a', 1: 'b', 2: 'c'}
```
**問258**
こちら
```js
let html = '';
const count = 10;
for(var i = 0;i < count; i++){
html += 'hai!!';
}
document.querySelector('#mngb').innerHtml = html;
'hai!!hai!!hai!!hai!!hai!!hai!!hai!!hai!!hai!!hai!!'
```
をより高速な書き方をしてください
```js
var html = [];
var count = 10;
for(var i = 0; i < count; i++){
html.push('hei!!');
}
document.querySelector('#mngb').innerHtml = html.join('');
'hei!!hei!!hei!!hei!!hei!!hei!!hei!!hei!!hei!!hei!!'
//+=より、配列に追加してjoinを使った方が高速
```
**問259**
このような関数があります
```js
function iterateTimerOver(){
const length = 100;
for (let i = 0; i < length; i++){
Timer();
}
}
```
Timerはグローバル関数です。より高速にしてください。
```js
//Timerの参照をローカル変数にポイントさせて、スコープがループの数だけグローバルまで辿らないようにしています。
function iterateTimerOver(){
const funcTimer = Timer;//参照を代入
const length = 100;
for (let i = 0; i < length; i++){
funcTimer();
}
}
//他にも
//forループの改善
for (i = 0; i < elements.length; i++) {
}
↓
//const length = elements.length;
for (i = 0; i < length; i++) {
}
//以後、何度も参照するObjectへポイント変数
this.propsはこのようなオブジェクトだとします
{name: 'ken', sex: 'man', 'age': 19, 'live': 'shibuya'}
const {name, sex, age, live} = this.props;
name
//ken
```
**問260**
こちら
```js
const myObject = {1: ['e', 'ee', 'eee'], 2: ['f', 'ff','fff']};
```
を
多次元配列にしてください
期待する結果:[[‘e’,’ee’,’eee’],[‘f’,’ff’, ‘fff’]];
```js
const myObject = {1: ['e', 'ee', 'eee'], 2: ['f', 'ff','fff']};
const newArr = Object.keys(myObject).map(function(elem){
return myObject[elem]
})
//[[‘e’,’ee’,’eee’],[‘f’,’ff’, ‘fff’]]
//other
const myObject = {1: ['ee', 'eee', 'efe'], 2: ['faf', 'fafa','fa']};
const arr = Object.values(myObject);
//※Object.values(ECMAScript2017)を使える環境で(Polyfill: es-shims/Object.values,tc39/proposal-object-values-entries)で
```
**問260**
こちら
```['a','b','c’] → {0: 'a’, 1: 'b', 2: 'c'}```
のように、インデックスをキーにして、配列要素をそれぞれの値となるようにしてください
```js
//1
const arry = ['a', 'b', 'c'];
function toObject(arry){
const obj = {};
const len = arry.length;
for(let i=0; i < len; i++){
obj[i] = arry[i]
}
return obj
}
toObject(arry)
//{0: 'a', 1: 'b', 2: 'c'}
//2
const arry = ['a', 'b', 'c'];
const obj = arry.reduce(function(o, v, i){
o[i] = v;
return o;
},{})
obj
//{0: 'a', 1: 'b', 2: 'c'}
//3
[{a: 1},{b: 3}].reduce(function(result, item){
var key = Object.keys(item)[0]
result[key] = item[key];
return result;
},{})
//{a: 1, b: 3}
```
**問261**
こちら
```js
const arr = [
{ key: 'foo', val: 'bar' },
{ key: 'hello', val: 'world' }
];
```
をMapオブジェクトにしてください
期待する結果:{'foo' => 'bar', 'hello' => 'world'}
```js
const arr = [
{ key: 'foo', val: 'bar' },
{ key: 'hello', val: 'world' }
];
const result = new Map(arr.map((i) => [i.key, i.val]));
console.log(result);
// Map {'foo' => 'bar', 'hello' => 'world'}
```
**問262**
こちら
```js
const characters = ['b', 'd', 'a', 'c'];
const sortedCharacters = characters.sort()
sortedCharacters
//['a', 'b', 'c', 'd']
sortedCharacters === characters
//true
```
配列をsortした返り値は同じオブジェクトを参照します。
sortをした上で新しい配列を返すようにしてください。
```js
const characters = ['b', 'd', 'a', 'c'];
const sortedCharacters = characters.slice().sort();
sortedCharacters === characters
//false
```
**問263**
ジェネレーター関数を使って1ずつ値を出力してください。
```js
var generatorFunction = function* (){
var i = 0;
while (true) {
yield i ++;
}
}
var iterator = generatorFunction();
iterator.next().value;
//0
iterator.next().value;
//1
```
**問264**
generator関数がyieldの完了まで前進したら'finish'という文字列を返してください
```js
var gen = function* (){
yield 'foo';
return 'finish';
}
var iterator = gen();
iterator.next();
//'foo'
iterator.next();
//'finish'
```
**問265**
数値1から3までの値を返すgenarator関数で生成されたiteratableをfor-of文に使い値を出力してください。(その際for-of文での戻り値を捨てていることを確認してください。)
```js
var fun = function * (){
yield 1;
yield 2;
yield 3;
return 4;//for-of文では捨てられる
}
var iterator = fun();
for(index of iterator){
console.log(index)
}
//1
//2
//3
```
**問266**
3つのgenerator関数、foo,bar,bazはそれぞれ関数名の文字列をyield operatorに持ち、fooは次の処理をbarに代理させて、barは次の処理をbaz、それぞれyield値で実行するように定義してください。さらにfor-of文で'foo','bar','baz'と連続で出力してください。
```js
let index;
const foo = function * (){
yield 'foo';
//Delegating yield
yield * bar();
}
const bar = function * (){
yield 'bar';
yield * baz();
}
const baz = function * (){
yield 'baz';
}
for (index of foo()){
console.log(index);
};
//'foo'
//'bar'
//'baz'
```
**問267**
値が'a'ならgenerator関数内のtry-catch内で値をバックアップ、'b'なら呼び出し元で例外を発生させるgenerator関数を定義してください。
```js
var generatorFunction = function * (){
while (true){
try {
yield;
} catch (e){
if(e != 'a') {
throw e;
}
console.log('generator caught', e);
}
}
};
var iterator = generatorFunction();
iterator.next();
try {
iterator.throw('a');
iterator.throw('b');
} catch (e) {
console.log('Uncaught', e);
}
//generator caught a
//Uncaught b
```
**問268**
こちらの
```js
const foo = (name, callback) => {
setTimeout(() => {
callback(name);
}, 100);
};
foo('a', (a) => {
foo('b', (b) => {
foo('c', (c) => {
console.log(a, b, c);
});
});
});
// a
// b
// c
```
ネストされた読みにくい処理記述をgenerator関数を使って記述し直してください。
```js
const foo = (name, callback) => {
setTimeout(() => {
callback(name);
}, 100);
};
const curry = (method, ...args) => {
return (callback) => {
args.push(callback);
return method.apply({}, args);
};
};
const controller = (generator) => {
const iterator = generator();
const advancer = (response) => {
var state;
state = iterator.next(response);
if (!state.done) {
state.value(advancer);
}
}
advancer();
};
controller(function* () {
const a = yield curry(foo, 'a');
const b = yield curry(foo, 'b');
const c = yield curry(foo, 'c');
console.log(a, b, c);
});
// a
// b
// c
```
**問269**
ジェネレーター関数barを実行して、返り値のiteratorが持つnext()すると、
1,2回目はvalue値がそれぞれ1,2。
3,4回目はfooが実行してそれぞれ3,4とするようにして、
4回目はさらに'z: Z, w: W'をコンソール出力。
5回目はbarが5。
6回目はvalueはundefined。文字列で'x: X, y: Y, v: V'を出力してください。
```js
function *foo() {
const z = yield 3;
const w = yield 4;
console.log( 'z: ' + z + ', w: ' + w );
}
function *bar() {
const x = yield 1;
const y = yield 2;
yield *foo(); // `yield*` delegates iteration control to `foo()`
const v = yield 5;
console.log( 'x: ' + x + ', y: ' + y + ', v: ' + v );
}
const it = bar();
it.next(); // { value:1, done:false }
it.next( 'X' ); // { value:2, done:false }
it.next( 'Y' ); // { value:3, done:false }
it.next( 'Z' ); // { value:4, done:false }
it.next( 'W' ); // { value:5, done:false }
// z: Z, w: W
it.next( 'V' ); // { value:undefined, done:true }
// x: X, y: Y, v: V
```
**問270**
generatorを作成してimgタグのsrc属性が1~7.pngを参照するようにしてそれぞれ格納した配列を作ってください。
```js
function * ge (from, to){
while(from <= to) yield from++
}
const create = function(i){
return `
`;
}
const arry = [];
for(var i of ge(1,7)){
arry.push(create(i))
}
```
**問271**
for-ofに渡すと1~10までの数値を返すitarableなオブジェクトを自作してください。
```js
var obj = {}; // イテラブルなオブジェクト
obj[Symbol.iterator] = function(){//イテレータを返す関数を代入
var iterator = {}; // イテレータ
var num = 1;
iterator.next = function(){//next実行してリザルトを返す関数を代入
var iteratorResult = (num <= 10)
? { value: num++, done: false }
: { value: undefined, done: true };
return iteratorResult; // イテレータリザルトを返す
};
return iterator;//イテレータを返す
};
```
**問272**
こちらの
```js
function* g(){
const num = yield 30
const num2 = yield 1 + num
yield 2 + num2
yield num + num2
}
```
iteratorのnextメソッドに1を渡してdoneがtrueになるまで```iterator.next(1).value```のように実行していくとそれぞれ何を返すか答えてください。
```js
function* g(){
const num = yield 30//numは2回目next()実行時の仮引数になる
const num2 = yield 1 + num//num2は3回目next()実行時の仮引数になる
yield 2 + num2
yield num + num2
}
const iterator = g();
iterator.next(1).value
//30
iterator.next(1).value
//2
iterator.next(1).value
//3
iterator.next(1).value
//2
iterator.next(1).value
//undefined
```
**問273**
こちらの`foo`を
```js
function* foo(x) {
var y = 2 * (yield (x + 1));
var z = yield (y / 3);
return (x + y + z);
}
var it = foo(5);
it.next();//1
it.next(12);//2
it.next(13);//3
```
上の1,2,3の箇所のように実行したら出力される値をそれぞれ教えてください
```js
function* foo(x) {
var y = 2 * (yield (x + 1));
var z = yield (y / 3);//2回目で返すのはyield式の結果までで結果はzに代入されない//3回目のnext引数がzに入る
return (x + y + z);
}
var it = foo(5);
it.next();
//{value: 6, done: false}
it.next(12);
//{value: 8, done: false}
it.next(13);
//{value: 42, done: true}
```
**問274**
1秒毎に1加算した値をコンソール出力してください。
```js
//increment, delegate
function * countUp(start = 0){
while(true){
start++;
yield* display(start)//Delegating Generators
}
}
//描画
function * display(start){
console.log(+start);
yield;
}
//controller
function run(generatorObject){
if(!generatorObject.next().done){
setTimeout(()=>{
run(generatorObject)
}, 1000)}
}
run(countUp());
```
**問275**
location.href'で返す文字列先頭が'http'から始まる場合trueを返す関数を定義してください。
```js
location.href.startsWith('http');
```
**問276**
location.href'で返す文字の最後が'/'かどうかを判定する関数を定義してください。
```js
location.href.endsWith('/');
```
**問277**
Symbolをプロパティキーとして認識する操作と無視する操作を教えて下さい。
```
//認識
Reflect.ownKeys()
Property access via []
Object.assign()
//無視
Object.keys()
Object.getOwnPropertyNames()
for-in loop
```
**問278**
こちらを実行すると
```js
const sym = Symbol('desc');
const str1 = '' + sym;
str1
//???
```
どうなりますか?
```
const sym = Symbol('desc');
const str1 = '' + sym; //TypeError
const str2 = `${sym}`; //TypeError
//Symbolに対して強制的な型変換をするとTypeErrorがスローされます。
```
**問279**
シンボルのユースケースをざっくり2つほど教えて下さい。
```js
//1
//unique property keys (ユニークなプロパティkey)
//for-ofを通して使えるobject iterableを作ることができる
const iterableObject = {
[Symbol.iterator]() { // メソッドのキーとしてSymbolを使う
const data = ['hello', 'world'];
let index = 0;
return {
next() {
if (index < data.length) {
return { value: data[index++] };
} else {
return { done: true };
}
}
};
}
}
for (const x of iterableObject) {
console.log(x);
}
//hello
//world
上記の"unique maker"はオブジェクトリテラブルを作り、for-ofループで使うことができる
//2
//constants representing concepts (概念を表す定数)
//ES5では定数を文字列として表現していたが
//シンボルを使うことでそれらは常にユニークになる。
const COLOR_RED = Symbol('Red');
const COLOR_ORANGE = Symbol('Orange');
const COLOR_YELLOW = Symbol('Yellow');
const COLOR_GREEN = Symbol('Green');
const COLOR_BLUE = Symbol('Blue');
const COLOR_VIOLET = Symbol('Violet');
function getComplement(color) {
switch (color) {
case COLOR_RED:
return COLOR_GREEN;
case COLOR_ORANGE:
return COLOR_BLUE;
case COLOR_YELLOW:
return COLOR_VIOLET;
case COLOR_GREEN:
return COLOR_RED;
case COLOR_BLUE:
return COLOR_ORANGE;
case COLOR_VIOLET:
return COLOR_YELLOW;
default:
throw new Exception('Unknown color: '+color);
}
}
```
**問280**
こちらは
```js
let target = {name: 'ken'}
try {
Object.defineProperty(target, 'name', {value: 'fe'})
//do something
} catch(e){}
```
targetが再定義できる場合name値を変更して「何か」をしようとしている。
これはObject.definePropertyが成功した際はObjectを返し、失敗したときは
TypeErrorをthrowするので、try/catchしているのだが、
if...elseブロックを使える、Reflectを用いて同じ実装になるように修正してください
```js
let target = {name: 'ken'}
const isAble = Reflect.defineProperty(target, 'name', {value: 'fe'})
if(isAble){
//do something
} else {}
```
**問281**
こちらの
delete target['key']
と同じことをReflectのAPIを使って行ってください。
```
Reflect.deletePropery(target, 'key')
```
**問282**
こちらはReflect.getを使って
```js
var obj = {a : 1}
Reflct.get(obj, "a")
//1
```
値を取得している。
```js
obj["a"]
//1
```
との違いを教えてください
```js
//objが非オブジェクトの際、ReflectはTypeErrorをthrowしますが、obj["a"]は
//undefinedになります。実行時objの型が適切か気づくことができます。
e.g
var obj = 1;//オブジェクトが入ってくる想定のobjにプリミティブ型を代入
Reflect.get(obj, 1)
//Uncaught TypeError: Reflect.get called on non-object
obj[1]
//undefined
```
**問283**
Reflect.applyとはどのようなものですか。
```js
//このようにthis.を参照するfun関数を引数を伴って使う必要がある場合、
var ctx = {
num : 5
}
function fun (a, b, c){
return a + b + c + this.num
}
fun.apply(ctx, [1,2,3])
//11
//これだとfunがapplyをプロパティとして持っているかわからない場合怖い。
//例
function fn (a, b, c) {
return a + b + c + this.num
}
fn.__proto__ = null;//意図しない代入でapplyまで辿れなくなった
fn.apply(ctx, [1,2,3])
//Uncaught TypeError: fn.apply is not a function(…)
//より安全に呼ぶ
//関数が Function.prototype を継承していなくとも TypeError を発生させない
Function.prototype.apply.call(fun, ctx, [1,2,3])
//11
//ただ上記は安全だが冗長な書き方になる。
//もしthisコンテキストを通して定義する必要があり、書き方をスッキリしたいなら
Reflect.apply(fun, ctx, [1,2,3])
//11
```
**問284**
こちら
```js
String.fromCharCode(104,101,108,108,111)
"hello"
```
String型の静的メソッドであるfromCharCodeは常にStringを伴って呼ぶ必要がある。
また返り値はString型ではなく文字列です。
Number型を渡さなくてはいけない引数に配列を渡し、
同じ出力になるようにしてください
```js
Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111])
//"hello"
```
**問284**
p.aにアクセスしたら1を返し、存在しないプロパティにアクセスしたら37を
返すオブジェクトを作成してください
期待する結果
p.a
//1
p.c(cは設定されていない任意のプロパティ)
//37
```js
var handler = {
get: function(target, name){
return name in target ? target[name] : 37
}
}
var p = new Proxy({}, handler);
p.a = 1
p.a
//1
p.c
//37
```
**問285**
{a: 1}がprototype上に'toString'持っているかBoolean値を出力してください
```js
Reflect.has({a: 1}, 'toString');
//true
```
**問286**
Errorオブジェクトのインスタンスにmessageとして"エラーが発生しました"を代入エラーをthrowしてください
```
var err = new Error();
err.message = "エラーが発生しました"
throw err
//other
throw new Error("エラーが発生しました。");
```
**問287**
obj.aに数値以外のものが代入されるとsetterでErrorを投げ、number型ならaに代入。getterはaを返すobjを作ってください。
```js
var obj = {
_a : 0,
get a(){return this._a; },
set a(n){
if(typeof n === "number"){
this._a = n;
} else {
throw new Error("代入できません")
}
}
};
```
**問288**
このようながDOMがあります。
```html
foo
```
付与されたclass名が存在するだけ出力してください。
期待する出力
//'bar'
//'baz'
```js
var foo = document.getElementById('foo');
for(var i = 0; i < foo.classList.length; i++) {
console.log(foo.classList[i]);
}
//'bar'
//'baz'
//classListはDOMTokenListのオブジェクト
//http://www.javascripture.com/DOMTokenList
//対応ブラウザバージョン
//http://caniuse.com/#feat=classlist
//ex 使えるか判定をして加える
if (el.classList)
el.classList.add(className);
else
el.className += ' ' + className;
```
**問289**
こちら
```html
foo
```
の中にbazがあることを真偽値で出力してください
```js
var foo = document.getElementById('foo');
foo.classList.contains('foo');
//対応ブラウザバージョン
//http://caniuse.com/#feat=classlist
```
**問290**
こちら
```html
foo
```
にfafaというclass名を追加してbarを削除してください
```js
var foo = document.getElementById('foo');
foo.classList.add('fafa');
foo.classList.remove('bar');
//対応ブラウザバージョン
//http://caniuse.com/#feat=classlist
```
**問291**
こちら
```js
$.getJSON('/my/url', function(data) {
});
```
Jqueryでgetしているが、ライブラリを使用しないのでJS記述してください。
```js
//一例
const request = new XMLHttpRequest();
request.open('GET', '/my/url', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
const data = JSON.parse(request.responseText);
} else {
// We reached our target server, but it returned an error
}
};
request.onerror = function() {
// There was a connection error of some sort
};
request.send();
```
**問292**
var data = { foo: 'abc', bar: 100 }
このようなdataをPOSTで送れるようにしてください
期待する結果
'foo=abc&bar=100'
```js
let arr = [];
Object.keys(data).forEach(function(el, ind){
arr.push(encodeURIComponent(el) + "=" + encodeURIComponent(data[el]))
})
const str = arr.join("&")
str
//'foo=abc&bar=100'
```
**問293**
こちら
```js
$(selector).each(function(i, el){
something...
});
```
と同じ処理をJSで記述してください
```js
var elements = document.querySelectorAll(selector);
Array.prototype.forEach.call(elements, function(el, i){
something...
});
```
**問294**
こちら
```js
$(el).after(htmlString);//1
$(el).before(htmlString);//2
$(el).children(); //3
$(el).next();//4
$(el).parent();//5
```
と同じ動きをJSで記述してください
```js
//1
parent.appendChild(el);
//2
el.insertAdjacentHTML('beforebegin', htmlString);
//3
el.children
//4
el.nextElementSibling
//5
el.parentNode
```
**問295**
こちら
```js
$(el).hasClass(className);
```
と同じ処理をJSで記述してください
```js
var el = document.getElementById('container')
if (el.classList){
el.classList.contains(className);
} else {
new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
}
```
**問296**
こちらの2つの処理
```js
$(el).next();
$(el).parent();
```
と同じことをJSで記述してください
```js
var el = document.getElementById('container')
el.nextElementSibling
el.parentNode
```
**問297**
こちら
```js
$(el).offset();
//{top: 11, left:11}
```
と同じ値を含むオブジェクトを取得できるようにJSで記述してください。
```js
var rect = el.getBoundingClientRect();
rect
//{top:11, height:11, left:11, right:11, bottom:11, width:11}
```
**問298**
こちら
```js
$(el).remove();
```
と同じ処理をするようにJSで記述してください。
```js
el.parentNode.removeChild(el);
```
**問299**
こちら
```js
$(el).removeClass(className);
```
と同じ処理をするようにJSで記述してください。
```js
if (el.classList) {
el.classList.remove(className);
} else {
el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
```
**問300**
こちら
```js
$(el).attr('tabindex', 3);
```
と同じ処理をするようにJSで記述してください。
```js
el.setAttribute('tabindex', 3);
```
問301〜問350
**問301**
こちら
```js
$(el).toggleClass(className);
```
と同じ処理をするようにJSで記述してください。
```js
if (el.classList) {
el.classList.toggle(className);
} else {
var classes = el.className.split(' ');
var existingIndex = classes.indexOf(className);
if (existingIndex >= 0)
classes.splice(existingIndex, 1);
else
classes.push(className);
el.className = classes.join(' ');
}
```
**問302**
こちら
```js
$.parseHTML(htmlString);
```
と同じ処理をするようにJSで記述してください。
```js
var parseHTML = function(str) {
var tmp = document.implementation.createHTMLDocument();
tmp.body.innerHTML = str;
return tmp.body.children;
};
parseHTML(htmlString);
```
**問303**
こちら
```js
$(el).on(eventName, eventHandler);
```
と同じ処理をするようにJSで記述してください。
```js
el.addEventListener(eventName, eventHandler);
```
**問304**
こちらはDOMの解析とロードの条件で渡されたコールバック、fncが同期的に呼ばれるか非同期に呼ばれるか変わるコードです。
```js
function onReady(fnc) {
var readyState = document.readyState;
if (readyState === 'interactive' || readyState === 'complete') {
fnc();
} else {
window.addEventListener('DOMContentLoaded', fnc);
}
}
onReady(function () {
console.log('DOMは解析とロード済み');
});
console.log('Start');
```
大雑把にいうと、body終了直前に書かれていた場合条件式trueの文が実行され同期的に、
head内で書かれていた場合elseブロックが実行され非同期的に呼ばれます。
なので'Start'が出力される順番が変わるのですが、
こちらを常に'Start'が先に出力されるようにしてください。
```js
//onReadyが実行される際に渡しているコールバックはもしtrueなら同期的にfnc()が実行される。
//なので
//DOMは解析とロード済み
//Start
//と出力される。
//これを常に
//Start
//DOMは解析とロード済み
//とするにはfncを非同期で実行するようにするようにする
//ex1 setTimeout
function onReady(fnc) {
const readyState = document.readyState;
if (readyState === 'interactive' || readyState === 'complete') {
setTimeout(fnc, 0);
} else {
window.addEventListener('DOMContentLoaded', fnc);
}
}
onReady(function () {
console.log('DOMは解析とロード済み');
});
console.log('Start');
//Start
//DOMは解析とロード済み
//ex2 Promise
function onReady() {
return new Promise(function(resolve, reject){
const readyState = document.readyState;
if (readyState === 'interactive' || readyState === 'complete') {
resolve();
} else {
window.addEventListener('DOMContentLoaded', resolve);
}
})
}
onReady().then(function(){
console.log('DOMは解析とロード済み')
})
console.log('Start');
//Start
//DOMは解析とロード済み
//Promiseは常に非同期で実行されることを保障されている
```
**問305**
非同期コールバックを同期的に呼んではいけない理由を教えて下さい。
```
・非同期コールバックを同期的に呼び出すと、処理の期待されたシーケンスが乱され、コードの実行順序に予期しない変動が生じるかもしれない。
・非同期コールバックを同期的に呼び出すと、スタックオーバーフローや例外処理の間違いが発生するかもしれない。
//非同期コールバックを次回に実行されるようスケジューリングするには、setTimeout のような非同期APIを使う。
```
**問306**
最初のPromiseオブジェクトがresolveされたら'私は'という文字列を返し、次のPromiseオブジェクトで文字列'今日、'を返し、次のPromiseオブジェクトで'運がいいです'を返し、
最後のPromiseオブジェクトでそれらが連結された文字列を出力してください。
```js
const initPromise = new Promise(function(resolve){
resolve('私は')
})
const lastName = function(sentence, lastname){
return sentence + '今日、'
}
const firstName = function(lastName){
return lastName + '運がいいです'
}
const comp = function(compName){
console.log(compName)
}
initPromise.then(lastName).then(firstName).then(comp);
//私は今日、運がいいです
```
**問307**
Promseオブジェクト作成時にresolveに数値1を渡すコールバックを呼び出し、console出力され、
続くthenメソッドで2を足した値を出力してください。
```js
var promise1 = new Promise(function(resolve, reject){
resolve(1);
})
promise1.then(function(val){
console.log(val);
return val + 2;
}).then(function(val){
console.log(val);
});
```
**問308**
Promiseオブジェクトを使ってGETメソッドリクエスト,list.jsonを取得してください。urlは`http://kenmori.jp/list.json`とする
```js
function get(url) {
return new Promise(function(resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function() {
if (req.status == 200) {
resolve(req.response);
} else {
reject(Error(req.statusText));
}
};
req.onerror = function() {
reject(Error("Network Error"));
};
req.send();
});
};
get('list.json').then(function(res){
console.log("Success!", res);
}, function(error){
console.log("Failed", error);
})
```
**問309**
Promiseオブジェクトを使ってこちら
```js
function say(callback, msg) {
setTimeout(callback, msg);
}
say(function(){
console.log('ken!!')
}, 1000);
```
と同じことをしてください
```js
function say(msg){
return new Promise(function(resolve, reject){
setTimeout(resolve, msg);
});
}
say(1000).then(function(){
console.log('ken!');
})
```
**問310**
Promiseを使って0.5秒後毎に文字列の出力がされる非同期処理を実装をしてください
```js
function f (name, time){
var done = new Promise(function(resolve){
setTimeout(function(){
console.log(name)
resolve();
}, time)
});
return done
};
f('kenji', 1000)
.then(()=> f('morita', 500))
.then(()=> f('kkk', 500))
.then(()=> f('jji', 500))
//lesson
function f (time){
return new Promise(function(resolve){
setTimeout(()=>{
//共通でやりたい処理
//終わったらresolve()を実行
//resolve(some)//渡したりする
}, time)
})
}
f().then(()=> f(500))//「fした後に~する」の中身を実装。この場合、し終わったらさらにfを実行
.then(()=> f(500)) //それが終わったらさらにf
```
**問311**
複数の非同期処理の完了を待って'done'を出力する実装をしてください
```js
function f (name, time){
var done = new Promise(function(resolve){
setTimeout(function(){
console.log(name)
resolve();
}, time)
});
return done
};
var i = Promise.all([f('morita', 500),f('kkk', 500),f('jji', 500)])
i.then(()=> console.log("done"))
```
**問312**
'http://localhost:3000/comments',
'http://localhost:3000/posts',
'http://localhost:3000/profile',
'http://localhost:3000/state',
の順にGETリクエスト、それぞれresponseが返って来るまで、処理を止めて、返ってきたら次のリクエストをする実装をしてください。
```js
function hidouki(url, num){
return new Promise(function(resolve, reject){
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function () {
console.log(num)
if(req.status == 200){
resolve(req.response);
} else {
reject(Error(req.statusText));
}
}
req.onerror = function(){
reject(Error("Network Error"))
}
req.send();
})
}
async function asyncFunction (url, num){
var result = await hidouki(url , num);
console.log(result);
return result;
}
asyncFunction('http://localhost:3000/comments', 1)
.then((res)=> asyncFunction('http://localhost:3000/posts', 2))
.then((res)=> asyncFunction('http://localhost:3000/profile', 3))
.then((res)=> asyncFunction('http://localhost:3000/state', 4))
.then(() => console.log('done!'))
```
**問313**
上記の記述はthenの第一引数にresolve処理を渡しています。
逐次処理のような記述に修正してください。
```js
function hidouki(url, num){
return new Promise(function(resolve, reject){
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function () {
console.log(num)
if(req.status == 200){
resolve(req.response);
} else {
reject(Error(req.statusText));
}
}
req.onerror = function(){
reject(Error("Network Error"))
}
req.send();
})
}
async function asyncFunction (){
const result = await hidouki('http://localhost:3000/posts', 1);
console.log(result);
const result2 = await hidouki('http://localhost:3000/comments', 2);
console.log(result2);
const result3 = await hidouki('http://localhost:3000/profile', 3);
console.log(result3);
const result4 = await hidouki('http://localhost:3000/state', 4);
console.log(result4);
console.log('done!');
}
asyncFunction();
```
**問314**
[co](https://github.com/tj/co)を使って、
'http://localhost:3000/comments',
'http://localhost:3000/posts',
'http://localhost:3000/profile',
'http://localhost:3000/state',
を並列でリクエストしてください。
```js
const promiseFun = co.wrap( function* (url){
return new Promise(function(resolve, reject){
var req = new XMLHttpRequest();
req.open('GET', url, true);
req.onload = function(){
if(req.status == 200){
setTimeout(()=>{
//note:5秒後にdoneするようにしています
resolve(req.response);
}, 5000)
} else {
reject(Error("error"));
}
}
req.onerror = function(){
console.log("error");
}
req.send(null);
});
})
co(function* (){
var res = yield [
promiseFun('http://localhost:3000/posts'),
promiseFun('http://localhost:3000/profile'),
promiseFun('http://localhost:3000/state'),
];
console.log(res[0], res[1], res[2]);
}).catch(onerror);
```
**問315**
coを使ってgeneratorをラップしたfnを実行して、Promiseがresolveするまで処理を止める記述をしてください。※Promise.resolveで任意の値をすぐ返してok
```js
var fn = co.wrap(function* (fa){
return yield Promise.resolve(fa);
});
fn(true).then(function(val){console.log(val)})
```
**問316**
coを使って、1から始まり1秒ごとにインクルメントされた値からパラメーターに渡した数値まで出力される関数を実装、呼び出し元にresolveのpromiseオブジェクトが返ってきたら'done'を出力してください。
```js
function sleep(i){
return new Promise(function(resolve){
setTimeout(resolve,1000);
})
};
var num = co.wrap(function* (num){
for(var i = 1; i <= num; i++) {
yield sleep(i);
console.log(i)
}
yield sleep(1)
})
num(5).then(function(num){
console.log('done')
});
```
**問317**
こちら
```js
function asyncFunc() {
return otherAsyncFunc()
.then(result => {
console.log(result);
});
}
```
は非同期の結果をハンドリングしています。この処理と同等になるようにasync/awaitで記述してください
```js
async function asyncFunc() {
const result = await otherAsyncFunc();
console.log(result);
}
```
**問318**
こちら
```js
function asyncFunc() {
return otherAsyncFunc1()
.then(result1 => {
console.log(result1);
return otherAsyncFunc2();
})
.then(result2 => {
console.log(result2);
});
}
```
は非同期の結果が返ってきたら次の非同期処理をしています(逐次処理)。
この処理と同等になるようにasync/awaitで記述してください
```js
async function asyncFunc() {
const result1 = await otherAsyncFunc1();
console.log(result1);
const result2 = await otherAsyncFunc2();
console.log(result2);
}
```
**問319**
こちら
```js
function asyncFunc() {
return Promise.all([
otherAsyncFunc1(),
otherAsyncFunc2(),
])
.then([result1, result2] => {
console.log(result1, result2);
});
}
```
は非同期処理を並列でしています。この処理と同等になるようにasync/awaitで記述してください
```js
async function asyncFunc() {
const [result1, result2] = await Promise.all([
otherAsyncFunc1(),
otherAsyncFunc2(),
]);
console.log(result1, result2);
}
```
**問320**
こちらは
```js
function asyncFunc() {
return otherAsyncFunc()
.catch(err => {
console.error(err);
});
}
```
非同期処理を移譲した先で起きたエラーをハンドリングしています
この処理と同等になるようにasync/awaitで記述してください
```js
async function asyncFunc() {
try {
const result = await otherAsyncFunc();
} catch (err) {
console.error(err);
}
}
```
**問321**
イベントデリゲーションに関して。
こちらのDOMの
```html
- Walk the dog
- Pay bills
- Make dinner
- Code for one hour
```
li要素のそれぞれにイベントリスナーをアタッチしたもが下記です。
```js
document.addEventListener('DOMContentLoaded', function() {
let app = document.getElementById('todo-app');
let items = app.getElementsByClassName('item');
// attach event listener to each item
for (let item of items) {
item.addEventListener('click', function() {
alert('you clicked on item: ' + item.innerHTML);
});
}
});
```
この問題はもしli要素が1000個あった場合1000個のリスナーを作るところにあります。
これは効率的ではありません。
全体のコンテナーに対し1つのイベントリスナーをアタッチして上記と同じ動作をするようなイベントデリゲーションを実装してください
```js
document.addEventListener('DOMContentLoaded', function() {
let app = document.getElementById('todo-app');
// attach event listener to whole container
app.addEventListener('click', function(e) {
if (e.target && e.target.nodeName === 'LI') {
let item = e.target;
alert('you clicked on item: ' + item.innerHTML);
}
});
});
```
**問322**
こちらの実装は配列のインデックスを3000ms後に出力することを期待しています。
```js
const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log('The index of this number is: ' + i);
}, 3000);
}
//"The index of this number is: 4"
//"The index of this number is: 4"
//"The index of this number is: 4"
//"The index of this number is: 4"
```
理由はsetTimeout関数はクロージャーを作り、それはスコープ外への参照を持ちます。
3秒後には関数は実行されその時ループはすでに終わっていてその際参照するiは4となっているためです。
これを期待する通り
```js
//"The index of this number is: 0"
//"The index of this number is: 1"
//"The index of this number is: 2"
//"The index of this number is: 3"
````
を出力するように実装をしてください。
```js
//変数iをそれぞれのfunctionに渡す
const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
// pass in the variable i so that each function
// has access to the correct index
setTimeout(function(i_local) {
return function() {
console.log('The index of this number is: ' + i_local);
}
}(i), 3000);
}
//let構文を使う。それぞれのfunctionが呼ばれるたびにletは新しいバインディングを作る
const arr = [10, 12, 15, 21];
for (let i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log('The index of this number is: ' + i);
}, 3000);
}
// read more here: http://exploringjs.com/es6/ch_variables.html#sec_let-const-loop-heads
```
**問323**
こちらのhtmlでcontainer内をscrollした際にイベントを発火させたい。
```html
```
ただ、window.scrollのイベント毎に発火するとパフォーマンスに深刻な問題を起こす。
inputにkeypressする際にも起こるようなこのような問題はdebouncingとthrottlingを実装することで解決できる。
//https://css-tricks.com/debouncing-throttling-explained-examples/
scroll後、2秒後にイベントが発火するdebouncingを実装してください。
```js
// debounce function that will wrap our event
function debounce(fn, delay) {
// maintain a timer
let timer = null;
// closure function that has access to timer
return function() {
// get the scope and parameters of the function
// via 'this' and 'arguments'
let context = this;
let args = arguments;
// if event is called, clear the timer and start over
clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(context, args);
}, delay);
}
}
// function to be called when user scrolls
function foo() {
alert('You are scrolling!');
}
// wrap our function in a debounce to fire once 2 seconds have gone by
let elem = document.getElementById('container');
elem.addEventListener('scroll', debounce(foo, 2000));
//https://jsfiddle.net/kenjimorita/2pmpvnqw/1/
```
**問323**
変数aに2代入してをaを4乗してください。
さらにaが16になることを確認してください
```js
let a = 2;
a **=4;
a === Math.pow(2, 4);
//true
```
**問324**
```js
let obj = {a: 1, b:2, c:3}
Object.values(obj).forEach(value=> console.log(value))
//1
//2
//3
```
こちらをfor-ofで同じ実装にしてください
```js
let obj = {a:1, b:2, c:3}
for(let value of Object.values(obj)){
console.log(value)
}
//1
//2
//3
```
**問325**
こちらはentriesで返されるkeyとvalueのペアー配列を要素とした配列をdestructuringしてそれぞれのkeyとvalueを出力しています。
```js
let obj = {a:1,b:2,c:3};
Object.entries(obj).forEach( ([key, value]) => {
console.log(`${key} is ${value}`)
})
```
この実装をfor-ofで記述してください
```js
let obj = {a: 1, b: 2, c: 3}
for (let [key, value] of Object.entries(obj)) {
console.log(`${key} is ${value}`)
}
// a is 1, b is 2, c is 3
```
**問326**
こちらは副作用がない関数です
```js
function add(x, y){
return x + y;
}
```
こちらの関数の中身を編集せずにx + yの結果、例えばadd(2, 3)を実行したら値をreturnする前にconsoleで'Result:5'を出力する記述をしてください。
```js
function add (x, y){
return x + y;
}
function addAndLog(x, y){
var result = add(x, y);
console.log(`Result:${result}`);
return result;
}
addAndLog(2, 3)
//Result:5
```
**問327**
下記のような減算する関数subtractと加算する関数addがあります。
```js
function add (x, y){
return x + y;
}
function subtract(x, y){
return x - y;
}
```
subtractかaddを渡すと実行結果をreturnする前にそれぞれの関数結果をconsole出力する汎用的な関数logAndReturnを実装してください
```js
function add (x, y){
return x + y;
}
function subtract(x, y){
return x - y;
}
//HigherOrderFunction
function logAndReturn(func) {
return function(){
var args = Array.prototype.slice.call(arguments);//返した関数の引数を配列にする
var result = func.apply(null, args);//渡された関数に引数を渡し実行する
console.log(`Result:${result}`);
return result;
}
}
var addAndLog = logAndReturn(add);
addAndLog(4, 4);
//'Result:8'
var subtractAndLog = logAndReturn(subtract);
subtractAndLog(4, 3);
//'Result:1'
```
**問328**
こちらの配列、[1, 2, 3, 3]で、
要素が重複しない形で返す記述をしてください
期待する値 [1, 2, 3]
```js
const arr = [1, 2, 3, 3];
const a = [...new Set([1, 2, 3, 3])];
console.log(a)
//[1, 2, 3]
//spread operatorが使えない環境下で
var unique = Array.from(new Set([1,2,2,3,3,3,4,5])); // [1,2,3,4,5]
```
**問329**
applyのユースケースについて。このような関数があります
```js
//1
function log(){
console.log.apply(console, arguments)
}
log('foo');
```
と
```js
//2
function log(){
console.log(arguments);
}
log('foo');
```
の違いを教えてください
```js
//applyを使うと適応された関数に引数として配列を渡すことができます。
//1の場合
console.log.apply(console, ['foo'])と評価され
下記が実行されます
console.log('foo')
//'foo'
//2の場合
Arguments objectをそのまま出力することになります
console.log(['foo'])を実行し、
//['foo']
//more
//e.g
Math.max(12, 45, 78) //returns 78
//組み込み関数と一緒に使用する
var max = Math.max.apply(null, [12, 45, 92, 78, 4]);//returns 92
//e.g
var array = [10, 20, 30];
function average(){
console.log.apply(console, arguments)
}
average(array[0], array[1], array[2]);
//↓
average.apply(null, array);//簡潔に
//or
Function.prototype.apply.call(average, null, array);//上記より安全に
//or
Reflect.apply(average, null, array);//上記より簡潔に
//or
average(...array);//違う方法で
```
**問330**
こちらの関数
```js
function foo(x) {
if (x > 10) return x + 1;
var y = x / 2;
if (y > 3) {
if (x % 2 == 0) return x;
}
if (y > 1) return y;
return x;
}
foo(2);
foo(4);
foo(8);
foo(12);
```
を実行したらそれぞれ何が返るかお答えください
```js
//2
//2
//8
//13
```
**問331**
以下の関数を実行すると
```js
function foo(a, b) {
arguments[1] = 2;
console.log(b);
}
foo(1);
```
bとして出力するのは何ですか?
``
```js
undefined
```
**問332**
以下
```js
NaN === NaN
```
出力するのは何ですか?
```
false
```
**問333**
こちらを順にお答えください。
```js
| y | x | == | === | Object.is() |
|-------------------|-------------------|----|-----|-------------|
| undefined | undefined | | | |
| null | null | | | |
| true | true | | | |
| false | false | | | |
| 'foo' | 'foo' | | | |
| 0 | 0 | | | |
| +0 | -0 | | | |
| 0 | false | | | |
| "" | false | | | |
| "" | 0 | | | |
| '0' | 0 | | | |
| '17' | 17 | | | |
| [1, 2] | '1,2' | | | |
| new String('foo') | 'foo' | | | |
| null | undefined | | | |
| null | false | | | |
| undefined | false | | | |
| {foo: 'bar'} | {foo: 'bar'} | | | |
| new String('foo') | new String('foo') | | | |
| 0 | null | | | |
| 0 | NaN | | | |
| 'foo' | NaN | | | |
| NaN | NaN | | | |
```
答え
```js
| y | x | == | === | Object.is() |
|-------------------|-------------------|-------|-------|-------------|
| undefined | undefined | true | true | true |
| null | null | true | true | true |
| true | true | true | true | true |
| false | false | true | true | true |
| 'foo' | 'foo' | true | true | true |
| 0 | 0 | true | true | true |
| +0 | -0 | true | true | false |
| 0 | false | true | false | false |
| "" | false | true | false | false |
| "" | 0 | true | false | false |
| '0' | 0 | true | false | false |
| '17' | 17 | true | false | false |
| [1, 2] | '1,2' | true | false | false |
| new String('foo') | 'foo' | true | false | false |
| null | undefined | true | false | false |
| null | false | false | false | false |
| undefined | false | false | false | false |
| {foo: 'bar'} | {foo: 'bar'} | false | false | false |
| new String('foo') | new String('foo') | false | false | false |
| 0 | null | false | false | false |
| 0 | NaN | false | false | false |
| 'foo' | NaN | false | false | false |
| NaN | NaN | false | false | true |
```
**問334**
こちら
```js
(function(){
return typeof arguments;
})();
```
を実行した際の返値を教えてください
```js
(function(){
return typeof arguments;
})();
//"object"
//argumentsはarray likeです。[]やインデックスにはアクセスできますが、pushなどのメソッドは存在しません。
//typeof でarrayはobjectを返します。なぜならarrayも参照型のobjectだからです。
```
**問335**
こちら
```js
const arr = ["a", , "c"];
const sparseKeys = Object.keys(arr);
const denseKeys = [...arr.keys()];
```
のsparseKeysとdenseKeysを出力した際の違いを教えてください
```
const arr = ["a", , "c"];
const sparseKeys = Object.keys(arr);
const denseKeys = [...arr.keys()];
console.log(sparseKeys); // ['0', '2'] //要素はstring
console.log(denseKeys); // [0, 1, 2]//抜けを無視しない //要素は数値
```
**問336**
こちら
```js
(function() {
var a = b = 5;
})();
console.log(b);
```
bは何を出力しますか?
```js
(function() {
var a = b = 5;
})();
console.log(b);
//5
//strict modeではないIIFE内のaはvarキーワードで宣言しているためfunction内のlocal変数。
//bはglobal変数になります。
//strict modeでは「Uncaught ReferenceError」になります。
(function() {
'use strict';
let a = b = 5;
})();
console.log(b);//Uncaught ReferenceError: b is not defined
その場合明示的にしなくてはいけません。
(function() {
'use strict';
var a = window.b = 5;
})();
console.log(b);
//5
```
**問337**
こちら
```js
var f = function g(){ return 23; };
typeof g();
```
は何を返しますか??
```js
var f = function g(){ return 23; };
typeof g();
//Uncaught ReferenceError: g is not defined
//エラーが起こります。function g(){ return 23; }は関数式で関数宣言ではありません。
この関数は実際にはfにバインドされていてgではありません。
//関数式に識別子を指定するとそれ自体使うことをスルーされます
```
**問338**
下のように
```js
console.log('hello'.repeatify(3));
//hellohellohello.
```
Stringオブジェクト上に整数値を受け取ってその数だけrepeatするrepeatify関数を定義してください。
```js
String.prototype.repeatify = String.prototype.repeatify || function(times) {
var str = '';
for (var i = 0; i < times; i++) {
str += this;
}
return str;
};
```
**問339**
下のコードは
```js
function test() {
console.log(a);
console.log(foo());
var a = 1;
function foo() {
return 2;
}
}
test();
```
何を出力しますか。またどうしてですか?
```js
//undefined
//2
//変数と関数は巻き上げられます(関数の上部に移動します。hoisted)
//ただ変数はどんな割り当ても保持しません。
//function内には存在するが状態はundefinedです。
//問題のコードは下記と同じです
function test() {
var a;
function foo() {
return 2;
}
console.log(a);//undefined
console.log(foo());//2
a = 1;
}
test();
```
**問340**
下記コードは
```js
var fullname = 'John Doe';
var obj = {
fullname: 'Colin Ihrig',
prop: {
fullname: 'Aurelio De Rosa',
getFullname: function() {
return this.fullname;
}
}
};
console.log(obj.prop.getFullname());
var test = obj.prop.getFullname;
console.log(test());
```
何を出力しますか
```js
//Aurelio De Rosa
//John Doe
```
**問341**
第一引数で受け取った数値に3を足して返す関数add3を第一引数に渡すとfを2回繰り返す関数twice。
```js
twice(add3, 7);
```
初期値として7をtwiceの第二引数に渡し、13を出力してください。
```js
function add3(v){
return v + 3
}
function twice(f, v){
return f(f(v))
}
twice(add3, 7);
//13
```
**問342**
こちらの
```js
logStuff({name: 'morita', job: engineer}, log);
```
を実行したら
```
//name morita
//job engineer
```
と出力する関数logStuffを実装してください。また、第二引数として渡すlogはlogStuffの第一引数のkey,valueを出力するコールバック関数です。
objはlogStuffの中でString型かObject型かチェックしてください。
```js
var arr = [];
function log(obj){
if (typeof obj === 'string'){
console.log(obj);
} else if (typeof obj === 'object'){
Object.keys(obj).map(function(el, i){
console.log(`${el} ${obj[el]}`)
})
}
}
function logStuff(obj, callback){
arr.push(obj);
callback(obj);
}
logStuff({name: 'morita', job: 'engineer'}, log);
```
**問343**
問342のlogStuffについて、第二引数で渡したcallbackの型をチェックしてFunctionだったら実行するようにしてください
**問344**
こちらの
```js
var clientData = {
id: 094545,
fullName: "Not Set",
setUserName: function (firstName, lastName) {
this.fullName = firstName + " " + lastName;
}
}
function getUserInput(firstName, lastName, callback) {
callback (firstName, lastName);
}
getUserInput('kenji', 'morita', clientData.setUserName);
console.log(clientData.fullName)
//"Not Set"
```
渡した値がfullNameにセットされて出力するようにしてください。
```js
var clientData = {
id: 094545,
fullName: "Not Set",
setUserName: function (firstName, lastName) {
this.fullName = firstName + " " + lastName;
}
}
function getUserInput(firstName, lastName, callback, callbackObj) {
callback.apply(callbackObj, [firstName, lastName]);
}
getUserInput('kenji', 'morita', clientData.setUserName, clientData);
clientData.fullName
//kenji morita
```
**問345**
こちら
```js
var greet = function(greeting, name){
console.log(greeting, name);
}
greet('Hello', 'kenji')
Hello kenji
```
greetをCurry化してgreetHello('kenji')を実行すると
同じ出力になるようにしてください
```js
var greetCurried = function(greeting){
return function(name){
console.log(`${greeting} ${name}`)
}
}
var greetHello = greetCurried('Hello')
greetHello('kenji')
//Hello kenji
```
**問346**
こちら
```js
var greetAwkwardly = greetDeeplyCurried("Hello")("...")("?");
greetAwkwardly("kenji");
```
を実行した際に
```
//Hello...kenji?
```
が出力されるようにgreetDeeplyCurriedを実装してください
```
var greetDeeplyCurried = function(greeting){
return function(spread){
return function(empasis){
return function(name){
console.log(`${greeting}${spread}${name}${empasis}`);
}
}
}
}
var greetAwkwardly = greetDeeplyCurried('Hello')('...')('?');
greetAwkwardly('kenji')
//Hello...kenji?
```
**問347**
文字列が'He'から始まる場合trueになる評価をしてください
ex 'Hello World' //true 'Goodby World' //false
```js
'Hello World'.startsWith('He');
//other
/^He/.test('Hello world')
//true
//'Hello World'.lastIndexOf("He",0) === 0
//true
```
**問348**
mystring#という文字列があります。最後の文字が#の場合trueになる評価をしてください
```js
let str = "mystring#";
str.endsWith("#")
//true
let str = "mystring#";
//str.endsWith(".")
false
//other
let str = "mystring#";
/#$/.test(str)
//true
//str.substr(-1) === "#"
//true
```
**問349**
引数に文字列を渡すとその最初の文字を大文字にして返す関数を実装してください
```js
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
capitalizeFirstLetter("morita")
//"Morita"
```
**問350**
prototype と \_\_proto\_\_ の違いを説明してください
```js
・prototype・・・Functionオブジェクトだけがもつプロパティ。参照先はオブジェクト。
・__proto__・・・全てのオブジェクトが持つ内部プロパティ。プロトタイプチェーン。暗黙の参照(自身のプロパティになければこの__proto__先を辿ること)を実現する内部で実装されているプロパティ。
newして生成されたインスタンスの__proto__にコンストラクタのprototypeオブジェクトが代入される
function F(){
this.name = '';//1
}
F.prototype.y = function(){} //2
let f = new F(); //f.__proto__ = F.prototype //
f.__proto__ === F.prototype
//true
F自体の__proto__には空の関数が入っている
F.__proto__
//function () { [native code] }
//yが自身のpropertyかどうかチェック
F.hasOwnProperty('y')
//false
F.prototype.hasOwnProperty('y') //2でprototypeに代入しているため
//true
//newした結果、インスタンスfは自身の参照リンクを辿った先のprototypeオブジェクトが持つyを見ることができる
f.y === f.__proto__.y
//true
f.hasOwnProperty('y') //f自身はyを持たない
//false
f.hasOwnProperty('name') //自身にnameをもつ //2
//true
//Array
var arry = [];
arry.__proto__ === Array.prototype
//true
arry.__proto__ === [].__proto__
//true
arry.hasOwnProperty('pop') //参照リンク先のオブジェクトprototypeが持つメソッド
//false
//more
//こちらのコンストラクタが実行された際に何が起きているか
function A (name){
this.name = name;
}
//Aのプロパティにprototypeが追加される
//prototypeプロパティはオブジェクトで、以下の2つのプロパティをもつ
//constructor
//__proto__
A.prototype
//constructor:function a(name)
//__proto__:Object
constructorは何もないがそれ自体内部に__proto__を持ち、その参照先はJavaScriptのルートオブジェクトであるObject。
//Aをnewした時に何が起きるか
let b = new A('JavaScript');
//4つのことが起こる
//1.新しい空のオブジェクト{}が生成される
//2.b上に__proto__が作られ、それはA.prototypeを参照するようになる。なのでb.__proto__ === A.prototype
//3.上記1で生成されたオブジェクトをthisコンテキストとして、A.prototype.constructorを実行します。したがってnameプロパティは新しく作成されたオブジェクトに追加されます。
//4.作成されたオブジェクトを返します。let bは新しいオブジェクトが割り当てられます。
//もしA.prototype.car = 'BMW'として、b.carとすると" BMW"をアウトプットします
//JavaScriptはb上のプロパティcarを探し、見つからなければ上記2で作成されたb.__proto__(A.prototype)を参照し、A.prototypeにあるcarプロパティ値を返すためです。
```
問351〜問400
**問351**
問352を参照にして、自身にyプロパティをもつFクラスのインスタンスfがFのprototypeオブジェクトを参照していることを証明してください。尚、Fはclass構文とする
```js
class F {
constructor(){
this.y = 'y'
}
}
let f = new F()
f.__proto__ === F.prototype
//true
//Examination
f.hasOwnProperty('y')
//true
```
**問352**
こちら
```
function a (name) {
this.name = name;
}
let b = new a('JavaScript');
a.prototype.car = 'BMW'
b.car
```
が実行された際のJavaScriptの内部の動きをざっくり教えてください(問350で説明しているところです。復習)
```js
function a (name) {
this.name = name;
}
let b = new a('JavaScript');
a.prototype.car = 'BMW'
b.car
//'BMW'
//4つのことが起こる
//1.新しい空のオブジェクト{}が生成される//WIP 仕様確認
//2.b上に__proto__が作られ、それはa.prototypeを参照するようになる。なのでb.__proto__ === a.prototype
//3.上記1で生成されたオブジェクトをthisにするもつa.prototype.constructorを実行します。したがってnameプロパティは新しく作成されたオブジェクトに追加されます。
//4.作成されたオブジェクトを返します。let bは新しいオブジェクトが割り当てられます。
//もしa.prototype.car = 'BMW'として、b.carとすると" BMW"をアウトプットします
//JavaScriptはb上のプロパティcarを探し、見つからなければ上記2で作成されたb.__proto__(a.prototype)を参照し、a.prototypeにあるcarプロパティ値を返すためです。
```
http://exploringjs.com/es6/ch_parameter-handling.html#sec_named-parameters
**問353**
こちらはmaxからminまでのランダム値を返す関数です。
```js
function randam({max=180, min=1}){
return Math.floor(Math.random() * (max - min) + min);
}
randam({max:20});//20までの値を返す
randam({});//1~180の値を返す
```
こちらの関数に{}を渡さないでも返してくれるようにしてください eg: randam();//1~180までを返す
```js
function randam({max=180, min=1} = {}){//defaultをもたせます
return Math.floor(Math.random() * (max - min) + min);
}
randam()
```
**問354**
下記のようなオブジェクト
```js
{ foo: { bar: 'baz' } }
```
barの値をdeepとして割り当ててください
```js
const {foo: {bar: deep}};
console.log(deep)//'baz'
```
**問355**
下記
```js
[...$('div')]
```
を実行すると例外が発生する(Symbol.iteratorがまだ実装されていないため)。任意の数のdivが持つid値を配列の要素になるような関数を定義してください
```js
Array.from($('div'), el => el.id)
//Array.from メソッドはiteratebleなオブジェクトもArraylikeなオブジェクトもサポートする
//Array.fromは3つの引数をとる
//・input -キャストしたいarraylike or iteratable object
//.map - 各inputのitemに対して実行されるmapping function
//.context - mapが呼ばれる際に使われるthis
```
**問356**
引数としてnull,[], NaNを渡した際にぞれぞれをtypeofで評価した配列['object', 'object', 'number']を返す関数を作ってください
```js
function typeOf(){
return Array.from(arguments, val => typeof val);
}
typeOf(null, [], NaN);
//['object', 'object', 'number']
```
**問357**
変数宣言無しで `{ a: "baz", b: 101 }`のそれぞれの値を`a`と`b`に代入してください
```js
({ a, b } = { a: "baz", b: 101 });
```
**問358**
こちら
```js
let faf;
let ee;
if(true){
ee = "true";
faf = "true";
} else {
ee = "false";
faf = "false";
}
```
をletを書かずにconstで代入できるようにしてください
```js
const {faf, ee } = (() => {
if(true){
return {ee:"true",
faf:"true"}
} else {
return {ee: "false",
faf:"false"}
}
})()
```
**問359**
上記のような
```js
[1, 2, 3].map(e => e);
```
いわゆるワンラインで書かれているFanctor内でconsole.logを出力してください
```js
[1, 2, 3].map(e => console.log(e) || e);
//console.logはundefinedを返すのでfalse。処理が次に移る
```
**問360**
下記
```
~1
~-1
~0
```
3つはそれぞれは何を返すか
```js
-2
0
-1
//符号を逆にして-1された値が返る
```
**問361**
下記のように
```js
let a = false
let b = false
let variable;
if(a){
variable = a;
} else if(b){
variable = "b"
} else {
variable = "c"
}
variable
//"c"
```
elseifを伴ったif文を一行で書いてください
```js
const variable = a ? a : b ? b : c
```
**問362**
`JSON.stringify`について、
以下
```js
let user = {
sayHi() {
alert("Hello");
},
[Symbol("id")]: 123,
something: undefined
};
JSON.stringify(user)
```
を実行した場合、返ってくる値を教えてください
``js
JSON.stringify(user)
"{}" //empty
``
why:
`Function properties(method)`、
`Symbolic properties`、
`値がundefinedなproperties`はskipされます
JSON typeとしてサポートされているのは以下です
```
Objects { ... }
Arrays [ ... ]
Primitives: strings,numbers, boolean values true/false, null.
```
_aside_
`'John'` became `"John"`, `{age: 30}` become `{"age": "30"}`
`typeof user` will return `"string"`
**問363**
こちらは
```js
let meetup = {
title: "conference",
room: {number: 24, participants: ["johon", "ann"]}
}
JSON.stringfiy(meetup)
```
期待した通りに返ります(深いkey-valueも返すことに注意)
```js
JSON.stringify(meetup)
"{"title":"conference","room":{"number":24,"participants":["johon","ann"]}}"
```
ではこちらを実行した結果は何ですか
```js
let room = {number: 23};
let meetup = {title: "Conference", participants: ["john", "ann"]};
meetup.place = room;
// "{"title":"Conference","participants":["john","ann"],"place":{"number":23}}"
room.occupiedBy = meetup
JSON.stringify(meetup) // ここを実行した場合は?
```
実行後
```js
VM2804:1 Uncaught TypeError: Converting circular structure to JSON
at JSON.stringify ()
at :1:6
```
why:
循環オブジェクト参照構造体を文字列に変換できません。
簡単に言うと、
参照がその参照を参照してその参照がさらにその参照をしてと繰り返されることです
```js
let a = {};
let b = {};
a.child = b;
b.child = a;
を実行した場合
//b
{child: {…}}
child:child:child:child: {child: {…}}
__proto__: Object
__proto__: Object
__proto__: Object
__proto__: Object
//a
{child: {…}}
child:child:child: {child: {…}}
__proto__: Object
__proto__: Object
__proto__: Object
childがchildを持ち続ける
a.child = bの時
a.childは {}がかえりますが
b.child = aにすると
a.childは参照先bの構造も変わるので
a.child.childになります
さらにb.childはaを参照するので.childがあり、と延々続くのですね
このようなケースを文字列にする場合失敗します
```
回避するには
```js
JSON.stringify(value[, replacer, space])
//[replacer](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)を設定します
let obj = {
a: "foo",
b: obj
}
let replacement = {"b":undefined}; //undefinedをいれてskipさせる
JSON.stringify(obj,replacement));
```
or
`json-stringify-safe`を使ってそれが`circular`か確認します
**問364**
こちらの値
```js
let str = '{"title":"Conference","date":"2017-11-30T12:00:00.000Z"}';
```
をJSだけで(moment.jsを使わず) dateの日付(この場合30)を返す関数を作ってください
```js
let str = '{"title":"Conference","date":"2017-11-30T12:00:00.000Z"}';
let meetup = JSON.parse(str, function(key, value) {
if (key == 'date') return new Date(value);
return value;
});
meetup.date.getDate()
//30
// advance: nested date
let schedule = `{
"meetups": [
{"title":"Conference","date":"2017-11-30T12:00:00.000Z"},
{"title":"Birthday","date":"2017-04-18T12:00:00.000Z"}
]
}`;
schedule = JSON.parse(schedule, function(key, value) {
if (key == 'date') return new Date(value);
return value;
});
schedule.meetups[1].date.getDate();
//18
```
**問365**
こちらのオブジェクト
```js
let user = {
name: "John Smith",
age: 35
};
```
と同じkey-valueをもつオブジェクトになるようにして同じものではないことを確認してください
```js
let user = {
name: "John Smith",
age: 35
};
let user2 = JSON.parse(JSON.stringify(user))//
user2
//{name: "John Smith", age: 35}
user2.name = "morita"
//"morita"
user2
//{name: "morita", age: 35}
user
//{name: "John Smith", age: 35}
```
**問366**
こちら
```js
alert( undefined || null || 0 );
```
を実行すると何がalertとして表示されますか?
```js
0
```
`chain of OR "||" returns the first truthy value or the last one if no such value is found.`
ORはtruthy valueかそのような値が見つからない場合最後の値を返します
_aside_
```js
alert( 1 || 0 ); // 1 (1 is truthy)
alert( true || 'no matter what' ); // (true is truthy)
alert( null || 1 ); // 1 (1 is the first truthy value)
alert( null || 0 || 1 ); // 1 (the first truthy value)
alert( undefined || null || 0 ); // 0 (all falsy, returns the last value)
```
**問367**
こちらを実行したら
```js
alert( alert(1) || 2 || alert(3) );
```
どうなりますか
```js
`1、2とアラートされます`
```
why
alertはundefinedを返します
最初のOR評価でalertとして実行し1のメッセージ
undefineを返すので、ORはtruthyを探しに次のオペランドへ2が返るのでORはそこで終わり、
外側のアラートがそれを実行します
**問368**
こちら
```js
/hoge.fefe/.test(`hoge
fefe`);
```
は正規表現内で全ての文字にマッチ「.」を使用しています。test引数内で改行を含める文字列にマッチさせるためです。
が、こちらはfalseが返ります。
trueになるようにしてください。
```js
/hoge.fefe/s.test(`hoge
fefe`)
//今まで.は改行文字に対応できていなかったのですがES2018ではsフラグを付けることで可能になります
```
**問369**
Numberオブジェクトに引数をとって加算できるplusメソッドを追加してください
```js
Object.defineProperty(
Number.prototype,
"plus", {
value: function (b) {
return this + b;
}
}
);
```
**問370**
`a`という変数に`{}`かkeyがあるかどうか評価してください
```js
Object.keys(a).length === 0
```
**問371**
このような `{foo: "hogehoge", bar: "fafa"}` 、 `{bar: "fafa"}` 、 `{foo: "hogehoge"}`、 `null` が渡って来る可能性がある関数がある。
```js
const buildAnObjectFromAQuery = (query) => {
const object = {};
if (query.foo) {
object.foo = query.foo;
}
if (query.bar) {
object.bar = query.bar;
}
return object;
}
```
上記の関数と同じ仕事をする関数をより端的に書いてください。
```js
const buildAnObjectFromAQuery = query => ({
...query.foo && { foo: query.foo },
...query.bar && { bar: query.bar },
});
```
**問372**
このような `[1,2,3,3]` 配列がある。 `[1,2,3]` とユニークな要素だけを取得するようにしてください
```js
let un = [...new Set([1, 2, 3, 3])]
console.log(un); //[1, 2, 3]
```
**問373**
このようなfalsyな値を含む配列がある。
```js
let e = [0, undefined, null, "", 21, "fafa", false]
```
それらを除外した ```[21, "fafa"]```を取得してください
```js
let e = [0, undefined, null, "", 21, "fafa", false]
let trusy = e.filter(Boolean);
console.log(trusy);// [21, "fafa"]
```
**問374**
引数が渡って来ない、`undefined` なら Errorをthrowする関数を書いてください
```js
const required = ()=> { throw new Error("ooops") }
const fn = (param = required()) => {
console.log("ok")
}
fn()// Error
fn(undefined) //Error
fn(null) // ok
fn("") //ok
```
**問題375**
文字列 `"hello"`を逆の文字列にしてください expect `"olleh"`
```js
const str = "hello"
str.split('').reverse().join('')
//other
[...str].reduce(( prev, next ) => next + prev)
```
**問題376**
addという関数
```js
add(a){
return a + a
}
add(2) //4
```
はaを引数に取りa + aの値を返す関数です。
これを改善して、a関数に同じ値a(上記の場合`2`)が渡ったら以前と同じ値なら以前に計算された結果である(上記の場合`4`)の`cache`を返すようにしてください
```js
function add (a){
if(!add.cache){
add.cache = {}
console.log("cache create!")
}
if(!add.cache[a]){
add.cache[a] = a + a;
console.log("create value in cacche!")
}
return add.cache[a]
}
```
**問題377**
数値 `-6.133`、`6.133` を正数値だけ取得してください。
```js
let num = -6.133
Math.trunc(num)
// -6
let num = 6.133
Math.trunc(num)
// 6
```
**問題378**
こちら2の4乗
```js
Math.pow(2, 4)
// 16
```
と同じことをしてください
```js
2 ** 4
// 16
//ECMAScript216の べき乗演算子**(Exponentiation Operator)
```
**問題379**
こちらの文字列
```js
"パスワードは😄😄😄😄です".length
// 16
```
は16文字として処理されます
絵文字1つを2とカウントしないようにしてください
```js
[..."パスワードは😄😄😄😄です"].length
// 12
```
**問題380**
reducerを使って、 `[{id: 1, name: 'kenji'}]` を `{1: {name: 'kenji'}}` にしてください
```js
[{id: 1, name: 'kenji'}].reduce((a, c)=> (a[c.id] = c) && a, {})
```
**問題381**
`[{1: {name: "kenji"}}, {2: {name: "rika"}}]` を reduceを使って `[{name: "kenji"},{name: "rika"}]` にしてください
```js
// 一例)
[{1: {name: "kenji"}}, {2: {name: "rika"}}].reduce((a, c) => {
return [...a, ...Object.values(c)]
}, [])
```
**問題382**
`const res = {user: {name: 'kenji'}}`の `res.user` は `null`になりうることがある(`{user: null}`)。 `name`の値が欲しい時、 `null`の場合は`undefined`、`name`がある場合はその値を下記のように `const name = res.user && res.user.name` ではなく、 端的に(`optional chain`。オプショナルチェーンで)書いてください
```js
const a = res.user?.name // undefined or "kenji"。 エラーにはならない
// optional chain
// ?の左がnullになり得る場合、もしnull or undefinedだったら.(ドットアクセス)でエラーにせず、undefinedを返し、そうでない場合はその先を返すというものです
// つまり res.user == null ? undefined : res.user.name と res.user?.nameは同じです。端的に書けることがわかります
```
**問題383**
下記
```js
const a = 0
const b = false
const c = undefined
const d = null
```
のような変数がある`null`と`undefined`の場合は文字列 `"null or undefined"`を返し、そうでない場合はその値を返す 関数isNullishを実装してください
また、`Nullish coalescing Operator(ヌリッシュコアレスオペレーター)`とはどんなものですか?
```js
const a = 0
const b = false
const c = undefined
const d = null
const isNullish = (value) => value ?? "null or undefined"
isNullish(a) // 0
isNullish(b) // false
isNullish(c) // "null or undefined"
isNullish(d) // "null or undefined"
// また、Nullish coalescing Operator(ヌリッシュコアレシングオペレーター)とはどんなものですか?
// nullish coalescing opearator は もし左がnull か undefinedなら 右 を返す || の代替です
```
**問題384**
ECMASCript2020で追加されたglobalThisとはなんですか?
```js
ブラウザがもつグローバルオブジェクトである`window`とNode.jsのグローバルオブジェクト`global`はJavaScript実行環境が違うため分けられていた。
`globalThis`はブラウザ、Node.jsがもつ共通のグローバルオブジェクトです
// use browser
// open console.log and then
// globalThis
// use node with lts version
// node -v
// v12.16.2
// > node
// Welcome to Node.js v12.16.2.
// Type ".help" for more information.
// > globalThis
// Object [global] {
// global: [Circular],
// clearInterval: [Function: clearInterval],
// clearTimeout: [Function: clearTimeout],
// setInterval: [Function: setInterval],
// setTimeout: [Function: setTimeout] {
// [Symbol(nodejs.util.promisify.custom)]: [Function]
// },
// queueMicrotask: [Function: queueMicrotask],
// clearImmediate: [Function: clearImmediate],
// setImmediate: [Function: setImmediate] {
// [Symbol(nodejs.util.promisify.custom)]: [Function]
// }
// }
```
**問題385**
こちらの関数
```js
function dosomthing(name){
console.log("Hello " + name)
}
```
に `dosomthing("kenji")`実行すると "Hello kenji"と出力されます。
これを`dosomthing`の関数の中身を変えずに
```
start
Hello kenji
finish
```
と`Hello kenji`の前と後に`start`, `finish`と出力されるようにしてください
```js
function dosomthing(name){
console.log("Hello " + name)
}
function loggingDecorator(callback){
return function(){
console.log("starting");
const result = callback.apply(this, arguments);
console.log("Finished");
return result
}
}
var wrapped = loggingDecorator(dosomthing)
wrapped("kenji")
```
**問題386**
下記のように
```js
class Example {
@log
sum(a, b){
return a + b
}
}
const e = new Example();
e.sum(1, 2)
```
でsumに対するlog(subに渡された引数)出力される@logz(Decorators)を作ってください
```js
function log(_target, _name, descriptor) {
const original = descriptor.value; // decorateしている関数
if (typeof original === "function") {
descriptor.value = function(...arg) {
console.log("arguments:", `${arg}`);
try {
const result = original.apply(this, arg);
return result;
} catch (e) {
console.log(`Error:${e}`);
throw e;
}
};
}
return descriptor;
}
class Example {
@log
sum(a, b) {
return a + b;
}
}
const ins = new Example();
ins.sum(1, 2);
```
[codeSandbox](https://codesandbox.io/s/decorator-x-typescript-x-react-hm8rj?file=/src/index.tsx)
**WIP**
//問題文をわかりやすくする
fun()を実行し、もしキャッシュがあればその値を返し、もしキャッシュがなければその引数をキャッシュのkeyとして値を返す関数を実装してください。
```js
function fn() {
console.log('Generate cache');
const cache = {};
return function(a) {
let res = cache[a];
if (res) {
console.log('From cache');
return res;
} else {
console.log('Calculate and save to cache');
res = 'value' + a;
cache[a] = res;
return res;
}
};
}
const fun = fn()
//Generate cache
fun(1)
//Calculate and save to cache
//1
fun(1)
//From cache
//1
```
```js
//下記の関数
function f(images, index, attributes){
return {images: [ ...images.slice(0, index), {...images[index], ...attributes}, ...images.slice(index + 1)]}
}
の
f(["eeee","ppp","lll"], 1, [1,2,3])
実行時出力結果を答えてください
//images:[ "eeee", {0: 1, 1: 2, 2: 3} ,"lll"]
```
[付録] 便利かもしれないユーティリティ関数
```js
let object = {
innerObject:{
deepObject:{
value:'Here am I'
}
}
};
if(object && object.innerObject && object.innerObject.deepObject && object.innerObject.deepObject.value) {
console.log('We found it!');
}
```
このように退屈なif文にならないためのユーティリティ関数
```js
let obj = {
innerObject: {
deepObject: {
value: 'Here am I'
}
}
};
function hasOwnDeepProperty(obj, prop) {
if (typeof obj === 'object' && obj !== null) { // only performs property checks on objects (taking care of the corner case for null as well)
if (obj.hasOwnProperty(prop)) { // if this object already contains the property, we are done
return true;
}
for (let p in obj) { // otherwise iterate on all the properties of this object
if (obj.hasOwnProperty(p) && // and as soon as you find the property you are looking for, return true
hasOwnDeepProperty(obj[p], prop)) {
return true;
}
}
}
return false;
}
console.log(hasOwnDeepProperty(obj, 'value')); // true
console.log(hasOwnDeepProperty(obj, 'another')); // false
```
[付録] [Observable](https://tc39.github.io/proposal-observable/)
```js
```
参照記事
参照
http://exploringjs.com/es6/
https://leanpub.com/understandinges6/read
https://github.com/airbnb/javascript
http://uhyohyo.net/javascript/
https://developer.mozilla.org/ja/docs/Web/API/document
http://foreignkey.toyao.net/archives/763
https://github.com/metagrover/ES6-for-humans
https://www.amazon.co.jp/%E3%83%91%E3%83%BC%E3%83%95%E3%82%A7%E3%82%AF%E3%83%88JavaScript-%E4%BA%95%E4%B8%8A%E8%AA%A0%E4%B8%80%E9%83%8E-ebook/dp/B00P2EG5LC
https://www.oreilly.co.jp/books/9784873115733/
https://www.oreilly.co.jp/books/9784873116211/
http://gihyo.jp/magazine/wdpress/archive/2015/vol87
https://www.amazon.co.jp/%E7%8B%AC%E7%BF%92JavaScript-%E7%AC%AC2%E7%89%88-%E9%AB%98%E6%A9%8B-%E5%92%8C%E4%B9%9F/dp/4798130842
http://nodejs.jp/nodejs.org_ja/
http://d.hatena.ne.jp/hasegawayosuke/20130330/p1
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/create
https://twitter.com/javascript_tips
http://blog.tojiru.net/article/205007468.html
http://gajus.com/blog/2/the-definitive-guide-to-the-javascript-generators
https://github.com/rauschma/generator-examples/blob/gh-pages/nonblocking-counter/index.html
http://exploringjs.com/es6/ch_overviews.html
http://www.javascripture.com/DOMTokenList
http://youmightnotneedjquery.com/
http://azu.github.io/promises-book/
http://exploringjs.com/es2016-es2017/ch_async-functions.html#_writing-asynchronous-code-via-generators
https://github.com/loverajoel/jstips
https://www.sitepoint.com/react-higher-order-components/
https://www.sitepoint.com/5-typical-javascript-interview-exercises/?utm_content=buffer5f461&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer
http://www.jstips.co/en/javascript/
http://javascriptissexy.com/understand-javascript-callback-functions-and-use-them/#more-1037
https://www.sitepoint.com/currying-in-functional-javascript/
https://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript
https://ponyfoo.com/articles/es6-array-extensions-in-depth
https://speakerdeck.com/wakamsha/sore-motutosumatonishu-keruyo-javascript-kodowomotutoduan-ku-motutosinpurunishu-ku-tips-4xuan
https://javascript.info/js
https://davidwalsh.name/javascript-tricks
https://www.sitepoint.com/javascript-decorators-what-they-are/