封装属性访问器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var obj = {};Object .defineProperty(obj, "a" , { set : function (newVal) { document .getElementById("a" ).value = newVal; document .getElementById("b" ).innerHTML = newVal; }, }); document .addEventListener("keyup" , function (e ) { obj.a = e.target.value; });
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。存取描述符是由 getter-setter 函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。
数据描述符和存取描述符均具有以下可选键值:
当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。
当且仅当该属性的 enumerable 为 true 时,该属性才能够出现在对象的枚举属性中。默认为 false。
数据描述符同时具有以下可选键值:
该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
当且仅当该属性的 writable 为 true 时,value 才能被赋值运算符改变。默认为 false。
存取描述符同时具有以下可选键值:
一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined。
一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined。
如果一个描述符不具有 value,writable,get 和 set 任意一个关键字,那么它将被认为是一个数据描述符。如果一个描述符同时有(value 或 writable)和(get 或 set)关键字,将会产生一个异常。
angular 1.x 的数据绑定原理 在未引入 angluar1.x 的情况下,要实现 angular1.x 的数据绑定设计,大概会是下面这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>two-way binding</title> </ head> <body onload="init()" > <button ng-click="inc" > increase 1 </button> <button ng-click="inc2"> increase 2 </ button> <span style="color:red" ng-bind="counter" ></span> <span style="color:blue" ng-bind="counter"></ span> <span style="color:green" ng-bind="counter" ></span> <script type="text/ javascript"> /* 数据模型区开始 */ var counter = 0; function inc() { counter++; } function inc2() { counter+=2; } /* 数据模型区结束 */ /* 绑定关系区开始 */ function init() { bind(); } function bind() { var list = document.querySelectorAll(" [ng-click]"); for (var i=0; i<list.length; i++) { list[i].onclick = (function(index) { return function() { window[list[index].getAttribute(" ng-click")](); apply(); }; })(i); } } function apply() { var list = document.querySelectorAll(" [ng-bind='counter' ]"); for (var i=0; i<list.length; i++) { list[i].innerHTML = counter; } } /* 绑定关系区结束 */ </script> </body> </html>
ECMA2015 的新特性 Proxy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 let validator = { set : function (obj, prop, value) { if (prop === "age" ) { if (!Number .isInteger(value)) { throw new TypeError ("The age is not an integer" ); } if (value > 200 ) { throw new RangeError ("The age seems invalid" ); } } obj[prop] = value; return true ; }, }; let person = new Proxy ({}, validator);person.age = 100 ; console .log(person.age); person.age = "young" ; person.age = 300 ;
几个被废弃的方案 1 Object.observe(obj, callback[, acceptList]) 方法对对象(或者其属性)进行监控观察,一旦其发生变化时,将会执行相应的 handler。
现在 Object.observe 将不加入 es7 An update on Object.observe
2 Object.prototype.watch(prop, handler) 方法对对象属性进行监控观察,一旦其发生变化时,将会执行相应的 handler。
此方法只在 Firefox 58 之前的 Firefox 中实现,其余浏览器及浏览器版本均不实现此方法 Object.prototype.watch()