【javascript】ロックとキーをシミュレートする

こちらの記事は以下の書籍を参考に執筆しました

- [入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)


以下のコードはロックとキーのシステムを構築している。

```javascript
function lock(secret){
  const key = Symbol('key')
  return {
    key,unlock(keyUserd){
      if(keyUserd==key){
        return secret;
      }else {
        return '*'.repeat(secret.length || secret.toString().length)
      }
    }
  }
}

const {key,unlock}=lock(42)

console.log(unlock())//**
console.log(unlock(Symbol('key')))//**
console.log(unlock('key'))//**
console.log(unlock(key))//42
```
>出典：[入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)



正しいキーならsecretを取得でき、正しくないならキーをマスクしている。

#コードの解説
このコードを読む上でわからないことがいくつかあった。

1. `return{key,unlock(...)}`とはどういうことか
2. unlock()で実行できるのはなぜか

#`return {key,unlock(...)}`とはどういうことか
`return {}`はオブジェクトを返しているということ。そしてオブジェクトには**簡易表記**という書き方ができる。

```javascript
const obj = {
  name: name,
  method: function() {}
}

//簡易表記
const obj = {
  name,
  method() {}
}
```
>出典：[入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)


プロパティ名(name)と変数名が同じ場合、一度指定すればいいだけになる。
`{name:name}`と書いていたのが`{name}`で済む。
またメソッドに関しては無名関数に限り`{method:function(){}}`が`{method()}`と書ける。

つまりlock関数を書き換えるとこういうこと

```javascript
function lock(secret){
  const key = Symbol('key')
  return {
    key:key,
    unlock:function(keyUserd){
      if(keyUserd==key){
        return secret;
      }else {
        return '*'.repeat(secret.length || secret.toString().length)
      }
    }
  }
}
```
>出典：[入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)



そして`const {key,unlock}=lock(42)`で変数keyに`Symbol('key')`が代入され、変数unlockには無名関数が代入されている。


#unlock()で実行できるのはなぜか
これは勘違いであった。

その原因となったコードがこちら

```javascript
const ffaa={
  at(n){
    if(n<=2)return 1;
    return this.at(n-1)+this.at(n-2);
  }
}

const {at}=ffaa;
const ff={at}
const aa={ff:at}

ffaa.at(7)//13
at(7)//エラー
ff.at(7)//13
aa.ff(7)//エラー
```
>出典：[入門JavaScriptプログラミング](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1F76CKY9CIJ66&dchild=1&keywords=%E5%85%A5%E9%96%80javascript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0&qid=1595991879&s=books&sprefix=%E5%85%A5%E9%96%80javascript%2Cstripbooks%2C-1&sr=1-3)



これだけを見ると、無名関数を分割した際、単純に`変数名()`では実行でいなものと思ってしまった。
確かに関数を名前で参照出来ないこともあるが、それは**関数内のメンバーを参照するとき**である。