Learning JavaScript
曖昧な知識をきちんと自分のものにしたい。
がわかりやすかった。
プロトタイプチェーン
var a = {name: 'a'}; var b = Object.create(a); console.log(b.__proto__ === a); // true console.log(b.name); // a
var c = {name: 'c'}; c.prototype = { say: function(){ alert(this.name); } }; var d = Object.create(c); console.log(d.__proto__ === c); // true console.log(d.say); // undefined
__proto__はプロトタイプチェーンの探索に使われる。 dのプロトタイプはcであって、c.prototypeではないので、d.say はundefined になる。
コンストラクタ関数とnew
function Dog(name) { this.name = name; } Dog.prototype = {bark: 'wooo!'}; var pochi = new Dog('pochi'); // pochi has own property 'name' console.log(pochi.name); console.log(pochi.hasOwnProperty('name')); // __proto__ equals to constractor's prototype console.log(pochi.__proto__ === Dog.prototype); // pochi does not have prototype console.log(pochi.hasOwnProperty('prototype')); // pochi can bark console.log(pochi.bark); // pochi.prototype is undefined console.log(pochi.prototype);
prototypeはnewでオブジェクト生成した際に、継承先の__proto__に代入されるという理解でよさそう。
スコープ
var variable = 'global'; function logger() { var variable = 'local'; console.log(variable); } function logger2() { variable = 'local'; console.log(variable); } console.log(variable); // global logger(); // local logger2(); // local console.log(variable); // local !!!
変数を新しく割り当てる時は、varで宣言する必要あり。 関数の{}がローカルスコープとなる。
this
function Dog(name) { this.name = name; this.say = function() { alert(this.name); }; } var pochi = new Dog('pochi'); var tama = { name: 'tama' }; tama.say = pochi.say; tama.say(); // tama pochi.say(); // pochi
関数はオブジェクトに束縛されず、thisは実行時に関数が属するオブジェクトを参照する。
call/apply
function say(greeting, period) { console.log(greeting + ', ' + this.name + period); } var person = { name: 'kotaroito' }; say.call(person, 'Hi', '.'); say.apply(person, ['Hello', '!']);
call/applyは束縛するthisオブジェクトを指定することができる。callとapplyの違いは第二引数以降で、callは引数を並べ、applyはArrayオブジェクトを渡す。
bind
function say(arg) { var str = 'My name is ' + this.name + '. I am a ' + arg + '.'; alert(str); } var pochi = { name: 'pochi' }; (say.bind(pochi))('dog');
bindは引数オブジェクトをthisに束縛した新しい関数をつくる。
まとめ
- ¥protoを辿ることでプロトタイプチェーンが実現される
- prototypeに設定されたオブジェクトはnew演算子によって、継承先オブジェクトのプロトタイプチェーンに入る
- 関数ブロックがローカルスコープとなり、解決できなければ1つ上のスコープを見る
- 関数はオブジェクトに束縛されずに、thisは実行時に関数が属するオブジェクトを参照する
- call/applyでthisが指すオブジェクトを指定できる
- bindは与えられた引数でをthisに束縛した関数を返す