<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>属性的操作</title> </head> <body> <script type="text/javascript"> //bind 兼容 if(!Function.prototype.bind){ Function.prototype.bind = function(scope){ var _this = this; return function(){ _this.call(scope); } } } /** * getter: 获取某一个对象的某个属性之前会回调的这个属性的getter的钩子函数 * setter: 设置某一个对象的某个属性之前会回调的这个属性的setter的钩子函数 * *一个对象的任意属性在没有设置setter和getter钩子函数的时候,默认系统有实现 */ var model = { name: "star", message: "this is message", isShow: true }; // function observerFactory(model){ for (var property in model ){ addOSer(model, property, model[property]); } } function addOSer(model, property, value){ Object.defineProperty(model, property,{ // value:"star", // writable:false,//是否可写入 enumerable: true,//是否可meiju configurable: false,//是否以后还可以配置name属性 set:function(nvalue){ console.log("进入set设置"); this.value = nvalue; }, get:function(){ console.log("进入get设置"); return this.value; } }); } observerFactory(model); model.name = "xxx"; // function observerFactory(model){ // for (var property in model){ // model.__defineSetter__(property, function(value){ // /** // * 问题:property循环出来的一直是isShow, // * 原因:闭包问题, observerFactory(model);执行了3次,所以property输出来的一直是isShow // * 解决办法:用ES6语法,把var改成let(let指的是:只在当前的作用域有用) // */ // console.log("已经进入了"+ property +"属性的setter"); // this.value = value; // }); // model.__defineGetter__(property, function(){ // console.log("已经进入了"+ property +"属性的getter"); // return this.value; // }); // } // } // observerFactory(model); /** * 我们可以在对象的原型链上找到这些方法,有些方法不是不存在,而是我们不关心它, * __defineGetter__(定义Getter):只要看到下划线开头的属性或者函数,代表是隐私的意思,不想让外面访问或者更改 * __defineGetter__基于原型链的,所以每个对象都有__defineGetter__方法 * * Object.defineGetter(); 静态方法 static model,准许我们使用的 * __defineGetter__(私有的,可以调用)和Object.defineGetter()区别: * __defineGetter__私有的,可以调用,但是javascript引擎想告诉我们最好不要这个用,强行用也是可以的, * javascript提供了Object.defineGetter方法,这个方法和__defineGetter__一样,推荐使用Object.defineGetter方法 */ // model.__defineSetter__("message", function(value){ // console.log("已经进入了message属性的setter"); // this.value = value; // }); // model.__defineGetter__("message", function(){ // console.log("已经进入了message属性的getter"); // /** // * (强行使用__defineGetter__):这里的this指的model本身, // */ // return this.value; // }); /** * 返回“undefined * 原因:当我们访问message属性的时候,__defineGetter__的钩子函数拦截了 * 当我们访问message的时候,会先调用get message钩子函数,this.value是undefined, * 所以返回的是undefined * *解决办法:需要先设置在获取,先setter再getter */ // model.name = "stas"; console.log(model.name); </script> </body> </html>