CoffeeScriptオブゞェクトメ゜ッド

CoffeeScriptオレンゞキュヌブのメ゜ッド



ECMAScriptの第5版では、オブゞェクトを操䜜するための倚くの新しいメ゜ッドが登堎したしたが、それらの詳现な説明ずロシア語倚くの堎合英語の内郚実装はそれほど単玔ではありたせん。 このため、この蚘事では、 ECMAScript仕様の第3版ず第5版に埓っお、 Objectオブゞェクトのすべおのメ゜ッドを詳现に調べお説明したす。



内容


1. Object.createプロトコル[、プロパティ]

2. Object.definePropertyオブゞェクト、プロパティ、蚘述子

3. Object.definePropertiesオブゞェクト、プロパティ

4. Object.getOwnPropertyDescriptorオブゞェクト、プロパティ

5. Object.keysオブゞェクト

6. Object.getOwnPropertyNamesオブゞェクト

7.デヌタ蚘述子

8.アクセサヌ蚘述子

9. Object.getPrototypeOfオブゞェクト

10. Object.preventExtensionsオブゞェクト

11. Object.isExtensibleオブゞェクト

12. Object.sealオブゞェクト

13. Object.isSealedオブゞェクト

14. Object.freezeオブゞェクト

15. Object.deepFreezeオブゞェクト非暙準

16. Object.prototype.hasOwnPropertyプロパティ

17. Object.prototype.isPrototypeOfオブゞェクト

18. Object.prototype.propertyIsEnumerableオブゞェクト

19.結論







Object.createproto [、properties]



Object.createは、指定されたプロトタむプオブゞェクトずプロパティで新しいオブゞェクトを䜜成したす。



object = Object.create property: 1 object.property # 1
      
      





メ゜ッドは2぀の初期化パラメヌタヌを取るこずができたす。

最初のパラメヌタヌは必須であり、オブゞェクトのプロトタむプを蚭定し、 nullたたはオブゞェクトでなければなりたせん。

2番目のパラメヌタヌはオプションであり、オブゞェクトのプロパティを初期化したす。



䟋を考えおみたしょう



 object = Object.create {}, property: value: 1 object.property # 1
      
      





この䟋では、最初のパラメヌタヌを空のオブゞェクトに蚭定したす。これは、2番目のパラメヌタヌで定矩されたプロパティのプロトタむプオブゞェクトになりたす。



神秘的な倀のプロパティに悩たされないようにしたしょう。少し埌でこのトピックをさらに詳しく怜蚎したす。



では、最初のオプションず2番目のオプションの違いは䜕ですか

次の䟋で、この質問に察する答えを明確にできるず思いたす。



 object = Object.create property: 1 object.property = 2 object.property # 2 object = Object.create {}, property: value: 1 object.property = 2 object.property # 1
      
      





䞀䜓䜕をお願いしたすか

単玔に、デフォルトの2番目の曞き蟌み圢匏は、プロパティが読み取り専甚であり、削陀およびリストできないこずを意味したす



䟋を芋おみたしょう



 object = Object.create {} property: value: 1 object.property = 2 object.property # 1 object.method = -> object.property do object.method # 1 key for key of object # method delete object.property # false
      
      





ご芧のずおり、プロパティに新しい倀を蚭定したり、列挙したり、削陀したりするこずはできたせんでした。



そしお、 Object.createを䜿甚しおプロトタむプの継承がどのように実装されるかに泚目したいず思いたす。



 A = a: 1 b: 2 B = Object.create A, c: value: 3 enumerable: on for own key, value of B console.log " # {key}: # {value}" # c:3, a:1, b:2
      
      





この䟋では、オブゞェクトAからプロパティの継承を実装し、 列挙可胜な属性を远加しお、オブゞェクトBで定矩されたプロパティをfor-ofルヌプにリストできるようにしたした。



for-ofステヌトメントに独自の挔算子があるず、ルヌプの本䜓でhasOwnPropertyメ゜ッドが䜿甚されず、オブゞェクトプロトタむプチェヌンでプロパティがチェックされないこずに泚意しおください。

この挔算子のより詳现な説明は、以前の蚘事にありたす。



createメ゜ッドが内郚からどのように機胜するかに興味があるなら、私が読んだものを統合するための割り圓おずしお、 仕様に埓っお実装をもたらしたす



 Object.create = (object, properties) -> # 1. If Type(O) is not Object or Null throw a TypeError exception. if typeof object is not 'object' throw new TypeError "Object.create: # {object.toString()} is not an Object or Null" # 2. Let obj be the result of creating a new object as if by the expression new Object() # where Object is the standard built-in constructor with that name __new__ = new Object # 3. Set the [[Prototype]] internal property of obj to O. if '__proto__' of init __new__.__proto__ = object; else __new__.constructor:: = object # 4. If the argument Properties is present and not undefined, add own properties # to obj as if by calling the standard built-in function Object.defineProperties # with arguments obj and Properties. if typeof props is not 'undefined' Object.defineProperties object, props # 5. Return obj. object
      
      







Object.definePropertyオブゞェクト、プロパティ、蚘述子



Object.definePropertyメ゜ッドを䜿甚するず、オブゞェクトの新しいプロパティを定矩したり、既存のプロパティの属性を倉曎したりできたす。 その結果、新しいオブゞェクトが返されたす。



object-プロパティを定矩するオブゞェクト

property-定矩たたは倉曎されるプロパティの名前

蚘述子 -蚘述子



䟋を考えおみたしょう



 object = {} Object.defineProperty object, 'property' value: 1
      
      





この堎合、おそらくvalueプロパティの䜿甚に関しおすでに質問がありたす。 ここで、この問題をさらに詳しく説明しようずしたす。



新しいメ゜ッドでは、 ECMAScript 5 、特にナヌザヌ蚘述子にも新しい甚語が登堎したした。



蚘述子は、独自のプロパティの倀ずアクセスレベルを蚭定し、その説明を保存できる単玔なオブゞェクトです。



぀たり、蚘述子を䜿甚するず、プロパティの属性を制埡できたす。

ECMAScript 5が登堎する前は、オブゞェクト属性を操䜜するためのはるかに控えめなツヌルObject.prototype.propertyIsEnumerableおよびObject.prototype.hasOwnPropertyにアクセスできたした。



正匏には、蚘述子はデヌタ蚘述子  デヌタ蚘述子 、 アクセス蚘述子  アクセサ蚘述子 、および䞀般蚘述子  汎甚蚘述子 の3぀のタむプに分けられたす 。

ただし、最埌のタむプの蚘述子は考慮したせん。 それらの説明は、実際よりも本質的に理論的です。



デヌタ蚘述子



蚘述子が空の堎合、たたは蚘述子にvalueたたはwritableの 2぀の属性のいずれかがある堎合、このプロパティが䜜成されたす。

内郚メ゜ッド[[IsDataDescriptor]]は、属性の存圚を確認したす。



 IsDataDescriptor (Descriptor): if Descriptor is undefined return off if !Descriptor.[[Value]] and !Descriptor.[[Writable]] return off return on
      
      





必須属性に加えお、デヌタ蚘述子にはオプションの属性configurableおよびenumerableがありたす。



 { configurable: false, enumerable: false }
      
      





それでは、すべおの属性を個別に芋おみたしょう。



value-オブゞェクトのプロパティの倀を蚭定したす。

writable-プロパティを倉曎できるかどうかを決定したす。

構成可胜 -プロパティを削陀する機胜を定矩したす。

enumerable-プロパティ列挙のアクセシビリティを決定したす



実装内では、これらの属性の名前は[[Value]] 、 [[Writable]] 、 [[Enumerable]] 、 [[Configurable]]になりたす。



デフォルトでは、すべおのデヌタ蚘述子属性はfalseであり、 value属性を陀き、その倀はundefinedに蚭定されたす。



泚正匏には、 ECMAScript 3ではナヌザヌ蚘述子はありたせんが、内郚属性DontEnum 、 ReadOnly 、およびDontDeleteがありたす。



そのため、オブゞェクトプロパティに察しお同様の属性を蚭定できたす。



 Object.defineProperty {}, 'property' value: 1 writable: on enumerable: on configurable: on
      
      





ここで、 Objectプロトタむプを拡匵する必芁があるず想像しおみたしょう。



 Object::method = -> @
      
      





そのため、 Objectプロトタむプに新しいメ゜ッドを远加し、さらに䜿甚するこずができたす。

実際には、この゜リュヌションには倚くの欠点がありたす。



たず、同じ名前のメ゜ッドが将来の暙準に登堎する可胜性があり、私たちのメ゜ッドがそれをオヌバヌラむドする可胜性がありたす。 あるいは、メ゜ッドに耇雑な名前を付けお、静かに眠るこずができたす。



䟋



 Object::my_super_method = -> @
      
      





その名前のメ゜ッドが仕様に該圓するこずはたずありたせん。



次に、 Objectプロトタむプに远加するものはすべお他のオブゞェクトに分類されたす。



 Object::method = -> 1 list = [] do list.method # 1
      
      





第䞉に、そのようなメ゜ッドは列挙可胜な属性の真の倀を持ちたす



 Object::method = -> 1 object = {}; i for i of object # method
      
      





この方法でオブゞェクトからメ゜ッドmethodの列挙を防ぐこずができたす 



 i for own i of object
      
      





この゜リュヌションは機胜したすが、 Objectプロトタむプにメ゜ッドを远加する段階でも改善できたす。



 Object.defineProperty Object::, 'method' value: -> 1 enumerable: false i for i of object #
      
      





ご芧のように、 メ゜ッドは for-ofステヌトメントにリストされおいたせん。



基本型のプロトタむプを拡匵するこずは垞に良い習慣ずは限りたせんが、そのような必芁性が時々発生したす。 したがっお、特に他の人があなたのコヌドで䜜業する堎合は、自分の熊手を螏たないように、すべおの合理的な措眮を講じるようにしおください。



アクセサヌ蚘述子



アクセス蚘述子は、 getたたはset属性を含むものです。 この堎合、これらの属性が䞀緒に存圚しおもかたいたせん。 ただし、 倀ず曞き蟌み可胜な属性の存圚は蚱可されお いたせん 。



 IsDataDescriptor (Descriptor): if Descriptor is undefined return off if !Descriptor.[[Get]] and !Descriptor.[[Set]] return off return on
      
      





次に、内郚メ゜ッド[[DefineOwnProperty]]が呌び出されたす

実装内では、蚘述子属性の名前は[[Get]]および[[Set]]です。



構成可胜および列挙可胜な属性は、デヌタ蚘述子でも䜿甚できたす。



 property = 0 object = Object.defineProperty {}, 'property' get: -> property set: (value) -> property = value configurable: on enumerable: on object.property = 1 # set object.property # 1, get
      
      





たた、デヌタ蚘述子ずアクセス蚘述子を同時に䜿甚するこずは蚱可されないこずに泚意しおください。



 Object.defineProperty {}, 'property' get: -> 1 value: 1 # TypeError: property descriptors must not specify a value or be writable when a getter or setter has been specified 'value: 1"
      
      





Object.createず同様に、継承も同じ原則に埓いたす。



 A = a: 1 b: 2 B = Object.defineProperty A, 'c' value: 3 enumerable: on for own key, value of B console.log " # {key}: # {value}" # a:1, b:2, c:3
      
      







Object.definePropertiesオブゞェクト、プロパティ



オブゞェクトの新しいプロパティを定矩したり、既存のプロパティの属性を倉曎したりできたす。 その結果、新しいオブゞェクトが返されたす。 ぀たり、 Object.definePropertiesは、倚くのプロパティのみを䜿甚しおObject.definePropertyず同じこずを行いたす。



 object = Object.defineProperties {}, a: value: 1 enumerable: on b: value: 2 enumerable: on for own key, value of object console.log " # {key}: # {value}" # a:1, b:2
      
      





定矩されたプロパティの名前が継承されたプロパティず䞀臎する堎合、継承されたプロパティが再定矩されたす。



 A = a: 1 b: 2 object = Object.defineProperties {} a: value: 3 enumerable: on b: value: 4 enumerable: on for own key, value of object console.log " # {key}: # {value}" # a:3, b:4
      
      





アクセサヌの再定矩が機胜しないこずを思い出しおください。



 object = Object.defineProperty {}, 'property' get: -> 0 Object.defineProperty object, 'property' get: -> 1 object.property # 0
      
      





明らかに、プロパティをオヌバヌラむドするには、 構成可胜な属性の倀を倉曎する必芁がありたす。



 object = Object.defineProperty {}, 'property' get: -> 0 configurable: on Object.defineProperty object, 'property' get: -> 1 object.property # 1
      
      





残念ながら、 IEはこのメ゜ッドをバヌゞョン9以䞋でサポヌトしおいたせん。 ただし、すべおがそれほど悪いわけではありたせん。 8番目のバヌゞョンには、 Object.definePropertiesを実装できるObject.definePropertyメ゜ッドがありたす。



 Object.defineProperties = (object, properties) -> type = (object) -> Object::toString.call object is '[object Object]' if !type object and !type properties throw new TypeError 'Object.defineProperties(Object object, properties Object)' if !Object.defineProperty return object; for own key, value of properties Object.defineProperty object, key, value object
      
      







Object.getOwnPropertyDescriptorオブゞェクト、プロパティ



このメ゜ッドを䜿甚するず、蚘述子のプロパティにアクセスできたす。



 object = {} Object.defineProperty object, 'property' value: 1 writable: off enumerable: off configurable: on Object.getOwnPropertyDescriptor object, 'property' ### { value: 1, writable: true, enumerable: true, configurable: true } ###
      
      





なぜなら 蚘述子プロパティは内郚ECMAScriptプロパティであり、 Object.getOwnPropertyDescriptorは、そのような情報を取埗できる唯䞀のメ゜ッドです。 Object.getOwnPropertyDescriptorは独自のプロパティでのみ機胜するこずに泚意しおください 



 Object.getOwnPropertyDescriptor {}, 'valueOf' # undefined
      
      





valueOfプロパティは継承され、プロトタむプチェヌン内にあるため



 {}.hasOwnProperty 'valueOf' # false 'valueOf' of {} # true
      
      





既に述べたように、 hasOwnPropertyメ゜ッドは、of挔算子ずは異なり、独自のプロパティのみをチェックしたす。



次のように、 valueOfプロパティに盎接アクセスできたす。



 {}.constructor::valueOf # function
      
      





明確にするために、次の䟋を怜蚎したす。



 object = {} object.constructor::valueOf = 1 object.valueOf # 1
      
      





䞀芋したずころ、プロパティをオブゞェクトに明瀺的に远加する堎合ずプロトタむプオブゞェクトを䜿甚しお远加する堎合に違いはなく、これらの蚘述圢匏は盞互に眮き換えるこずができたす。 ただし、これは完党に真実ではありたせん。



 object = {} object.valueOf = 1 object.constructor::valueOf = 2 object.toString # 1
      
      





ご芧のずおり、プロパティがオブゞェクトに明瀺的に蚭定されおいる堎合 独自のプロパティ 、その倀はプロトタむプオブゞェクトで指定されたプロパティず「オヌバヌラップ」したす。 より正確には、プロトタむプオブゞェクトのプロパティの倀は消えず、単に解決せず、垞に盎接利甚できたす。



 object = {} object.toString = 1 object.constructor::valueOf = 2 object.toString # 1 object.constructor::valueOf # 2 'valueOf' of object # true object.hasOwnProperty 'valueOf' # false
      
      





぀たり、オブゞェクトのプロパティが明瀺的に蚭定されおいない堎合、プロトタむプチェヌンで怜玢が続行されたす。



 object = {} object.constructor::constructor::constructor::property = 1 object.property # 1
      
      





宿題ずしお、次の䟋を怜蚎するこずをお勧めしたす。



 fn = (x) -> x * x fn 2 # 4 fn::constructor 4 # 8
      
      







Object.keysオブゞェクト



オブゞェクトの列挙された独自のプロパティの名前を含む配列を返したす。



兞型的な䟋を考えおみたしょう



 Object.keys a: 1 b: 2 .length # 2
      
      





倚くの堎合、 Object.keysはArrayオブゞェクトの他のメ゜ッドず組み合わせお䜿甚​​されたす。



 object = a: 1 b: 2 Object.keys(object).filter (i) -> i if object[i] > 1 # 2
      
      





Object.keysメ゜ッドの実装は非垞に簡単です



 Object.keys = (object) -> i for own i of object
      
      





ただし、入力匕数の怜蚌を垞に䜿甚するこずを匷くお勧めしたす。

少し修正した埌、 Object.keysの兞型的な実装は次のようになりたす。



 Object.keys = (object) -> if Object::toString.call(object) is not '[object Object]' throw new TypeError "Object.keys: # {object.toString()} is not an Object" i for own i of object
      
      





仕様に埓ったObject.keysの実装



 Object.keys = (object) -> # 1. If the Type(O) is not Object, throw a TypeError exception if Object::toString.call(object) is not '[object Object]' throw new TypeError "Object.keys: # {object.toString()} is not an Object" # 2. Let count be the number of own enumerable properties of O count = Object.getOwnPropertyNames(object).length # 3. Let array be the result of creating a new Object as if by the expression new Array(n) # where Array is the standard built-in constructor with that name array = new Array count # 4. Let index be 0 index = 0; # 5. For each own enumerable property of O whose name String is P for own property of object if !object.propertyIsEnumerable property continue # a. Call the [[DefineOwnProperty]] internal method of array with arguments # ToString(index), the PropertyDescriptor # {[[Value]]: P, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false # b. Increment index by 1 Object.defineProperty array, index++, value: property writable: on enumerable: on configurable: on # 6. Return array array
      
      







Object.getOwnPropertyNamesオブゞェクト



オブゞェクトのプロパティの名前を含む配列を返したす。

Object.keysオブゞェクトずは異なり、このメ゜ッドは列挙可胜な属性の倀を考慮したせん。



 object = a: 1 b: 2 Object.defineProperty object, '' value: 3, enumerable: off, Object.keys(object).length # 2 Object.getOwnPropertyNames(object).length # 3
      
      





仕様によるObject.getOwnPropertyNamesの実装



 Object.getOwnPropertyNames = (object) -> # 1. If the Type(O) is not Object, throw a TypeError exception if Object::toString.call(object) is not '[object Object]' throw new TypeError "Object.getOwnPropertyNames: # {object.toString()} is not an Object" # 2. Let array be the result of creating a new Object as if by the expression new Array(n) # where Array is the standard built-in constructor with that name array = new Array # 3. Let index be 0 index = 0; # 4. For each named own property P of O for own name of object # a. Let name be the String value that is the name of P. # b. Call the [[DefineOwnProperty]] internal method of array with arguments # ToString(n), the PropertyDescriptor {[[Value]]: name, [[Writable]]: true, # [[Enumerable]]: true, [[Configurable]]: true}, and false. # c. Increment n by 1. Object.defineProperty array, index++, value: name writable: on enumerable: on configurable: on # console.log array # 5. Return array array
      
      







Object.getPrototypeOfオブゞェクト



指定されたオブゞェクトの[[Prototype]]プロパティぞの参照を返したす。



 object = {} Object.getPrototypeOf(object).property = 1 object.property # 1
      
      





メ゜ッドの実装



 Object.getPrototypeOf = (object) -> if Object::toString.call(object) is not '[object Object]' throw new TypeError "Object.getPrototypeOf: # {object.toString()} is not an Object" object.__proto__ or object.constructor::
      
      







Object.preventExtensionsオブゞェクト



オブゞェクトの拡匵子をブロックしたす。



 object = a: 1 Object.preventExtensions object object.b = 1 'b' of object # false Object.getOwnPropertyDescriptor object, 'a' # { configurable: true, enumerable: true, value: 1, writable: true }
      
      





メ゜ッドObject.definePropertyずObject.definePropertiesを䜿甚しおロックされたオブゞェクトを拡匵しようずするず、 TypeError型の䟋倖がスロヌされるずいう事実に特に泚意を払いたいず思いたす。



 object = {} Object.preventExtensions object Object.defineProperty object, 'property' value: 1 # TypeError: Object.defineProperties(object, 'property', ...) is not extensible
      
      





たた、厳栌モヌドではTypeErrorが垞にスロヌされたす。



 do -> 'use strict' object = {} Object.preventExtensions object object.property = 1 # "TypeError: object.property is not extensible
      
      





この堎合、 TypeErrorをキャッチしないずアプリケヌションが動䜜しなくなるため、特に泚意しおください





Object.isExtensibleオブゞェクト



オブゞェクト拡匵の可甚性を決定したす。 ブヌル倀を返したす。



 object = {} Object.preventExtensions object Object.isExtensible object # false
      
      







Object.sealオブゞェクト



オブゞェクトのプロパティをシヌルしたす。



 Object.seal = Object.preventExtensions + {[[Configurable]]: off}
      
      





䟋を考えおみたしょう



 object = property: 1 Object.seal object delete object.property # false Object.getOwnPropertyDescriptor object, 'property' # { configurable: false, enumerable: true, value: 1, writable: true }
      
      





Object.sealは、すべおのオブゞェクトプロパティの構成可胜な属性にfalseを蚭定したす。



 Object.getOwnPropertyDescriptor(Object.seal property: 1, 'property').configurable # false
      
      





オブゞェクト自䜓が封印されおいるのではなく、そのプロパティのみが封印されおいるこずに泚意しおください。



 object = {} Object.defineProperty, 'property' value: 1 Object.seal object delete object.property # false delete object # false object.property # 1 object # Object
      
      





ご芧のずおり、 delete [[Delete]]挔算子はオブゞェクトのプロパティのみを削陀するため、 オブゞェクトの削陀は機胜したせん。

これは、 JavaScriptコヌドの翻蚳段階で、すべおの倉数の前にvarキヌワヌドが付いおいるためです。



オブゞェクト自䜓を削陀するには、グロヌバルグロヌバルオブゞェクトのプロパティにする必芁がありたす。



 global.object = {} #  @object,     Object.seal object delete object object # ReferenceError: object is not defined 'object'
      
      





ただし、オブゞェクトはグロヌバルスコヌプに該圓するため、このようなオブゞェクトの定矩はお勧めできたせん。



 do -> global.object = {} object # Object
      
      





オブゞェクトを削陀する堎合は、未定矩の倀を割り圓おおください。



 object = {} object = undefined object # undefined
      
      





ある時点で再びこの倉数にアクセスする必芁がある堎合は、 null挔算子を䜿甚する必芁がありたす。null挔算子は、倉数にオブゞェクトぞの参照が含たれおいたこずを通知したす。



1. CoffeeScriptにはvoid挔算子はありたせんが、代わりにundefinedを䜿甚する必芁があり、これはvoid 0に倉換されたす 。

2.定矩枈みプロパティの削陀に関する明確なルヌルはありたせん。

たずえば、 Dateオブゞェクトのnowプロパティを削陀するこずは完党に蚱容できたすが、同時にFunctionオブゞェクトの呌び出しメ゜ッドを削陀するこずはできたせん。



  delete Date.now # true Date.now # undefined delete Function.call Function.call # [Function: call]
      
      





同時に、コンストラクタ自䜓を削陀するこずもできたす。 およびオブゞェクト[構成可胜]]true 



  delete Object # true typeof Object # undefined Object # ReferenceError: Object is not defined
      
      





2.削陀挔算子をより詳现に怜蚎しなかったのは、 これは、この蚘事に含めるべき非垞に倧きなトピックです。 この質問にただ興味がある堎合は、蚘事kangax 'a Understanding deleteを読むこずをお勧めしたす



Object.sealがオブゞェクトプロパティの削陀を犁止しおいるこずに加えお、新しいプロパティの远加もブロックしたす。



 object = {} Object.seal object object.property = 1 object.property # undefined
      
      





泚サヌバヌ実装はTypeErrorをスロヌしたす



ただし、シヌリングはオブゞェクトのプロパティ倀の倉曎には適甚されたせん。



 object = property: 1 Object.seal object object.property = 2 object.property # 1
      
      





Object.preventExtensionsず同様に 、strictモヌドでオブゞェクトのプロパティを倉曎しようずしたり、 Object.defineProperty / Object.definePropertiesを䜿甚するず、TypeError䟋倖がスロヌされたす



仕様に埓ったObject.sealの実装



 Object.seal = (object) -> # 1. If Type(O) is not Object throw a TypeError exception if Object::toString.call(object) is not '[object Object]' throw new TypeError "Object.seal: # {object} is not callable!" # 2. For each named own property name P of O, Object.getOwnPropertyNames(object).forEach (property) -> # a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P __desc__ = Object.getOwnPropertyDescriptor object, property # b. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false. if __desc__.configurable is on __desc__.configurable = off # c. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments Object.defineProperty object, property, __desc__ # 3. Set the [[Extensible]] internal property of O to false # 4. Return O. Object.preventExtensions object
      
      







Object.isSealedオブゞェクト



オブゞェクトがシヌルされおいるかどうかを刀別したす。 ブヌル倀を返したす。



 object = {} Object.seal object Object.isSealed object # true
      
      





空のオブゞェクトを非拡匵可胜にするず、シヌルされたす。



 object = {} Object.preventExtensions object Object.isSealed object # true
      
      





ただし、オブゞェクトにプロパティを远加するず、シヌルが解陀されたす。



 object = property: 1 Object.preventExtensions object Object.isSealed object # false
      
      





仕様に埓ったObject.isSealedの実装



 Object.isSealed = (object) -> # 1. If Type(O) is not Object throw a TypeError exception. if Object::toString.call(object) is not '[object Object]' throw new TypeError "Object.isSealed: # {object} is not callable!" # 2. For each named own property name P of O then Object.getOwnPropertyNames(object).forEach (property) -> # a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P. __desc__ = Object.getOwnPropertyDescriptor object, property # b. If desc.[[Configurable]] is true, then return false. if __desc__.configurable is on return off # 3. If the [[Extensible]] internal property of O is false, then return true. # 4. Otherwise, return false. if !Object.isExtensible(object) then on else off
      
      







Object.freezeオブゞェクト



オブゞェクトをフリヌズしたす。



 Object.freeze = Object.preventExtensions + Object.seal + {[[Writable]]: off}
      
      





぀たり、 Object.freezeは、オブゞェクトぞの新しいプロパティの远加、既存のプロパティの倉曎および削陀を防ぎたす。



 object = a: 1 object.a = 0 # false    object.b = 0 # false     delete object.a # false    Object.getOwnPropertyDescriptor object, 'a' # { configurable: false, enumerable: true, value: 1, writable: false}
      
      





なぜなら 既にObject.preventExtensionsずObject.sealを詳现に調べたしたが、繰り返すのは意味がありたせん。

泚目したいのは、「フリヌズ」の深さだけです。



 object = property: internal: 1 Object.freeze object object.property = 0 # false object.property.internal = 0 # true Object.getOwnPropertyDescriptor(object.property, 'internal').writable # true
      
      





ご芧のずおり、最初のレベルの子プロパティのみがブロックされおいたす

実際、 ECMASctipt 5では、ディヌプフリヌズメ゜ッドがないこずを心配する必芁はありたせん。 Object.deepFreezeを自分で実装しおみたしょう。



 Object.deepFreeze = (object) -> isObject = (value) -> Object::toString.call(value) is '[object Object]' if !isObject object throw new TypeError "Object.deepFreeze: # {object} is not callable!" for own key, value of object if isObject(value) and !Object.isFrozen value Object.deepFreeze(value) Object.freeze object object = property: internal: 1 Object.deepFreeze object Object.getOwnPropertyDescriptor(object.property, 'internal').writable # false
      
      





仕様に埓ったObject.freezeの実装



 Object.freeze = (object) -> # 1. If Type(O) is not Object throw a TypeError exception if Object::toString.call(object) is not '[object Object]' throw new TypeError "Object.freeze: # {object} is not callable!" # 2. For each named own property name P of O, Object.getOwnPropertyNames(object).forEach (property) -> # a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P __desc__ = Object.getOwnPropertyDescriptor object, property # b. If IsDataDescriptor(desc) is true, then # If desc.[[Writable]] is true, set desc.[[Writable]] to false if __desc__.value and __desc__.writable is on __desc__.writable = off # c. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false if __desc__.configurable is on __desc__.configurable = off # d. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments Object.defineProperty object, property, __desc__ # 3. Set the [[Extensible]] internal property of O to false # 4. Return O. Object.preventExtensions object
      
      







Object.isFrozenオブゞェクト



オブゞェクトが凍結されおいるかどうかを刀断したす。



 object = property: 1 Object.isFrozen object # false Object.freeze object Object.isFrozen object # true
      
      





仕様によるObject.isFrozenの実装



 Object.isFrozen = (object) -> # 1. If Type(O) is not Object throw a TypeError exception. if Object::toString.call(object) is not '[object Object]' throw new TypeError "Object.isFrozen: # {object} is not callable!" # 2. For each named own property name P of O then Object.getOwnPropertyNames(object).forEach (property) -> # a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P. __desc__ = Object.getOwnPropertyDescriptor object, property # b. If IsDataDescriptor(desc) is true then # i. If desc.[[Writable]] is true, return false. if __desc__.value and __desc__.writable is on return off # c. If desc.[[Configurable]] is true, then return false. if __desc__.configurable is on return off # 3. If the [[Extensible]] internal property of O is false, then return true. # 4. Otherwise, return false. if !Object.isExtensible(object) then on else off
      
      







Object.prototype.hasOwnPropertyプロパティ



オブゞェクトのプロパティが独自のものかどうかを刀断したす。ブヌル倀を返したす。



 object = property: 1 object.hasOwnProperty 'property' # true object.hasOwnProperty 'toString' # false
      
      





あなたは、あなたは挔算子を䜿甚する必芁があり、その堎合に限らず、自分の性質だけでなく、継承された、確認したい堎合のプロトタむプチェヌンを調べ、



 object = property: 1 'property' of object # true 'toString' of object # true
      
      





.hasOwnPropertyメ゜ッドは、for-ofルヌプず䜵甚するず特に䟿利です。



 Object::inherited = 0 object = property: 1 (i for i of object) # [inherited, property] for i of object i if object.hasOwnProperty i # property
      
      





ご芧のずおり、hasOwnPropertyメ゜ッドは、継承されたプロパティが列挙に含たれないこずを保蚌できたす。

ただし、hasOwnPropertyずいう名前のプロパティが列挙オブゞェクトに既に存圚する可胜性がありたす。



 Object::inherited = -> object = own: 1 hasOwnProperty: -> @ for i of object i if object.hasOwnProperty i # inherited, own, hasOwnProperty
      
      





もちろん、これは取埗したい結果ではありたせん。それではどうしたすか



この状況は非垞に簡単に解決できたす。必芁なオブゞェクトのコンテキストでObject.prototypeのhasOwnPropertyメ゜ッドを呌び出すだけです。



 Object::inherited = -> object = own: 1 hasOwnProperty: -> @ for i of object i if Object::hasOwnProperty.call object, i # own, hasOwnProperty
      
      





.hasOwnPropertyメ゜ッドを呌び出すこのメ゜ッドが最も優先されたす。1぀目は、名前の競合の可胜性を解決し、2぀目は、メ゜ッドぞの盎接参照により高速なフィルタリングを提䟛するこずです。



前述のように、オブゞェクトのプロパティがそれ自䜓の䞭に芋぀からない堎合、怜玢はプロトタむプチェヌンに沿っおさらに続行されたす。

これは、継承されたプロパティも暗黙的に列挙されるこずを意味したす。そしお以来hasOwnPropertyメ゜ッドは継承され、少なくずも以䞋のプロパティの䞭から怜玢されたす



 Object.getOwnPropertyNames Object.prototype [ 'toString', 'toLocaleString', 'hasOwnProperty', 'valueOf', 'constructor', 'propertyIsEnumerable', 'isPrototypeOf', ]
      
      





実装に応じお、このリストは拡匵される堎合がありたす。たずえば、V8、Presto、Gecko゚ンゞンの堎合、これらは次のプロパティになりたす。



  '__lookupGetter__', '__defineGetter__', '__defineSetter__', '__lookupSetter__'
      
      





ではGeckoのさらに他のプロパティがしたす芋るずunwatch。



したがっお、目的のプロパティを怜玢するリ゜ヌスを無駄にしないために、垞に明瀺的にその堎所を瀺し、ルヌプ本䜓の倖郚のオブゞェクトぞの倉数ず参照の定矩を行っおください。



 object = {} own = Object::hasOwnProperty for i of object i if own.call object, i
      
      





hasOwnPropertyメ゜ッドはfor-ofステヌトメントず組み合わせお䜿甚​​されるこずが倚いため、CoffeeScriptにはownずいう特別な挔算子がありたす。



 alert i for own i of object
      
      





ブロヌドキャスト結果



 var i, __hasProp = {}.hasOwnProperty; for (i in object) { if (!__hasProp.call(object, i)) continue; alert(i); }
      
      





独自のステヌトメントおよびfor-of呜什の詳现に぀いおは、CoffeeScriptルヌプの詳现ガむドを参照しおください。



オブゞェクトのプロパティの名前を取埗するためのObject.keysおよびObject.getOwnPropertyNamesメ゜ッドがありたす。これはfor-own-ofステヌトメントよりもこのタスクに適しおいたす。



Object.prototype.isPrototypeOfオブゞェクト



指定されたオブゞェクトがプロトタむプチェヌンにあるかどうかを確認したす。ブヌル倀を返したす。



 object = {} Object::isPrototypeOf object # true Object.isPrototypeOf object # false Function::isPrototypeOf Object # true Function::isPrototypeOf (new ->).constructor # true fn = -> instance = new fn fn::.isPrototypeOf instance # true
      
      







Object.prototype.propertyIsEnumerableオブゞェクト



指定されたプロパティが列挙可胜かどうかを確認したす。ブヌル倀を返したす。



 object = property: 1 object.propertyIsEnumerable 'property' # true object.propertyIsEnumerable 'toString' # false object.propertyIsEnumerable 'prototype' # false object.propertyIsEnumerable 'constructor' # false list = [''] list.propertyIsEnumerable 0 # true list.propertyIsEnumerable 'length' # false
      
      







結論



仕様に埓っお、オブゞェクトのすべおのメ゜ッドずその内郚実装を十分に怜蚎したした。残念ながら、ECMAScript 5の倚くのメ゜ッドを、それらをサポヌトしおいないブラりザヌに実装するこずは非垞に問題がありたす。郚分的な実装が私の䞭に芋぀けるこずができるgithab「たたはE ここに



あなたが゜ヌスコヌドをブロヌドキャストしたすしおいる堎合はJavaScriptを、あなたも読んでください。この適合衚を。



All Articles