newæŒç®åã®åã
ååã®èšäºã§ã¯ããããã¿ã€ããã§ãŒã³ãçè§£ããããã«ãããããã£ã®"åç §"ã®ã¿ã€ãã³ã°ã§äœãèµ·ãã£ãŠããã®ãã解説ãããããã§ã¯ãããããã£ã"äœæã»å€æŽ"ããéã«ã¯äœãèµ·ããã®ã ãããã
é£èŒç¬¬3åã§è¿°ã¹ãéããJavaScriptã§ã¯(ãªãã©ã«å€ãé€ãã°)ãã¹ãŠã®ããŒã¿ã¯ãªããžã§ã¯ãã§ãããã€ãŸããããããã£ã®å€ã(ãªãã©ã«å€ãé€ãã°)ãªããžã§ã¯ããšããŠå®çŸ©ããããããããã£ãå®çŸ©(äœæ)ãããšãã®åããçè§£ããããã«ããŸãã¯ãnewæŒç®åã®åãããã¡ããšç¢ºèªããŠããããã
newæŒç®åã®åãã¯ããããŸã§ãã³ãã³ç޹ä»ããŠããCore JavaScript 1.5 ReferenceãèŠãŠãçè§£ãé£ããããããªãã
Core JavaScript 1.5 Referenceã§è§£èª¬ãããŠããã®ã¯ãnewæŒç®åã®åããšããããã¯äœ¿ãããã®éšåã ããã ãããå°ãçè§£ãæ·±ããããã«ãJavaScriptã®ããŒã¹ãšãªã£ãŠããECMAScript(ãšã¯ãã¹ã¯ãªãã)ã®èšèªä»æ§ãèªã¿èŸŒãã§ã¿ãããJavaScript 1.7ã«å¯Ÿå¿ããECMAScriptã®ããŒãžã§ã³ã¯1999幎12æã«å ¬éãããStandard ECMA-262ã ãEcma internationalã®WebããŒãžãã仿§æž(PDF)ãããŠã³ããŒãã§ããã
ECMA-262ã®ããã¥ã¡ã³ããååŸããŠããããç®æ¬¡ããã£ãšçºãããã¥ãŒã¢ã®æ€çŽ¢æ©èœãªã©ãçšããŠ"new Operator"ãšããæååãæ€çŽ¢ããŠã¿ããã11.2.2ç¯ã«ã次ã®è§£èª¬ããªãããŠããããšããããã
11.2.2 The new Operator
The production NewExpression : new NewExpression is evaluated as follows:
1. Evaluate NewExpression.
2. Call GetValue(Result(1)).
3. If Type(Result(2)) is not Object, throw a TypeError exception.
4. If Result(2) does not implement the internal [[Construct]] method, throw a TypeError exception.
5. Call the [[Construct]] method on Result(2), providing no arguments (that is, an empty list of arguments).
6. Return Result(5).
ããã§è§£èª¬ãããŠããéããã€ã³ã¿ããªã¿ã¯newæŒç®åãçºèŠãããšã察象ããªããžã§ã¯ãã§ããã(æ°å€ãæååãªã©ã®ãªãã©ã«å€ã§ç¡ãã)ãå€å¥ããç¶ããŠå éš [[Construct]] ã¡ãœãããã³ãŒã«ããããšããããšããããã
ããã§ã¯ãç¶ããŠã[[Construct]] ã¡ãœããã«ã€ããŠãèŠãŠãããã13.2.2ç¯ã«ã次ã®è§£èª¬ããªãããŠããã
13.2.2 [[Construct]]
When the [[Construct]] property for a Function object F is called, the following steps are taken:
1. Create a new native ECMAScript object.
2. Set the [[Class]] property of Result(1) to "Object".
3. Get the value of the prototype property of the F.
4. If Result(3) is an object, set the [[Prototype]] property of Result(1) to Result(3).
5. If Result(3) is not an object, set the [[Prototype]] property of Result(1) to the original Object prototype object as described in 15.2.3.1.
6. Invoke the [[Call]] property of F, providing Result(1) as the this value and providing the argument list passed into [[Construct]] as the argument values.
7. If Type(Result(6)) is Object then return Result(6).
8. Return Result(1).
ããã§ã¯ã(var F = function() { ... } ã§å®çŸ©ããããããª)颿°ãªããžã§ã¯ã F ãäŸã«ãnew F() ããéã®åãã詳现ã«è§£èª¬ãããŠãããããã®è§£èª¬ã§ããä»ã®ããŒãžãåç §ãã¹ãããŒã¯ãŒããå€ã ç»å ŽããŠãããã端çã«èš³ããšãããã§ã®åŠçã¯æ¬¡ã®éãã (次ã®é çªã¯ãå¿ ãããäžèšã®ãããšäžèŽããªãã®ã§æ³šæ)ã([[Class]], [[Prototype]], [[Call]] ã«ã€ããŠãåæ§ã«ä»æ§ã確èªããŠãããã)
- æ°ãããã€ãã£ãã®ECMAScriptãªããžã§ã¯ããçæãã
- Fãªããžã§ã¯ãã®ãããã¿ã€ãããããã£(F.prototype)ãååŸãã
- ããããªããžã§ã¯ãã§ããã°(æ°å€ãæååãªã©ã®ãªãã©ã«å€ã§ãªããã°)ãããã 1 ã§çæãããªããžã§ã¯ãã®[[prototype]]ããããã£ã«ã»ãããã(JavaScriptã®å®è£ ã§ã¯ __proto__ ããããã£ãšãªã)
- ãªããžã§ã¯ãã§ãªããã°ã(æäžäœã«äœçœ®ãã)Objectãªããžã§ã¯ãã®ãããã¿ã€ãããããã£ã [[prototype]]ããããã£ã«ã»ãããã
- åŒæ°ãšããŠãnewããããšãã®åŒæ°ãããã®ãŸãŸèšå®ããF() (ã³ã³ã¹ãã©ã¯ã¿)ãã³ãŒã«ããããã®ã³ã³ã¹ãã©ã¯ã¿å
éšã§ã¯ã1ã§çæãããªããžã§ã¯ããthisãšããŠæ±ã
- ãã®è¿ãå€ããªããžã§ã¯ãã§ããã°ãããã"new"ã®çµæãªããžã§ã¯ããšããŠè¿ã
- ãªããžã§ã¯ãã§ãªããã° 1 ã§çæãããªããžã§ã¯ãã"new"ã®çµæãªããžã§ã¯ããšããŠè¿ã
以äžãããJavaScriptã§ãªããžã§ã¯ããnewããéã¯ããŸãããããã¿ã€ããã§ãŒã³ã蟿ãprototypeããããã£ãã»ãããããã®äžã§ã³ã³ã¹ãã©ã¯ã¿ãã³ãŒã«ãããããšããããã
ããããå°ãããªãããŒãªã®ã¯ã
- ã³ã³ã¹ãã©ã¯ã¿å ã§ãããã¿ã€ããé©çšãããªããžã§ã¯ããçæãããŠããããš(ã¯ã©ã¹ããŒã¹ã§èšãã¹ãŒããŒã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã(åŒæ°ã®æç¡ã«ããããã)æé»ã§åŒã³åºãããŠãã)(äžèš2)
- ã³ã³ã¹ãã©ã¯ã¿ã®è¿ãå€ããªããžã§ã¯ãã§ãªããã°ããããã¿ã€ããé©çšãããªããžã§ã¯ãããã®ãŸãŸè¿ããã(äžèš3.2)
ãšããç¹ã ããã³ã³ã¹ãã©ã¯ã¿ã®è¿ãå€ããšã¯ã銎æã¿ã«ãããããããªãããé£èŒç¬¬4åã§è¿°ã¹ãéããã³ã³ã¹ãã©ã¯ã¿ã¯åãªã颿°ãªããžã§ã¯ãã§ããã颿°ãªããžã§ã¯ãã«newæŒç®åãæœããšã(颿°ãªããžã§ã¯ããã³ã³ã¹ãã©ã¯ã¿ãšããŠæ©èœãã)äžèšã®ãããªåŠçããªãããããšèããã°ãããçè§£ããããã ããã
ããããã£ã®äœæã»å€æŽ
ããŠã以äžã§newæŒç®åã®åãã確èªã§ãããä»åã®äž»æšã§ãããããããã£ã® "äœæã»å€æŽ" ã«è§£èª¬ãæ»ããããããŸã§ããã°ããããã¿ã€ããã§ãŒã³ã®ä»çµã¿ãããçè§£ã§ããã¯ãã ã
ããããã£ã® "äœæã»å€æŽ" ã§ã¯ãæç€ºçã« prototype ãäžæžãããããšããªãéãããã®ãªããžã§ã¯ãèªèº«ã®ããããã£ãäœæã»å€æŽããããnewæŒç®åã®åãããããããã£ã®å®çŸ©æ¹æ³ããã確èªããªãããååå®è¡ããã³ãã³ã(åŸåéšå)ãæ¯ãè¿ã£ãŠã¿ããã
// ããã¯ã¹ãã³ããªããžã§ã¯ã"Dachshund"ã®ãããã¿ã€ãã
// ç¬ãªããžã§ã¯ããšãã
>>> var Dachshund = function() { this.name='ãµã©'; }
// Dog(ããèªäœã¯prototypeããããã£ã«Mammalãªããžã§ã¯ããæã€)ãnewãã
>>> Dachshund.prototype = new Dog()
Object name=noname
// Dachshund(ããèªäœã¯prototypeããããã£ã«Dogãªããžã§ã¯ããæã€)ãnewãã
>>> var dh = new Dachshund()
// ã³ã³ã¹ãã©ã¯ã¿ã«ãããprototypeãé©çšããŠçæããããªããžã§ã¯ãã®nameãæžãæããããŠãã
>>> dh.name
"ãµã©"
// ããã¯ã¹ãã³ããªããžã§ã¯ãã®ãããã¿ã€ããäžæžã
>>> Dachshund.prototype.name = 'ãã'
"ãã"
>>> dh.name
"ãµã©"
// â dhã¯8è¡ç®ã§æ¢ã«newãããŠããããããããã¿ã€ãã®å€æŽã¯åœ±é¿ããªã
>>> dh.bark()
// â ãããã¿ã€ãããããã£(__proto__)ãåç
§ããã = 'ã°ããã' ãšè¡šç€º
// dhãªããžã§ã¯ãèªèº«ã®barkããããã£ãäœæ
>>> dh.bark = function() { alert('ãã
ãŒã'); }
function()
>>> dh.bark()
// â'ãã
ãŒã' ãšè¡šç€º
äžèšã§ã¯ãååã®è§£èª¬ããããã³ã¡ã³ãã詳现ã«èšè¿°ããŠãããããããã®ãªããžã§ã¯ããnewãããã¿ã€ãã³ã°ã§äœãèµ·ãã£ãŠãããDachshund.prototype.nameã®äžæžããdh.barkã®å®çŸ©ããã©ã®ããã«åäœããŠãããçè§£ã§ããã ãããã
以äžããããã¿ã€ããã§ãŒã³ã«ããç¶æ¿ã¡ã«ããºã ã玹ä»ããããããã¿ã€ãããŒã¹ãªããžã§ã¯ãæåã§ã¯ãã¯ã©ã¹ããŒã¹ã§ãããªãŒããŒã©ã€ããšäŒŒããããªä»çµã¿ã§ç¶æ¿ãå©çšã§ãããããããããããã£ã鿬¡äœæã»å€æŽã»åé€ã§ãããšããç¹ããããã¯ã©ã¹ããŒã¹ãšæ¯èŒãããããã€ãããã¯ãªãªããžã§ã¯ãæåããã°ã©ãã³ã°ãå¯èœã«ãªã£ãŠããäºããããã ããã
äžæ¹ããããã¿ã€ããã§ãŒã³ã¯äŸ¿å©ãªä»çµã¿ã ããå Žåœããçãªããããã£æäœãè¡ã£ãŠãããšããã¡ãŸã¡ãªããžã§ã¯ããè¥å€§åã»è€éåããŠããŸããã©ã®ããã«ã³ãŒãã£ã³ã°ããŠããã®ããããå®è·µçãªã®ã ããããæ¬¡å以éã¯ãäžã«å ¬éãããŠããããŸããŸãªJavaScriptã©ã€ãã©ãªã®ãœãŒã¹ã³ãŒããèªã¿ãªãããåºç€çãªéšåãæŒããã€ã€ãããã«å®è·µçãªãããã¯ã«ã€ããŠè§£èª¬ããŠãããã