Inheriting properties
JavaScript objects have a link to a prototype object. When trying to access a property of an object, the property will not only be sought on the object but on the prototype of the object, the prototype of the prototype, and so on until either a property with a matching name is found or the end of the prototype chain is reached.
Javascriptのオブジェクト(の__proto__プロパティ)は、(継承元の?)prototypeオブジェクトを指している。オブジェクトのプロパティにアクセスするとき、自身だけでなく、その__proto__が指すもの、さらにその__proto__が指すもの、も探すよ。アクセスしようとしているプロパティが見つかるか、あるいはprototypeチェーンの終端(null)に行き着くまで探すよ。
↑の情報をもとに考えていく。
<script> var C = function (name) { this.name = name; }; console.log(`one:${Object.getPrototypeOf(C)}`); console.log(`two:${C.__proto__===Object.getPrototypeOf(C)}`); console.log(`three:${C.__proto__===Function.prototype}`); console.log(`four:${C.__proto__===Object.prototype}`); var o = {a: 1}; console.log(`one:${Object.getPrototypeOf(o)}`); console.log(`two:${o.__proto__===Object.getPrototypeOf(o)}`); console.log(`three:${o.__proto__===Function.prototype}`); console.log(`four:${o.__proto__===Object.prototype}`); </script>
zz_5.php:13 one:function () { [native code] } zz_5.php:14 two:true zz_5.php:15 three:true zz_5.php:16 four:false zz_5.php:21 one:[object Object] zz_5.php:22 two:true zz_5.php:23 three:false zz_5.php:24 four:true
maeharin.hatenablog.comに書いてある通り、CにはFunctionオブジェクトがセットされる。
13行目:Object.getPrototypeOf(C)は、C.__proto__のこと。つまりFunction.prototype。
14行目:C.__proto__===Object.getPrototypeOf(C)}
これが__proto__,prototypeチェーンの定義ということなのだろう。なのでtrue。
15行目、16行目、maeharin.hatenablog.comに書いてある通りの結果といえる。
次に変数oに、オブジェクトリテラルを使って生成したオブジェクト(インスタンス)をセット。
21行目:Object.getPrototypeOf(o)
これはObject.prototypeのことなのだろう。
ここまでは問題ない。次にObject.createメソッド。
<script> var proto = {}; var obj = Object.create(proto); console.log(Object.getPrototypeOf(obj) === proto); //true </script>
新しいオブジェクトを生成する。どういうオブジェクトを生成するのか?
新しく生成するオブジェクトの__proto__プロパティが、(Object.create()の)引数に指定したオブジェクトを指す、そういうオブジェクトを生成する関数。
関数コンストラクタとnewでインスタンスを生成する場合、
let c1=new C();
をすると、c1.__proto__がC.prototypeを指すので、これは、
let c1=Object.create(C.prototype);
と同じこと。
<script> var C = function (name) { this.name = name; }; let c1=new C(); let c2=Object.create(C.prototype); console.log(c1.__proto__===c2.__proto__); //true </script>
c1とc2は別のオブジェクトなのだが、どちらもCというFunctionオブジェクトを基に生成されているので上記のように
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/create
// Shape - superclass function Shape() { this.x = 0; this.y = 0; } // superclass method Shape.prototype.move = function(x, y) { this.x += x; this.y += y; console.info('Shape moved.'); }; // Rectangle - subclass function Rectangle() { Shape.call(this); // call super constructor. } // subclass extends superclass Rectangle.prototype = Object.create(Shape.prototype); Rectangle.prototype.constructor = Rectangle; //If you don't set Object.prototype.constructor to Rectangle, //it will take prototype.constructor of Shape (parent). //To avoid that, we set the prototype.constructor to Rectangle (child). var rect = new Rectangle(); console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle); // true console.log('Is rect an instance of Shape?', rect instanceof Shape); // true rect.move(1, 1); // Outputs, 'Shape moved.'