【JavaScript】Object.(getOwnPropertyDiscriptor| getOwnPropertyNames | create | preventExtenstions | __proto__)のこと

【JavaScript】Object.(getOwnPropertyDiscriptor| getOwnPropertyNames | create | preventExtenstions | __proto__)のこと

image

先の記事「【JavaScript】この際はっきりさせる!Object.create ,Object.defineProperty,Object.definePropertiesの違い」で改めて学んでいましたが、
表題のこと、コンソール叩いて、確認しながらやったら理解できました。
特に__proto__とprototypeとか、Object.prototypeってなんだって思っていたのですが、開眼しました。
Object.createはとてもcoolです。
でわまたーーー。

Object.getOwnPropertyDiscriptor
ver obj = {a: 1};
Object.getOwnPropertyDiscriptor(obj, "a");
objがもつ第二引数のプロパティのディスクリプタを返す
//Object {value: 1, writable: true, enumerable: true, configurable: true}
configurable:true
enumerable:true
value:1
writable:true
__proto__:Object

Object.getOwnPropertyNames
Object.key()はオブジェクトがもつ独自propertyのみの列挙可能なpropertyを配列で返すが、
Object.getOwnPropertyNamesは列挙可能なpropertyだけでなく、指定したオブジェクトのすべての独自propertyの名前が返される(列挙不可能のプロパティも)
/////e.g
ver obj = {a: 1};
Object.getOwnPropertyNames(obj)
objが自身が持つプロパティを配列で返す
//["a"]

////e.g
var arr = ['a', 'b', 'c'];
console.log(Object.getOwnPropertyNames(arr).sort());
// ["0", "1", "2", "length"]
//列挙不可能な独自のプロパティ「length」も返す
///Object.keysは、、
var arr = ['a', 'b', 'c'];
Object.keys(arr)
["0", "1", "2"]

ES5とES6のプリミティブ型を渡した時の挙動の違い
/////ES5
Object.getOwnPropertyNames('foo');
// TypeError: "foo" is not an object (ES5 code)

///ES6
強制的なラッパーオブジェクトへの型変換が起きる
Object.getOwnPropertyNames('foo');
// ["0", "1", "2", "length"] (ES6 code)
// ES6 の結果は ES5 における次のコードと等価
Object.getOwnPropertyNames(Object('foo'));
仕様

Object.isPrototypeOf
[対象objのprototype].isPrototypeOf(obj)//第一引数objが対象を継承しているか判定
ver obj = {a: 1};
Object.prototype.isPrototypeOf(obj);
//true
var obj4 = {z: 1};
var obj6 = {c : 2};
obj4.__proto__ = obj6
obj6.isPrototypeOf(obj4);
//true

/////////e.g
var p = {x: 1};
var o = Object.create(p);
p.isPrototypeOf(o)//oはpを継承していますか??
//true
Object.isPrototypeOf(p)//pはObjectを継承していますか??
//true pはObject.prototypeを継承している

Object.crate
第一引数を__proto__の参照先、第二引数を自身がもつ{properties : {ディスクリプタ}}とした新しいオブジェクトを返す
var ff = Object.create(null, {p: {value: "p"}});
ff
//{p: "p"};
//__proto__の参照先はnull
//Object.prototypeすらもたない
Object.getPrototypeOf(ff)
//null
'toString' in ff;
//false

var ff = Object.create({}, {p: {value: "p"}});
ff
//{p:"p", __proto__: obj} //objは{__proto__: {Object.prorotype}}

obj1 = {c: "c"};
obj1
//objct {c: "c", __proto__: obj}
obj2 = Object.create({}, {c: {value: "c"}});
obj2
//objct {c: "c", __proto__: obj}

var i = {}//空オブジェクト
i;
//objct {__proto__: obj}//空でも基底オブジェクトの参照を持つ

自身のプロパティpを持ち__proto__先に{}を指定
var i = {c: "c"};
var s = Object.create({},{p: {value: "p"}});
s
//{p: "p", __proto__: obj}
s.__proto__;
//{__proto__: obj}

「新たに作るpは__proto__の参照先にoをもち,自身のプロパティpに"p"を持つ」の意
var o = {a: "a"};
var p = Object.create(o, {p: {value: "p"}});

function Constructor(){}
var o = new Constructor;
o
//{__proto__: {}}
o.__proto__
//{
constructor : function Constructor {}
__proto__: {}
}

Constructor.prototype
//
{constructor: function Constructor{}, __proto__: {}}

//親としてConstructorを継承するインスタンスoを作る
以下は新しく生成されるoの__proto__の参照先に{constructor: function Constructor{}, __proto__: {}}を設定する
var o = Object.create(Constructor.prototype)
//以下と同じ
var o = new Constructor();

object.crateがやっていること
if (!Object.create) {
Object.create = function (o) {
if (arguments.length > 1) {
throw new Error('Object.create implementation only accepts the first parameter.');
}
function F() {}
F.prototype = o;
return new F();
};
}

プロトタイプ継承したコードをより直感的に記述できる
function MyClass(){};
var Proto = {z: 1, x: 3};//プロトタイプオブジェクト
MyClass.protoype = Proto;
var obj = new MyClass();
--------------------------
creteを使うと

var Proto = {z: 1, x : 3};//プロトタイプオブジェクト
var obj = Object.create(Proto);
----------------------------

var obj = {x: 2, y: 4};
下と等価(createを使うとdefaultがfalseな属性を明示的に設定できる)
var obj = Object.create(Object.prototype, {x: {value: 2, writable: true, enumerable: true, configurable: true}, y: {value: 4, writable: true , enumerable: true, configurable: true}});

--------------------------

prototype(__proto__)

__proto__(オブジェクトの暗黙リンク)
__proto__が参照するオブジェクトが「prototypeオブジェクト」
function MyClass(){};
var obj = new MyClass();
MyClass.prototypeとobj.__proto__は同じオブジェクトを参照する

function MyClass(){}
MyClass.prototype
//Object
//constructor:MyClass()
// __proto__:Object

var obj = new MyClass();
obj.__proto__
//Object
//constructor:MyClass()
//__proto__:Object
※__proto__:Objectは Objectプロパティ
※MyClass.prototypeの参照オブジェクトはMyClassのプロトタイプオブジェクトではなく「Function.prototypeの参照先オブジェクト」
※オブジェクトをインスタンス化する際にプロトタイプとして使用するオブジェクトへのポインタ。

function f(){}
f.prototype.__proto__
//obj
※3

var f = new f();
f
//object f
__proto__:{
constructor:f()
__proto__:Object
}

Object.getPrototypeOf
Object.getPrototypeOf(ins)//インスタンス
暗黙リンク(__proto__)の参照先オブジェクトを返す
オブジェクトからプロトタイプオブジェクトを取得する方法

function MyClass(){};
var bb = MyClass.prototype;
bb.__proto__;
//※3

//ES5
var b = new MyClass();

//インスタンスオブジェクトから暗黙リンクの参照先オブジェクトを取得
var bb = Object.getPrototypeOf(b)
//Object {constructor: function Myclass(){}, __proto__: Object//※3}

//インスタンスオブジェクトから取得
var bb = b.__proto__;

//インスタンスオブジェクトからコンストラクタを経由した取得
var bb = b.constructor.prototype;

__proto__はgetPrototypeOfに置き換えれる

isPrototypeOf
プロトタイプオブジェクトの確認

////////////////////////
function f () {};
fn.constructor === Function
//true
fn.__proto__ === Function.prototype
//true

Object.preventExtensions/Object.isExtensible
プロパティの追加不可
var obj = {x: 1, y: 2};
Object.preventExtensions(obj);
Object.isExtensible(obj)
//false 追加できない
obj.z = 3;
Object.keys(obj)
//[x , y]//追加されていない

Object.seal/Object.isSealed
プロパティの追加と削除不可
var obj = {x: 1, y: 2};
Object.seal(obj)
確認
Object.isSealed(obj)
//true
obj.x = 10;
obj
{x: 10, y: 2}//変更はできる

Object.freeze/Object.isFrozen
プロパティの追加と削除と変更不可
var obj = {x: 1, y: 2};
Object.freeze(obj);
//確認
Object.isFrozen(obj)
//true
Object {x: 1, y: 2}
obj.z = 5
obj
{x: 1, y: 2}//追加できない
delete obj.z
obj
// {x: 1, y: 2}削除できない
obj.x = 20
obj.x変更できない
//1

Object.keys
Object.keys(o)
継承を含むプロパティ名を返す

※トップレベルコード・・・関数の外
※上位互換・・・より制約が厳しくなること(feezeはsealの上位互換)
※Object.prototype

__defineGetter__:__defineGetter__()
__defineSetter__:__defineSetter__()
__lookupGetter__:__lookupGetter__()
__lookupSetter__:__lookupSetter__()
constructor:Object()
hasOwnProperty:hasOwnProperty()
isPrototypeOf:isPrototypeOf()
propertyIsEnumerable:propertyIsEnumerable()
toLocaleString:toLocaleString()
toString:toString()
valueOf:valueOf()
get __proto__:__proto__()
set __proto__:__proto__()

他のJavaScript記事
JavaScript問題集