ã¡ãã£ã¨åã«
Microsoft å
¬å¼ã«ä»¥ä¸ã®ãããªçºè¡¨ãããã¾ããã
Responding to Change: Updated Getter/Setter Syntax in IE8 RC 1 – IEBlog
ã¾ãã以ä¸ã®ãããªããã¥ã¡ã³ããå
¬éããã¦ãã¾ãã
ãããã®å 容ã§ã®æ¦è¦ãèªåãªãã«ã¾ã¨ãã¦ã¿ã¾ãã
æ¦ç¥
è¦ç¹ã¯
- DOM ãªãã¸ã§ã¯ãã®ãããã¿ã¤ãã使ããããã«ãªã
- DOM ãªãã¸ã§ã¯ãã«æ¢åã® Getter/Setter API ã使ããããã«ãªã
- DOM ãªãã¸ã§ã¯ãã« ECMAScript 3.1 ã® Getter/Setter APIï¼PropertyDescriptorï¼ã使ããããã«ãªã
- DOM ãªãã¸ã§ã¯ã以å¤ã® Getter/Setter ã¯åºæ¥ãªã
ã¨ãããã¨ã§ãã
DOM ãªãã¸ã§ã¯ãã®ãããã¿ã¤ãã使ããããã«ãªã
// Element ã®ãããã¿ã¤ãã« isElement ã¨ããããããã£ãä½ãã Element.prototype.isElement = true; // ãããã㨠// è¦ç´ ã« isElement ã¨ããããããã£ãåºæ¥ã alert(document.body.isElement); // true alert(document.createElement('div').isElement); // true // HTMLDocument ã®ãããã¿ã¤ãã« hoge ã¨ããé¢æ°ãä½ã HTMLDocument.prototype.hoge = function() { alert('fuga'); }; // ãããã㨠// document ã« hoge ã¨ããé¢æ°ãåºæ¥ã document.hoge(); // fuga
DOM ãªãã¸ã§ã¯ãã«æ¢åã® Getter/Setter API ã使ããããã«ãªã
// Element ã®ãããã¿ã¤ãã« innerHTML Setter ãåå¾ãã var nativeInnerHTML = Element.prototype.__lookupSetter__('innerHTML'); // Element ã®ãããã¿ã¤ãã« innerHTML Setter ãè¨å®ãã Element.prototype.__defineSetter__('innerHTML', function(html) { alert(this.tagName + 'ã® innerHTML ãè¨å®ããã¾ããï¼'); return nativeInnerHTML.call(this, html); }); // body ã® innerHTML ã«å¤ãè¨å®ãã document.body.innerHTML = '<p>Hello, world!</p>'; // ãbody ã® innerHTML ãè¨å®ããã¾ããï¼ãã¨è¡¨ç¤ºããã
DOM ãªãã¸ã§ã¯ãã« ECMAScript 3.1 ã® Getter/Setter APIï¼PropertyDescriptorï¼ã使ããããã«ãªã
// Element ã®ãããã¿ã¤ãã« innerHTML Setter ãåå¾ãã var nativeInnerHTML = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML').setter; // Element ã®ãããã¿ã¤ãã« innerHTML Setter ãè¨å®ãã Object.defineProperty(Element.prototype, 'innerHTML', { setter: function(html) { alert(this.tagName + 'ã® innerHTML ãè¨å®ããã¾ããï¼'); return nativeInnerHTML.call(this, html); } }); // body ã® innerHTML ã«å¤ãè¨å®ãã document.body.innerHTML = '<p>Hello, world!</p>'; // ãbody ã® innerHTML ãè¨å®ããã¾ããï¼ãã¨è¡¨ç¤ºããã
DOM ãªãã¸ã§ã¯ã以å¤ã® Getter/Setter ã¯åºæ¥ãªã
// ä¸è¨ã¯ã¨ã©ã¼ãçºçãã Object.defineProperty(Object.prototype, 'hoge', { setter: function() { alert('fuga') } }); // Error!
以ä¸ãåç §ãã¦ãã ããã
The first parameter (the object on which to attach the accessor) supports only DOM instances, interface objects and interface prototype objects in Internet Explorer 8.
Internet Explorer for Developers | Microsoft Docs
ãã ããã®ãã¡åºæ¥ãããã«ãããçãªãã¨ã¯ãããã¦ãã¾ããã
å½ç¶ããªãã¸ã§ã¯ããªãã©ã«å
ã§å®ç¾©ãããã¨ã¯åºæ¥ãªãã¨æããã¾ãã
ã¨ãããã
ããã§è¨ããããã¨ã¯çµãããªã®ã§ããããããã§ã¤è©³ãããã¨ãæ¸ãã¦ããã¾ãã
Getter/Setter API ã®èæ¯ã¨æµã
Getter/Setter API ã«é¢ãã¦ã¯ãã¡ãã£ã¨è¤éãªçµç·¯ãããã®ã§ããã¾ã§ã®æµããç´¹ä»ãã¾ãã
- ECMAScript 3 ã®ä»æ§ãåºã¾ãããã®æç¹ã§ Setter/Getter API ã®ä»æ§ã¯åå¨ããªã
- Firefox ãåæã« Getter/Setter API ãå®è£ ï¼ãããããã£ãç´¹ä»ãããæ¢åã® Getter/Setter APIãï¼
- Safari, Opera ãããã追å¾
- IE8 Beta2 ãããã追å¾
- ECMAScript 3.1 ã§ãæ°ãã Getter/Setter ã®ä»çµã¿ï¼PropertyDescriptorï¼ããã³ãã® API ãä»æ§åããã
- IE8 ã§ã¯ãæ¢åã® API ãæ®ãã¤ã¤ãæ°ãã API ãå®è£ ãããã¨ã«æ±ºå®ï¼âã¤ãã³ã³ï¼ï¼
- Mozilla, Opera, Apple, Google ã ECMAScript 3.1 ã®ä»æ§ã«åæãã¦ããã®ã§ããã®æµãã«è¿½å¾ãããã®ã¨æãããã
ããããæµãããã£ããã§ããã
ãããã¿ã¤ãã¨ã¯ä½ã
ããã¯ãä½åãæ¸ãã¦ããã¨æãã®ã§ããä½åã§ãæ¸ãã¾ãï¼
ãããã¿ã¤ãã¨ã¯è¤æ°ãªãã¸ã§ã¯ãã®å ±éããããã£ãæã¤ãªãã¸ã§ã¯ã
ãããã¿ã¤ãã¨ã¯ãè¤æ°ã®ãªãã¸ã§ã¯ãã®å
±éããããã£ãæã¤ãªãã¸ã§ã¯ãã§ãã
ãã¨ãã°ã document.body ã document.documentElement ã document.createElement('div') ã®å
±éããããã£ãæã£ã¦ããã®ã Element.prototype ã¨ãããªãã¸ã§ã¯ãã§ãã
以ä¸ã®ä¾ãã¿ã¦ãã ããã
var body = document.body; var html = document.documentElement; var div = document.createElement('div'); Element.prototype.hoge = 1; alert(body.hoge); // 1 alert(html.hoge); // 1 alert(div.hoge); // 1 Element.prototype.hoge = 2; alert(body.hoge); // 2 alert(html.hoge); // 2 alert(div.hoge); // 2
ç°¡åã§ãããã
ããã®ã Element.prototype ã document.body ã document.documentElement ã document.createElement('div') ã®ããã¿ã¤ãã§ãã
å ±éããããã£ã®ä»£è¡¨ã¯ã¡ã½ãã
ãã®ä»çµã¿ã¯ä¸»ã«ã¡ã½ããã§ä½¿ããã¾ãã
ãã¨ãã°ã以ä¸ã®ããã« Element.prototype ã«ã¡ã½ãããä½ã㨠body ã div ã§ãå¼ã³åºããããã«ãªãã®ã§ãã
var body = document.body; var html = document.documentElement; var div = document.createElement('div'); Element.prototype.sayTagName = function() { alert(this.tagName) }; body.sayTagName(); // BODY html.sayTagName(); // HTML div.sayTagName(); // DIV
ãã¨ãã°ããã©ã¦ã¶ã®å®è£ ã«ãããã¾ãã appendChild ã removeChild ãªã©ã®ã¡ã½ããããããã¿ã¤ãã§å®ç¾©ããã¦ãã¾ãã
IE ã§ãDOM ãªãã¸ã§ã¯ãã®ãããã¿ã¤ãã使ããããã«ãªããã¨ã¯ã©ããããã¨ãªã®ã
ä»ã¾ã§ã® IE ã®ç¹å¾´ã¯
- DOM ãªãã¸ã§ã¯ãã¯ãããã¿ã¤ããæã£ã¦ããªã
- DOM ãªãã¸ã§ã¯ãã®å®è£ ãæ¨æºä»æ§ã«å¾ã£ã¦ããªãï¼ä¸»ã«ã¤ãã³ãå¨ãï¼
ã¨ããã¨ããã§ããã
ããã IE8 ããã¯
- DOM ãªãã¸ã§ã¯ãããããã¿ã¤ããæã£ã¦ããï¼New!!ï¼
- DOM ãªãã¸ã§ã¯ãã®å®è£ ãæ¨æºä»æ§ã«å¾ã£ã¦ããªãï¼ä¸»ã«ã¤ãã³ãå¨ãï¼
ã¨ãã風ã«ãªã£ãã®ã§ãã
ããã¯ã©ããããã¨ã
æ¨æºä»æ§ã«å¾ã£ã¦ããªãé¨åããããã¿ã¤ãã«å±æåãããã¨ãããã¨ã«ãªãã¾ãã
ã¨ãããã¨ã¯ã JavaScript ãæ¸ã人ã¯ãããã¿ã¤ããæ¨æºæºæ ã® API ã«æ¸ãæãã¦ãã¾ããã¨ãåºæ¥ãããã«ãªã£ãã®ã§ãã
ãã¨ãã°ã以ä¸ã®è¨äºã®ããã« IE ã« addEventListener ãå®è£
ãããã¨ãåºæ¥ã¾ãã
// Apply addEventListener to all the prototypes where it should be available. HTMLDocument.prototype.addEventListener = Element.prototype.addEventListener = Window.prototype.addEventListener = function (type, fCallback, capture) { var modtypeForIE = "on" + type; if (capture) { throw new Error("This implementation of addEventListener does not support the capture phase"); } var nodeWithListener = this; this.attachEvent(modtypeForIE, function (e) { // Add some extensions directly to 'e' (the actual event instance) // Create the 'currentTarget' property (read-only) Object.defineProperty(e, 'currentTarget', { getter: function() { // 'nodeWithListener' as defined at the time the listener was added. return nodeWithListener; } }); // Create the 'eventPhase' property (read-only) Object.defineProperty(e, 'eventPhase', { getter: function() { return (e.srcElement == nodeWithListener) ? 2 : 3; // "AT_TARGET" = 2, "BUBBLING_PHASE" = 3 } }); // Create a 'timeStamp' (a read-only Date object) var time = new Date(); // The current time when this anonymous function is called. Object.defineProperty(e, 'timeStamp', { getter: function() { return time; } }); // Call the function handler callback originally provided... fCallback.call(nodeWithListener, e); // Re-bases 'this' to be correct for the callback. }); } // Extend Event.prototype with a few of the W3C standard APIs on Event // Add 'target' object (read-only) Object.defineProperty(Event.prototype, 'target', { getter: function() { return this.srcElement; } }); // Add 'stopPropagation' and 'preventDefault' methods Event.prototype.stopPropagation = function () { this.cancelBubble = true; }; Event.prototype.preventDefault = function () { this.returnValue = false; };Internet Explorer for Developers | Microsoft Docs
ãMSDN ã«æ¸ãã¦ãæããããªãï¼ãããå®è£ ãã¦åºè·ãã¦ãããï¼ï¼ï¼ãã¨ããè¨èã¯ãã¿ç· ãã¦ããã¾ãããã
ãããã¿ã¤ãã ãã§ã¯è§£æ±ºã§ããªãéäºæ
DOM ã®ããããã£ã«ã¯ä»£å
¥ãç¹æ®ãªæå³ãæã¤ã¨ãããã¨ãå¤ã
ããã¾ãã
ãã¨ãã°ã
document.body.innerHTML = '<p>hoge</p><p>fuga</p><p>piyo</p>'; alert(document.body.childNodes.length);ã// 3 document.body.innerHTML = '<p>hoge</p><p>fuga</p>'; alert(document.body.childNodes.length); // 2
ãã®ããã«ã代å
¥ãããã¨èªä½ã«ä»£å
¥ä»¥å¤ã®æå³ããããã¨ãå¤ã
ããã®ã§ãã
ãã®ãããªããããã£ã«éäºæãããå ´åã¯ããããã¿ã¤ããããã ãã§ã¯è§£æ±ºãã§ãã¾ããã
ã©ããã¦ãã Getter/Setter ã¨ããä»çµã¿ãå¿
è¦ãªã®ã§ãã
ãããã Getter/Setter ã£ã¦ãªããªã®ãï¼
Getter/Setter ã¨ã¯ãããããã£ã®ä»£å
¥ãåç
§ãçºçããã¨ãã«ãæå®ããé¢æ°ãªãã¸ã§ã¯ããå¼ã³åºãä»çµã¿ã§ãã
ãã¨ãã°ã以ä¸ã®ãããªãã®ã§ãã
var obj = {}; // hoge ã¨ãã Getter ãä½ã obj.__defineGetter__('hoge', function() { return 1 }); alert(obj.hoge); // 1 // hoge ã¨ãã Setter ãä½ã obj.__defineSetter__('hoge', function(v) { this._v = v; return v * 2 }); alert(obj.hoge = 2); // 4 alert(obj._v); // 2
æ¢åã® Getter/Setter API ã®è©³ç´°
Firefox, Safari, Opera ã§ä½¿ãã Getter/Setter API ã®è©³ç´°ã説æãã¾ãã
- __defineGetter__
- __defineSetter__
- __lookupGetter__
- __lookupSetter__
- ãªãã¸ã§ã¯ããªãã©ã«å ã§å®ç¾©
__defineGetter__
ã²ãã¿ã¼ãä½ãã¾ãã
document.body.__defineGetter__('hoge', function() { return 'fuga'; }); alert(document.body.hoge); // fuga
__defineSetter__
ã»ãã¿ã¼ãä½ãã¾ãã
document.body.__defineSetter__('hoge', function(v) { this.v = v * 2; return v; }); var a = document.body.hoge = 2; // ãã®ããã«ããã¨ãã« a ã«ã¯ã»ãã¿ã¼ãè¿ããå¤ãå ¥ã
è¿ãå¤ã¨ãã¦ãåãåã£ãå¤ãè¿ãããã«ãã¦ãããªãã¨å¼ã®å¤ããããããªãã®ã§æ³¨æãå¿ è¦ã§ãã
__lookupGetter__
ã²ãã¿ã¼ãæ¢ãã¾ãã
var innerHTMLGetter = document.body.__lookupGetter__('innerHTML'); // innerHTML ãåç §ããã¨ãã¨åããã¨ãã§ãã innerHTMLGetter.call(document.body);
ãã®ã¨ãã __lookupGetter__ ã¯ãããã¿ã¤ããæã¤ã²ãã¿ã¼ãæ¢ãã¦ããã¾ãã
__lookupSetter__
ã²ãã¿ã¼ãæ¢ãã¾ãã
var innerHTMLSetter = document.body.__lookupSetter__('innerHTML'); // innerHTML ã« 'hoge' ãä»£å ¥ããã¨ãã¨åããã¨ãã§ãã innerHTMLSetter.call(document.body, 'hoge');
åæ§ã«ã __lookupSetter__ ã¯ãããã¿ã¤ããæã¤ã²ãã¿ã¼ãæ¢ãã¦ããã¾ãã
ãªãã¸ã§ã¯ããªãã©ã«ä¸ã«å®ç¾©
以ä¸ã®ãã㪠set/get ãã¼ã¯ã¼ãã使ã£ã¦ããªãã¸ã§ã¯ããªãã©ã«ä¸ã§å®ç¾©ãããã¨ãã§ãã¾ãã
var hoge = { get a() { return this._a * 2 }, set a(v) { this._a = v; return v } }; hoge.a = 1; alert(hoge.a); // 2
ãããã¿ã¤ã㨠Getter/Setter API ã ãã§ã¯å¯¾å¿ã§ããªãå¾®å¦ãªåé¡
ãããã¿ã¤ãã¨æ¢åã® Getter/Setter API ãããã°ãã»ã¨ãã©ã®éäºæã«ããåé¡ã¯è§£æ±ºã§ããã®ã§ããã
- ããããã£ã for in ãããããããªãã
- ããããã£ãæ¸ãæãå¯è½ã
- ããããã£ãåé¤å¯è½ã
ã«ä¾åããã³ã¼ããåå¨ããå ´åã¯ãæ¢åã® Getter/Setter API ã§ã¯å¯¾å¦ãããã¨ãã§ãã¾ããã
ãã®ä»£è¡¨çãªä¾ã¯ãªãã¸ã§ã¯ããããã·ã¥ã¨ãã¦ä½¿ã£ã¦ããå ´åãªã©ã§ãã
ãã®å¾®å¦ãªåé¡ã解決ããããã«ã¯ã
- ããããã£ã for in ãããããããªãã
- ããããã£ãæ¸ãæãå¯è½ã
- ããããã£ãåé¤å¯è½ã
ã¨ããããããã£ã®å±æ§ãè¨å®åºæ¥ããã¨ãæã¾ãã¾ãã
ECMAScript 3.1 ã® PropertyDescriptor ã使ã㨠Getter/Setter ãä½ããã¨ã¨åæã«ãããã®ããããã£ã®å±æ§ãè¨å®ãããã¨ãåºæ¥ãããã«ãªãã¾ãã
ECMAScript 3.1 ã® PropertyDescriptor ã®è©³ç´°
ECMAScript 3.1 ã§ã¯ Getter/Setter ãããåé¤å¯è½ããæ¸ãæãå¯è½ãã for in ãããããã¨ããå±æ§ããããããã£ã®å¤ããã¹ã¦ PropertyDescriptor ã¨ãããã®ã§æ±ããã¾ãã
ã¤ã¾ããããããã£ã®ç¶æ
ã¯ãã¹ã¦ PropertyDescriptor ã使ã£ã¦æ±ºãããã¨ãã§ãã¾ãã
ãã® PropertyDescriptor ã«ã¤ãã¦ã®è©³ç´°ã¯ã以åã«è¨äºãæ¸ããã®ã§ãã¡ããããããã ããã
ï¼æ³¨ï¼ä»¥ä¸ã®è¨äºå·çæç¹ã§ flexible ã¨ããååã ã£ãããããã£ã«é¢ãã¦ã¯ãç¾æç¹ã§ configurable ã¨ããååã«å¤æ´ããã¦ãã¾ããï¼
次の JavaScript の仕様はこうなる! ECMAScript 3.0 から 3.1 への変更点まとめ - IT戦記