ã©ãã§äœ¿çšã§ããŸããïŒ
1.äžè¬çãªäžéæœè±¡å
2.ä»®æ³ãªããžã§ã¯ãã®äœæïŒæ¢åã®ãªããžã§ã¯ãã®ã©ãããŒããªã¢ãŒãïŒé ãããé¢ããïŒãªããžã§ã¯ãããªããžã§ã¯ãã®é 延äœæïŒORMã®äŸ-Ruby ActiveRecordãGroovy GORMïŒ
3.ééçãªãã®ã³ã°ããã¬ãŒã¹ããããã¡ã€ãªã³ã°
4.ãã¡ã€ã³åºæã®èšèªã®çŽ¹ä»
5.ååšããªãã¡ãœããã®åçã€ã³ã¿ãŒã»ãããæ¬ èœããã¡ãœããã®äœæïŒ__noSuchMethod__ïŒ
6.ç¹å®ã®ã€ãã¬ãŒã¿ãŒã®ããŒã¹
ã³ã³ã»ãã
1.ãã®èšèªã®æ©èœã¯ããå æ¬çãªã¡ã«ããºã ãïŒå ã®ãã£ãããªãŒã«ã¡ã«ããºã ïŒãšåŒã°ããŸã-ãã®ååã¯ããã®æ©èœã説æããããã«äœ¿çšãããŸãã ããã¹ãã¯å ã®ååã䜿çšããŸãã
2.ãå æ¬çãªã¡ã«ããºã ãã®æŠå¿µã®å¥å-仲ä»è ïŒorigãIntercession APIïŒ
3.ããããã£ãåŠçãããªããžã§ã¯ãã¯ãã³ãã©ãŒãšåŒã°ããŸã-ãã³ãã©ãŒ
4.ããããã£ã眮ãæãããããªããžã§ã¯ãã¯ãããã·ãšåŒã°ããŸã-ãããã·
5.ãããã·ãªããžã§ã¯ããäœæãããªããžã§ã¯ã/ã¡ãœããã¯ããããã·ãã¡ã¯ããªãšåŒã°ããŸã-ãããã·ãã¡ã¯ããª
6.åäœãåŠçãããã³ãã©ãŒã«å«ãŸããã¡ãœããã¯ããã©ãã/ã€ã³ã¿ãŒã»ãã¿ãŒãã©ãããšåŒã°ããŸãïŒãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«é¡äŒŒïŒ
7.ãããã·ã¯ããšããµã€ãã£ã³ã°/ã¢ã¯ãã£ãïŒå ã®ãã©ããã³ã°ïŒãŸãã¯è§£æ£ïŒå ã®åºå®ïŒã§ãã
ãããã䜿çšããæ¹æ³-API
ãããã·ãã¡ã¯ããªã«ã¯2ã€ã®ã¿ã€ãããããŸãã 1ã€ã¯ãªããžã§ã¯ãçšããã1ã€ã¯é¢æ°çšã§ãã
ãããã·ã³ã³ã¹ãã©ã¯ã¿ãŒïŒ
var proxy = Proxy.create(handler, proto);
ãããã·ã³ã³ã¹ãã©ã¯ã¿ãŒã³ã³ã¹ãã©ã¯ã¿ãŒïŒ
var proxy = Proxy.createFunction(handler, callTrap, constructTrap);
proto-ãããã·ãããã¿ã€ããå®çŸ©ãããªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒ
callTrap-ãããã·é¢æ°ãçŽæ¥åŒã³åºããããšãã«å ã®é¢æ°ã眮ãæããé¢æ°ïŒä»¥äžã®äŸã§ãã¹ãŠã説æããŸãïŒã éèŠïŒãã®ä»£æ¿é¢æ°ïŒcallTrapïŒã¯ã代æ¿thisãšäžèŽããŸãã
constructTrap-ãªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒ-newãéããŠåŒã³åºããããšãã«é¢æ°ã®å ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã眮ãæããé¢æ°ã éèŠïŒãã®çœ®æé¢æ°ïŒconstructTrapïŒã¯åžžã«æªå®çŸ©ã§ãã constructTrapãæž¡ãããªãå ŽåãcallTrapã䜿çšãããproxy.prototypeãããã®ããªã²ãŒãã䜿çšãããŸãïŒES5ã³ã³ã¹ãã©ã¯ã¿ãŒã®éåžžã®åäœç¬¬13.2.2ç« ïŒ
ãã³ãã© -ãããã·ã®åäœãå®çŸ©ãããªããžã§ã¯ãã ãã®ãªããžã§ã¯ãã«ã¯åžžã«ãã©ãããå«ãŸããŠããå¿ èŠããããŸãã
ããŒã¹ãã©ãã/ã€ã³ã¿ãŒã»ãã¿ãŒïŒåºæ¬çãªãã©ããïŒ
èªã¿æ¹ïŒ
: function(, __) -> { } //
{ getOwnPropertyDescriptor: function(name) -> {PropertyDescriptor | undefined} // Object.getOwnPropertyDescriptor(proxy, name) getPropertyDescriptor: function(name) -> {PropertyDescriptor | undefined} // Object.getPropertyDescriptor(proxy, name) (not in ES5) getOwnPropertyNames: function() -> {String[]} // Object.getOwnPropertyNames(proxy) getPropertyNames: function() -> {String[]} // Object.getPropertyNames(proxy) (not in ES5) defineProperty: function(name, propertyDescriptor) -> {Mixed} // Object.defineProperty(proxy,name,pd) delete: function(name) -> {Boolean} // delete proxy.name fix: function() -> {{String:PropertyDescriptor}[]|undefined} // Object.{freeze|seal|preventExtensions}(proxy) }
掟çãã©ãã/ã€ã³ã¿ãŒã»ãã¿ãŒïŒæŽŸçãã©ããïŒ
ãããã®ã€ã³ã¿ãŒã»ãã¿ãŒã¯ãªãã·ã§ã³ã§ãããå®çŸ©ãããŠããªãå Žåãããã©ã«ãã®ããžãã¯ã䜿çšãããŸãã
{ has: function(name) -> {Boolean} // if (name in proxy) ... hasOwn: function(name) -> {Boolean} // ({}).hasOwnProperty.call(proxy, name) get: function(receiver, name) -> {Mixed} // receiver.name; set: function(receiver, name, val) -> {Boolean} // receiver.name = val; enumerate: function() -> {String[]} // for (name in proxy) keys: function() -> {String[]} // Object.keys(proxy) }
ããã©ã«ãã§ã¯ã 次ã®ããžãã¯ãå®è¡ãããŸã
衚圢åŒã§ããã«èŠãããšãã§ããŸã
掟çãã©ããã¯ãããŒã¹ãã©ããã§å®çŸ©ã§ãããããã掟çããšåŒã°ããŸãã ããšãã°ãgetPropertyDescriptorããã¯ã䜿çšããŠhasããã¯ãå®çŸ©ã§ããŸãïŒundefinedãè¿ããã©ããã確èªããŸãïŒã 掟çã€ã³ã¿ãŒã»ãã¿ãŒã䜿çšãããšãããäœãã³ã¹ãã§ããããã£ããšãã¥ã¬ãŒãã§ããŸããããããå®çŸ©ãããçç±ã§ãã ãããã·ã
Object.preventExtensions
ã
Object.seal
ããã³
Object.freeze
ãšå¯Ÿè©±ã§ããããã«ããããã«ãä¿®æ£ãã©ãããå°å ¥ãããŸããã éæ¡åŒµãå¯éããŸãã¯åçµããããªããžã§ã¯ãïŒéæ¡åŒµãå¯éãåçµïŒã¯ãäœããã®æ¹æ³ã§ãã³ãã©ãŒã®èªç±ãå¶éããå¿ èŠããããŸãã
set, get
ãªã©ã®å°æ¥ã®åŒã³åºãã§äœãè¿ãã ããšãã°ã以åã®
handler.get(p, âfooâ)
åŒã³åºããæªå®çŸ©ã§ã¯ãªããè¿ããå Žåããã®åŸã®
handler.get(p, "foo")
åŒã³åºãã¯ããªããžã§ã¯ããåçµãããŠããå Žåã«åãå€ãè¿ãå¿ èŠããããŸãã ãããã·ãããªãŒãºãã·ãŒã«ããããã¯ïŒéæ¡åŒµãã·ãŒã«ããŸãã¯ããªãŒãºïŒãè©Šã¿ããã³ã«ã
"fix"
ããã¯ãã©ãããåŒã³åºãããŸãã
ä¿®æ£ãã³ãã©ãŒã«ã¯2ã€ã®ãªãã·ã§ã³ããããŸãã
1.èŠæ±ãæåŠãïŒä¿®æ£ããã°ã©ã ã¯æªå®çŸ©ãè¿ãå¿ èŠããããŸãïŒãTypeErroräŸå€ãã¹ããŒãããŸãã
2.ã¯ãšãªãå®è¡ãã
{String:PropertyDescriptor}[]
ã®åœ¢åŒã§ãªããžã§ã¯ãã®èª¬æãè¿ããŸãããã®å Žåããå æ¬çãªã¡ã«ããºã ãã¯ããªããžã§ã¯ãã®èª¬æã«åºã¥ããŠæ°ãããªããžã§ã¯ããäœæããŸãã ãã®æç¹ã§ããã³ãã©ãŒãžã®ãã¹ãŠã®åç §ãåé€ãããŸãïŒã¬ããŒãžã³ã¬ã¯ã¿ãŒã«ãã£ãŠåé€ã§ããŸãïŒã ãã®å Žåããããã·ã¯licentiousãšåŒã°ããŸãã
äŸ
ããã«ã¡ã¯ãããã·ïŒ
次ã®ã³ãŒãã¯ãããããã£ãžã®ã¢ã¯ã»ã¹ãäžæããåããããã£ãpãã«å¯ŸããŠãHelloãpããè¿ããããã·ãäœæããŸãã
var p = Proxy.create({ get: function(proxy, name) { return 'Hello, '+ name; } }); document.write(p.World); // 'Hello, World'
çããŠããäŸ
ã·ã³ãã«ãªãããã¡ã€ã©ãŒ
ã©ã®ããããã£ãååŸãããããã«ãŠã³ãããåçŽãªã©ãããŒãäœæããŸãã
function makeSimpleProfiler(target) { var forwarder = new ForwardingHandler(target); var count = Object.create(null); forwarder.get = function(rcvr, name) { count[name] = (count[name] || 0) + 1; return this.target[name]; }; return { proxy: Proxy.create(forwarder, Object.getPrototypeOf(target)), get stats() { return count; } }; }
makeSimpleProfileré¢æ°ã¯ãç£èŠãããªããžã§ã¯ããåŒæ°ãšããŠåãåããŸãã ãããã·èªäœãšçµ±èš-åŒã³åºãã®æ°ãšãã2ã€ã®ããããã£ãæã€ãªããžã§ã¯ããè¿ããŸãã
çããŠããäŸ
makeSimpleProfileré¢æ°ã®2è¡ç®ã®ForwardingHandleré¢æ°ã¯ããã¹ãŠã®ãããã·æäœãã¿ãŒã²ããã«ééçã«å§ä»»ããåçŽãªãªãã€ã¬ã¯ããããã·ãäœæããŸãã ããã¯æ¬¡ã®ãããªãã®ã§ãã
function ForwardingHandler(obj) { this.target = obj; } ForwardingHandler.prototype = { has: function(name) { return name in this.target; }, get: function(rcvr,name) { return this.target[name]; }, set: function(rcvr,name,val) { this.target[name]=val;return true; }, delete: function(name) { return delete this.target[name]; } enumerate: function() { var props = []; for (name in this.target) { props.push(name); }; return props; }, iterate: function() { var props = this.enumerate(), i = 0; return { next: function() { if (i === props.length) throw StopIteration; return props[i++]; } }; }, keys: function() { return Object.keys(this.target); }, ... }; Proxy.wrap = function(obj) { return Proxy.create(new ForwardingHandler(obj), Object.getPrototypeOf(obj)); }
ãã®é¢æ°ã®å®å šãªããŒãžã§ã³ã¯ã ããã«ãããŸã ã ãã®è»¢éãã³ãã©ã¯æšæºã®äžéšã«ãªãããã§ãã
åé€ãããã¢ã€ãã
ãããã·ã䜿çšãããšããªã¢ãŒããªããžã§ã¯ããŸãã¯æ¢åã®ãªããžã§ã¯ãããšãã¥ã¬ãŒãã§ããä»®æ³ãªããžã§ã¯ããäœæã§ããŸãã ãã¢ã®ããã«ãæ¢åã®JavaScriptãªã¢ãŒãéä¿¡ã©ã€ãã©ãªã®ã©ãããŒãäœæããŸãããã web_send Tyler Closeã©ã€ãã©ãªã䜿çšããŠããµãŒããŒäžã«ãããªããžã§ã¯ããžã®ãªã¢ãŒãæ¥ç¶ãäœæã§ããŸãã ããã§ããã®ãªã¢ãŒãæ¥ç¶ã䜿çšããŠHTTP POSTèŠæ±ã§ã¡ãœãããåŒã³åºãããšãã§ããŸãã æ®å¿µãªããããªã¢ãŒãéä¿¡ã¯ãªããžã§ã¯ããšããŠäœ¿çšã§ããŸããã
æ¯èŒããŠãã ããã ãªã¢ãŒãé¢æ°ãåŒã³åºãã«ã¯ãæåã«åŒã³åºãå¿ èŠããããŸããã
Q.post(ref, 'foo', [a,b,c]);
ãããã·ã䜿çšããŠããã®åŒã³åºããããèªç¶ã«ããã©ãããŒãèšè¿°ã§ããŸãã
function Obj(ref) { return Proxy.create({ get: function(rcvr, name) { return function() { var args = Array.prototype.slice.call(arguments); return Q.post(ref, name, args); }; } }); }
ããã§
Obj(ref).foo(a,b,c)
ãå®è¡ã§ããŸãã
__NoSuchMethod__ãšãã¥ã¬ãŒã·ã§ã³
ãããã·ã䜿çšãããšãããããµããŒãããŠããªããã©ãŠã¶ã§__noSuchMethod__ããã¯ããšãã¥ã¬ãŒãããããšãã§ããŸãïŒãã ããçŸåšããã¯é¢ä¿ãããŸããïŒã
function MyObject() {}; MyObject.prototype = Object.create(NoSuchMethodTrap); MyObject.prototype.__noSuchMethod__ = function(methodName, args) { return 'Hello, '+ methodName; }; new MyObject().foo() // returns 'Hello, foo'
ãã®ãªããžã§ã¯ãã¯ãå ã®__noSuchMethod__ãgetããã¯ã«çœ®ãæããNoSuchMethodTrapãããã·ã䜿çšããŸãã
var NoSuchMethodTrap = Proxy.create({ get: function(rcvr, name) { if (name === '__noSuchMethod__') { throw new Error("receiver does not implement __noSuchMethod__ hook"); } else { return function() { var args = Array.prototype.slice.call(arguments); return this.__noSuchMethod__(name, args); } } } });
çããŠããäŸ
é«æ¬¡ã¡ãã»ãŒãž
ããã§èª¬æãããŠããããã«ãé«æ¬¡ã¡ãã»ãŒãžã¯ãåŒæ°ãšããŠä»ã®ã¡ãã»ãŒãžãåãåãã¡ãã»ãŒãžã§ã ã
é«æ¬¡ã®ã¡ãã»ãŒãžã¯é«æ¬¡ã®é¢æ°ã«äŒŒãŠããŸãããã³ãŒãã§ã¯ãã容éã倧ãããªããŸãã ãããã·ã䜿çšãããšãé«æ¬¡ã®ã¡ãã»ãŒãžãç°¡åã«äœæã§ããŸãã é¢æ°å ã®ã¡ãã»ãŒãžããªã¡ã€ã¯ããç¹å¥ãªãªããžã§ã¯ãã_ããèããŠã¿ãŸãããã
var msg = _.foo(1,2) msg.selector; // "foo" msg.args; // [1,2] msg(x); // x.foo(1,2)
msgã¯ãé¢æ°
function(z) { return z.foo(1,2); }
ãšããŠå®çŸ©ãããŠãããã®ããã«ã1ã€ã®åŒæ°ã䜿çšããé¢æ°
function(z) { return z.foo(1,2); }
function(z) { return z.foo(1,2); }
次ã®äŸã¯ãäžèšã®ããã¥ã¡ã³ãã®SVPãçŽæ¥è§£éãããã®ã§ããããã容éã®å€§ããã³ãŒãã§èšè¿°ãããŠããŸãã
var words = "higher order messages are fun and short".split(" "); String.prototype.longerThan = function(i) { return this.length > i; }; // document.write(words.filter(_.longerThan(4)).map(_.toUpperCase())); // : // words.filter(function (s) { return s.longerThan(4) }) // .map(function (s) { return s.toUpperCase() })
ãªããžã§ã¯ãã_ãã®ã³ãŒãã¯æ¬¡ã®ãšããã§ãã
// var _ = Proxy.create({ get: function(_, name) { return function() { var args = Array.prototype.slice.call(arguments); var f = function(rcvr) { return rcvr[name].apply(rcvr, args); }; f.selector = name; f.args = args; return f; } } });
çããŠããäŸ
ããŒã¹ãªããžã§ã¯ãã®ãšãã¥ã¬ãŒã·ã§ã³
ãããã·ã䜿çšãããšãJavascriptããã°ã©ãã¯DOMãªã©ã®åºæ¬ãªããžã§ã¯ãã®å¥åŠãªéšåããšãã¥ã¬ãŒãã§ããŸãã ããã«ãããã©ã€ãã©ãªã®äœæè ã¯ãåºæ¬ãªããžã§ã¯ããã©ããããŠã調æŽãïŒãµã³ãããã¯ã¹ã«è¿äŒŒïŒããããä¿®æ£ããŠãã©ãŠã¶éã®éäºææ§ã軜æžãããã§ããŸãã
ãããã·æ©èœ
åã®äŸã§ã¯ãªããžã§ã¯ãã䜿çšããŸããã ç°¡åãªãããã·é¢æ°ã®äŸã次ã«ç€ºããŸãã
var simpleHandler = { get: function(proxy, name) { // can intercept access to the 'prototype' of the function if (name === 'prototype') return Object.prototype; return 'Hello, '+ name; } }; var fproxy = Proxy.createFunction( simpleHandler, function() { return arguments[0]; }, // call trap function() { return arguments[1]; }); // construct trap fproxy(1,2); // 1 new fproxy(1,2); // 2 fproxy.prototype; // Object.prototype fproxy.foo; // 'Hello, foo'
çããŠããäŸ
ãããã·é¢æ°ã¯ãçŽç²ãªJavaScriptã§ã¯å©çšã§ããªãã£ãç¹å¥ãªã€ãã£ãªã ãèšè¿°ããæ©äŒãæäŸããŸãã ãŸãããããã·é¢æ°ã¯ä»»æã®ãªããžã§ã¯ãããé¢æ°ïŒåŒã³åºãå¯èœãªãªããžã§ã¯ãïŒãäœæã§ããŸãã
function makeCallable(target, call, construct) { return Proxy.createFunction( new ForwardingHandler(target), call, construct || call); }
次ã«ããããã·é¢æ°ã䜿çšããŠãã€ã³ã¹ã¿ã³ã¹ãåŒã³åºãå¯èœãªãšã³ãã£ãã£ã§ããæ¬äŒŒã¯ã©ã¹ãäœæã§ããŸãã
function Thing() { /* initialize state, etc */ return makeCallable(this, function() { /* actions to perform when instance is called like a function */ }); }
æ°ããã»ãã³ãã£ã¯ã¹ã®å®éš
èšèªã奜ããªäººåãïŒãããã·ã䜿çšããŠãJavaScriptèªäœã§ãæšæºããªããžã§ã¯ããšJavaScripté¢æ°ãäœæã§ããŸãã JavaScriptå ã®JavaScriptãªããžã§ã¯ãã®ã»ãã³ãã£ã¯ã¹ãå€æŽããæ©èœã«ãããå®éšã®ããã«ã»ãã³ãã£ã¯ã¹ã«ããããªå€æŽãå ããã¡ã«ããºã ãå€§å¹ ã«ç°¡çŽ åãããŸãã JavaScriptå ã®ã»ãã³ãã£ã¯ã¹ã®éšåçãªå®è£ ã¯ã ããã©ã«ãã®ãã©ããå€ã§ç¢ºèªã§ããŸã ã å¥ã®äŸïŒãããã·ã䜿çšããJavaScriptå ã®JavaScripté å ã
ãããã·ã®ãã³ã
ååž°ãé¿ãã
ãã©ããå ã®æé»çãªtoStringåŒã³åºãã¯é¿ããŠãã ããã getããã³setããã¯ã®ã¬ã·ãŒããŒåŒæ°ã«æ³šæããŠãã ããã ã¬ã·ãŒãã¯ãããã·ãžã®ãªã³ã¯ãè¡šããããæé»çã«getããã³setãåŒã³åºããšãç¡éååž°ãçºçããŸãã ããšãã°ãconster.logïŒreceiverïŒãåŒã³åºããŠã»ãã¿ãŒå ã§ãããã°ãããšãtoStringã¡ãœãããåŒã³åºãããç¡éååž°ãçºçããŸãã
get: function(receiver, name) { print(receiver); return target[name]; }
p
ãäžèšã®ãã©ããã䜿çšãããããã·ã§ããå Žåã
p.foo
ãåŒã³åºããšãç¡éã«ãŒããçºçããŸãããŸãã
name="foo"
ã§
get
ãã©ãããåŒã³åºããã
receiver
ïŒã€ãŸã
p
ïŒãåºåãããŸãã ããã«ãã
p.toString()
ãåŒã³åºãããä»åã¯
name="toString"
ã§åã³ãã©ãããåŒã³åºãããŸãã ãªã©ãªã©ã
ãã³ãã©ãŒãšããŠã®ãããã·
ãããã·ãã³ãã©ãŒèªäœããããã·ã«ããããšãã§ããŸãã 以äžã®ãããã·ãã¬ãŒãµãŒã¯ãã®ãã¿ãŒã³ããã¡ã€ã³åããåäžã®getããã¯ãä»ããŠãã³ãã©ãŒã®ãã¹ãŠã®æäœã®ããã³ããªã³ã°ããäœæããããã«äœ¿çšãããŸãã
ãããã·ãã¬ãŒãµãŒ/ãããã·ãããŒã
ãã¬ãŒãµãŒã¯ãåŠçãããã¹ãŠã®æäœã®èª¬æãåã«åºåããŸãã ããã¯ããããã°ããããã·ã®åäœæ¹æ³ãåŠç¿ããã®ã«éåžžã«åœ¹ç«ã¡ãŸãã
çããŠããäŸ
ãããŒãã«ã¯ããã¬ãŒãµãŒãšåæ§ã®ããžãã¯ããããé©çšããããã¹ãŠã®ã¡ã¿ã¬ãã«ã®æäœãèšé²ããŸãã
çããŠããäŸ
ãã€äœ¿çšã§ããŸããïŒ
çŸåšãFirefox 4.0ã®ã¿ããããã·ããµããŒãããŠããŸãã æ¡åŒµãšããŠNode.jsã®ãããã·å®è£ ããããŸã ïŒ node-overload ïŒéšåçãªãµããŒãïŒ node-proxy ïŒã»ãŒå®å šãªãµããŒãïŒã ãããã«ããããããã·ã¯æšæºã«å«ãŸããããããã©ãŠã¶ã«ãããã«è¡šç€ºãããŸãïŒ
è¿œå ã®ãªãœãŒã¹
1. ECMAScript Harmony
2. Mozilla Developer Networkã®ããã¥ã¡ã³ã
3.æšæºã®éçºïŒ DLS 2010ã§ç€ºããããã®Google Tech Talkãšãã®ããŒããŒã®æåã®éšåã
4. Brendan Eichã¯åœŒã®ããã°ã§Proxyã®åºæ¬ãç°¡åã«èª¬æããŠããŸãã
5. Firefox 4ã®ãªãŒãã³ãããã·ã®åé¡ã®éšåçãªãªã¹ã ã
6. jsconfã®çµŠäžãããã¬ã³ãã³ã»ãšã€ããã¹ã©ã€ã
èšäºã§äœ¿çšããããªãœãŒã¹
1. MDCãããã·ïŒãã©ããïŒ
2. ES5ãã£ãããªãŒã«ãããã·
3. ãããã·ã€ã³ã»ãã·ã§ã³ ïŒãã¬ã³ãã³ã¢ã€ãïŒ
4. ãã¥ãŒããªã¢ã«ïŒHarmony Proxies ïŒTom Van CutsemïŒ
äžæãªç¹ãããå Žåã¯ã質åãããã¹ã©ã€ããã芧ãã ããã ææ¡ãåžæãæ¹å€ã¯å€§æè¿ã§ãïŒ