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ããããªããèªãã§ãã ããããã®é©åè¡šãã