ios 4% Android 10% Python 1% Design 15% Web(PHP/JS) 10% Windows(C#) 20% 40%
最近のボク お嫁 Web/WordPress Windows Android Design Python Python Android 1% 5% Design Windows 5% 15% お嫁 50% Web/WordPress 25% 2013年6月1日 株式会社フォーエンキー調べ 愛 恐
Simple and Powerfull
var obj = {}
var obj = { } key: value
var f = function() {...}
var obj = { } key: function() {...}
var obj = { } key: function() {...}
( _ )
( _ )
クラス Class (型) new new new クラスという 型 を元にして オブジェクトを生成するイメージ クラスから生成されたオブジェクトは クラスの特性 属性や機能 を受け継ぐ Object 実体 Object 実体 Object 実体
Object (実体) prototype dele gate dele gate dele gate プロトタイプ オブジェクトは 自分自身が備えて いない特性 機能や属性 を 別の オブジェクトにお願い 委譲 する イメージ この時 お願いする先を プロトタイプ と言ったりします Object 実体 Object 実体 Object 実体
var obja = { name : 'Yome', say : function () { alert('i Love ' + this.name); } }; var objb = { name : 'Nikole' }; objb. proto = obja; var objc = { }; objc. proto = objb; objc.say(); I Love Nicole
var obja = { name : 'Yome', say : function () { alert('i Love ' + this.name); } }; var objb = { name : 'Nikole' }; objb. proto = obja; var objc = { }; objc. proto = objb; objc.say();
objc.say objc. proto.say (objb) objc. proto. proto.say (objb) (obja)
objc.name objc. proto.name (objb) objc. proto. proto.say (objb) (obja)
obj. proto. proto.property このように 自分に無い機能や属性を proto に入っている別のオブジェクトから 連鎖的に検索して探す仕組みが
obj. proto. proto.property
var obja = { name : 'Yome', say : function () { alert('i Love ' + this.name); } }; var objb = { name : 'Nikole' }; objb. proto = obja; var objc = { name : 'Gyu-Ri' }; objc. proto = obja; objb.say(); // I Love Nikole objc.say(); // I Love Gyu-Ri
class A extends class B extends class C new obj A of B obj A (delegete) obj B (delegete) obj C (delegete) obj D new new obj B of C obj C of C (delegete) obj F (delegete) obj E
あまり見たコトない obj. proto = otherobj 実は proto は標準仕様ではありません つまり proto が利用できない環境もあり だから通常 このようなことはしません ここまでは プロトタイプチェインの概念を分かり易くするために proto を使って 説明していましたが そういうことなので 実際のプログラミングではこんなことしな いでくださいねー ( )/ では 逆に 良く見かけるのは
こっちのが よく見る感じ var o = new Person('Nicole') これは new 演算子とコンストラクタ関数によるオブジェクトの生成です JavaScript におけるオブジェクトの生成で よく見られるコードです このあたりの記法が クラスベースの言語を学んだ方を惑わしますね
var Person = function (name) { this.name = name; } Person.prototype.sayHello = function() { alert('hello ' + this.name); } var person = new Person('Nicole');
var Person = function (name) { } this.name = name; Person.prototype.sayHello = function() { } alert('hello ' + this.name); var person = new Person('Nicole');
var Person = function (name) { } this.name = name; Person.prototype.sayHello = function() { } alert('hello ' + this.name); var person = new Person('Nicole');
var o = new Person('Nicole')
var newobj = {}; newobj. proto = Person.prototype; Person.apply(newObj, arguments); return newobj;
だいたいこんな意味 var newobj = {}; newobj. proto = Person.prototype; ①新しい Object が 生成される Person.apply(newObj, arguments); return newobj; new する度に 新しい個別のオブジェクトが生成されます
だいたいこんな意味 var newobj = {}; newobj. proto = Person.prototype; Person.apply(newObj, arguments); return newobj; ②プロトタイプのオブ ジェクトの参照を代入 コンストラクタ関数の Person.prototype を 新しいオブジェクトの proto に 参照を代入し プロトタイプチェインの仕組みで その特性を継承します
だいたいこんな意味 var newobj = {}; ③ newobj を this に コンストラクタ 関数を実行 newobj. proto = Person.prototype; Person.apply(newObj, arguments); return newobj; これによって コンストラクタ関数の中で 生成される新しいオブジェクトを this と して参照し その属性をセットしたりできるようになります
だいたいこんな意味 var newobj = {}; newobj. proto = Person.prototype; ④完成した オブジェクトを返す Person.apply(newObj, arguments); return newobj; Person.prototype の特性を継承し コンストラクタ関数によって初期化済みの 新しいオブジェクトが返され プログラムで利用できるようになります
newobj. proto = Person.prototype;
整理すると proto プロトタイプチェインで 検索されるプロトタイプ オブジェクトが入ってる プロトタイプチェインで 使われるもの prototype プロトタイプオブジェク トの控え室 new とコンストラクタ 関数でオブジェクトを生 成する時に proto に代入される オブジェクト生成で 使われるもの
(function() { var Person = function (name){ this.name = name; }; Person.prototype.name = 'nanashi'; Person.prototype.say = function () { alert('i Love ' + this.name); }; var p = new Person('Nicole'); alert( p. proto === Person.prototype ); // true p.say(); // I Love Nicole p.name = 'Gyu-Ri'; p.say(); // I Love Gyu-Ri Person.prototype.name = 'Ha-Ra'; p.say(); // I Love Gyu-Ri delete p.name; p.say(); // I Love Ha-Ra })();
(function() { var Person = function (name){ this.name = name; }; Person.prototype.name = 'nanashi'; Person.prototype.say = function () { alert('i Love ' + this.name); }; Person: { prototype: { name:'nanashi' say: functon () { } } } var p = new Person('Nicole'); alert( p. proto === Person.prototype ); p.say(); })(); p.name = 'Gyu-Ri'; p.say(); Person.prototype.name = 'Ha-Ra'; p.say(); delete p.name; p.say();
(function() { var Person = function (name){ this.name = name; }; Person.prototype.name = 'nanashi'; Person.prototype.say = function () { alert('i Love ' + this.name); }; Person: { prototype: { name:'nanashi' say: functon () { } } } var p = new Person('Nicole'); alert( p. proto === Person.prototype ); p.say(); p.name = 'Gyu-Ri'; p.say(); var newobj = {}; newobj. proto = Person.prototype.name = 'Ha-Ra'; p.say(); delete p.name; p.say(); Person.apply(newObj, ['Nicole']) return newobj; })();
(function() { var Person = function (name){ this.name = name; }; Person.prototype.name = 'nanashi'; Person.prototype.say = function () { alert('i Love ' + this.name); }; Person: { prototype: { name:'nanashi' say: functon () { } } } var p = new Person('Nicole'); alert( p. proto === Person.prototype ); p.say(); p.name = 'Gyu-Ri'; p.say(); Person.prototype.name = 'Ha-Ra'; p.say(); delete p.name; p.say(); p: { name:'nicole' proto : } })();
(function() { var Person = function (name){ this.name = name; }; Person.prototype.name = 'nanashi'; Person.prototype.say = function () { alert('i Love ' + this.name); }; Person: { prototype: { name:'nanashi' say: functon () { } } } var p = new Person('Nicole'); alert( p. proto === Person.prototype ); p.say(); p.name = 'Gyu-Ri'; p.say(); Person.prototype.name = 'Ha-Ra'; p.say(); delete p.name; p.say(); p: { name:'nicole' proto : } })();
(function() { var Person = function (name){ this.name = name; }; Person.prototype.name = 'nanashi'; Person.prototype.say = function () { alert('i Love ' + this.name); }; Person: { prototype: { name:'nanashi' say: functon () { } } } var p = new Person('Nicole'); alert( p. proto === Person.prototype ); p.say(); p.name = 'Gyu-Ri'; p.say(); Person.prototype.name = 'Ha-Ra'; p.say(); delete p.name; p.say(); p: { name:'nicole' proto : } })();
(function() { var Person = function (name){ this.name = name; }; Person.prototype.name = 'nanashi'; Person.prototype.say = function () { alert('i Love ' + this.name); }; Person: { prototype: { name:'nanashi' say: functon () { } } } var p = new Person('Nicole'); alert( p. proto === Person.prototype ); p.say(); p.name = 'Gyu-Ri'; p.say(); Person.prototype.name = 'Ha-Ra'; p.say(); delete p.name; p.say(); p: { name:'gyu-ri' proto : } })();
(function() { var Person = function (name){ this.name = name; }; Person.prototype.name = 'nanashi'; Person.prototype.say = function () { alert('i Love ' + this.name); }; Person: { prototype: { name:'ha-ra' say: functon () { } } } var p = new Person('Nicole'); alert( p. proto === Person.prototype ); p.say(); p.name = 'Gyu-Ri'; p.say(); Person.prototype.name = 'Ha-Ra'; p.say(); delete p.name; p.say(); p: { name:'gyu-ri' proto : } })();
(function() { var Person = function (name){ this.name = name; }; Person.prototype.name = 'nanashi'; Person.prototype.say = function () { alert('i Love ' + this.name); }; Person: { prototype: { name:'ha-ra' say: functon () { } } } var p = new Person('Nicole'); alert( p. proto === Person.prototype ); p.say(); p.name = 'Gyu-Ri'; p.say(); Person.prototype.name = 'Ha-Ra'; p.say(); delete p.name; p.say(); p: { name:'gyu-ri' proto : } })();
function myfunc() { } var name = 'Gyu-Ri'; myfunc(); alert(name); //ReferenceError
var a = 123; function func1() { var b = 3; function func2() { var c = 2; alert(a * b * c); //738 } } func2(); func1();
var name = 'Nicole'; function myfunc() { var name = 'Gyu-Ri'; } myfunc(); alert(name); //Nicole
var name = 'Nicole'; function myfunc() { name = 'Gyu-Ri'; } myfunc(); alert(name); //???
var name = 'Nicole'; function myfunc() { } name = 'Gyu-Ri'; myfunc(); alert(name); //Gyu-Ri
var name = 'Nicole'; function myfunc() { Before var name = 'Gyu-Ri'; }
var name = 'Nicole'; function myfunc() { After name = 'Gyu-Ri'; }
var name = 'Nicole'; function myfunc() { var name = 'Gyu-Ri'; var }
var a = 123
var a = 123; function func1() { var b = 3; function func2() { var c = 2; alert(a * b * c); } } func2(); func1(); //738
var a = 123; function func1() { var b = 3; function func2() { var c = 2; alert(a * b * c); } } func2(); func1(); //738
var a = 123; function func1() { var b = 3; function func2() { var c = 2; alert(a * b * c); } } func2(); func1(); //738
var a = 123; function func1() { var b = 3; function func2() { var c = 2; alert(a * b * c); } } func2(); func1(); //738
scope.a (func2) scope. scope.a (func2) (func1) scope. scope. scope.a (func2) (func1) (global)
scope. scope. scope.identifier このように 今のスコープに無い識別子を より外側のスコープから連鎖的に 検索して探す仕組みが
scope. scope. scope.identifier
余談ですが 実はJavaScriptでは 変数のスコープでさえも 内部的にはオブジェクトで構成されています 変数オブ ジェクト つまり つまるところ スコープチェイン も プロトタイプチェイン も オブジェクトの特 殊なプロパティによる連結リストによるデータ構造と それを終端に向かって連鎖的に検索するという よく 似たシンプルな仕組みに過ぎません またこれは JavaScriptにおけるスコープの実体が グローバルスコー プ グローバル変数オブジェクト をrootとする 変数オブジェクトが連なった巨大なオブジェクトのツ リー構造だということでもあります 興味深いですね 残念ながら それらのスコープを構成するオブジェクトのツリーを プログラマが直接参照することは出来ま せん しかし プロトタイプチェインを構成する proto 属性については ECMA Script標準では無いも のの 幾つかのブラウザ実装では実際に目にしてその仕組みを確認することが出来ます これを良く観察す ることで スコープチェイン と プロトタイプチェイン 両方の理解を深めることが出来るはずです
var a = 123; function func1() { var b = 3; function func2() { var c = 2; alert(a * b * c); } ( ) } func2(); func1(); //738
var a = 123; function func1() { var b = 3; function func2() { var c = 2; alert(a * b * c); } } func2(); func1(); //738
var a = 123; function func1() { var b = 3; function func2() { var c = 2; alert(a * b * c); } } func2(); func1(); //738
var a = 123; function func1() { var b = 3; function func2() { var c = 2; alert(a * b * c); } } func2(); func1(); //738
var Person = (function($) { var privatevalue = 'Hogeta'; function Person(name) {... } Person.prototype.xxxx =... return Person; })(jquery);
function newcounter() { } var i = 0; return function() { } i = i + 1; return i; var c1 = newcounter(); alert(c1()); // 1 alert(c1()); // 2 alert(c1()); // 3
var Person = function (name) { this.name = name; } Person.prototype.sayHello = function() { alert('hello ' + this.name); } var person = new Person('Nicole'); var btn = $('button#say-hello'); btn.on('click', function() { person.sayhello(); });
var Person = function (name) { this.name = name; } Person.prototype.sayHello = function() { alert('hello ' + this.name); } var person = new Person('Nicole'); var btn = $('button'); btn.on('click', person.sayhello);
var obj = { } key: function() {...}
person sayhello btn.on('click', person.sayhello);
sayhello btn.on('click', person.sayhello);
person.sayhello();
...nothing... sayhello();
function sayhello() { alert('hello ' + this.name); } sayhello(); global object = window 関数のコール時にレシーバーが無い時 this はグローバルオブジェクトになります ブラウザ実装の場合 これは通常 window オブジェクトです
call apply bind
call(object, arg1, arg2,...) apply(object, Array) bind(object, arg1, arg2,...)
call apply
call の例 function say(arg1, arg2) { alert(arg1 + this.name + arg2); } var person = new Person('Nicole'); say.call(person, 'Hello ', ' chan'); person を this として実行 call の第1引数が this に 第2引数以降の引数が say関数の引数に
apply の例 function say(arg1, arg2) { alert(arg1 + this.name + arg2); } var person = new Person('Nicole'); say.apply(person, ['Hello ', ' chan']); person を this として実行 call の第1引数が this に 第2引数の 配列の内容が say関数の引数になる 引数の渡し方以外は call と同じ
var p1 = { name: 'Gyu-Ri', say: function (arg1, arg2) { alert(arg1 + this.name + arg2); } }; var person = new Person('Nicole'); p1.say.call(person, 'Hello ', ' chan');
var p1 = { name: 'Gyu-Ri', say: function (arg1, arg2) { alert(arg1 + this.name + arg2); } }; var person = new Person('Nicole'); p1.say.call(person, 'Hello ', ' chan');
bind
function say(arg1, arg2) { alert(arg1 + this.name + arg2); } var person = new Person('Nicole'); var say2 = say.bind(person); say2('hello ', ' chan');
bind
var Person = function (name) { this.name = name; } Person.prototype.sayHello = function() { alert('hello ' + this.name); } var person = new Person('Nicole'); var btn = $('button'); btn.on('click', person.sayhello);
var Person = function (name) { this.name = name; } Person.prototype.sayHello = function() { alert('hello ' + this.name); } var person = new Person('Nicole'); var btn = $('button'); btn.on('click', person.sayhello.bind(person));
apply
// this function bind (self, func) { return function () { return func.apply(self, arguments); }; } // function Person (name) { this.name = name; this.say = bind(this, this.say); } Person.prototype.say = function (prefix) { alert(prefix + this.name); } // var person = new Person('Nicole'); // nicole.say('i Love '); // I Love Nicole // OK settimeout(person.say.bind(null, 'I Just Realy Love to '), 2000);
var obj = {}
@yuka2py http://www.amazon.co.jp/dp/4798129682