参考自<<JavaScript权威指南 第6版>>, 文字太多反而不易理清其中的关系, 直接上代码和注释
1 /* 2 * 对象的setter和getter属性: 3 * 定义为一个或者两个和属性同名的函数, 这个函数不用function,而是使用get 或 set, 4 * 作用和java中的getter/setter很类似. 但是他们并不是函数,所以调用方式也比较特别. 5 */ 6 var demo = { 7 data: 100, 8 get get_data(){ 9 return this.data; 10 }, 11 set set_data(data){ 12 this.data = data; 13 } 14 }; 15 console.log(demo.get_data); 16 demo.set_data = 200; 17 console.log(demo.get_data); 18 19 20 //ECMScript 5 中定义了对象 propertyDescriptor 对象, 用来实现属性特性的查询和设置操作. 21 console.log(Object.getOwnPropertyDescriptor({x:1},"x")); // 查询自有属性描述符 22 23 /* 24 * Object.defineProperty():为已存在的对象添加自有属性或者修改自有属性,但是不能修改继承属性. 25 * 如果需要同时修改多个属性, 则需要使用Object.defineProperties(). 26 */ 27 28 /* js 代码默认创建的对象是: 可读,可写,可配置,可枚举的和可扩展的 29 * 可扩展指: 可以添加新属性. 30 * 判断方式: Object.isExtensible(obj); 31 * 禁止方式: Object.preventExtensions(obj); 32 */ 33 //为obj对象添加一个不可枚举的变量x, 所以输出的是{} 34 var obj = {}; 35 Object.defineProperty(obj,"x",{value:1, writable:true,enumerable:false, configurable:true}); 36 console.log(obj); //"{}" 37 console.log("x" in obj);//"true", 属性x是存在的 38 Object.defineProperty(obj,"x",{writable:false}); 39 obj.x = 100; // 不会报错, 但是什么都不会做.在严格模式中抛出 TypeError 40 console.log(obj.x); //输出: 1, 没有被改变 41 //通过配置来修改属性x 42 Object.defineProperty(obj,"x",{value:2}); // 修改x的值, 直接修改不可以,通过配置修改就ok 43 console.log(obj.x);//输出: 2 44 Object.defineProperty(obj,"x",{get:function(){return 100;} }); // 修改属性x为一个存取器 45 console.log(obj.x); // 输出: 100 46 /* 47 * Object.defineProperties()直接为要修改的对象添加3个属性, 然后返回到新对象r 48 */ 49 var t = {s:100}; 50 var p = Object.defineProperties(t,{ 51 x:{value:1,writable:true,enumerable:true,configurable:true}, 52 y:{value:1,writable:true,enumerable:true,configurable:true}, 53 r:{ 54 get: function(){ 55 return Math.sqrt(this.x * this.x + this.y * this.y); 56 }, 57 enumerable:true, 58 configurable:true 59 } 60 }); 61 console.log(p); // { s: 100, x: 1, y: 1, r: [Getter] } 62 console.log(p.r); //1.4142135623730951 63 console.log(t); //{ s: 100, x: 1, y: 1, r: [Getter] } 原来的对象t也被修改了, 和p对象一样 64 65 /* 66 * 使用js自带的extend()函数只能简单复制属性名和值,不能复制属性的特性和getter/setter(简单地转换为静态的数据属性), 67 * 下面进行深拷贝. 68 */ 69 Object.defineProperty(Object.prototype, 70 "extend", //定义Object.prototype.extend 71 { 72 writable:true, 73 enumerable:false, 74 configurable:true, 75 value:function(obj){ 76 var names = Object.getOwnPropertyNames(obj); //得到所有的自有属性 77 for(var i=0;i<names.length;++i){ 78 if(names[i] in this) 79 continue; //跳过已有属性 80 var desc = Object.getOwnPropertyDescriptor(obj,names[i]); 81 Object.defineProperty(this,names[i],desc); // 复制属性和属性的配置. 82 } 83 } 84 }); 85 86 var r ={}; 87 r.extend(p); 88 console.log(r); //复制了p的属性和属性配置. 89 console.log(Object.getOwnPropertyDescriptor(r,"x")); 90 91 /*设置对象的可扩展性: 92 * - 对象转换为不可扩展后就无法转成可扩展了. 93 * - preventExtensions 只影响对象本身, 原型链上新加入的属性也会加入到不可扩展的对象上. 94 *更多方法: Object.seal()/Object.isSealed(), Object.freeze()/Object.isFreeze() 95 */ 96 console.log(Object.isExtensible(r)); //"true" 97 Object.preventExtensions(r); 98 console.log(Object.isExtensible(r)); //"false" 99 100 /* 101 * 对象的序列化 102 * - JSON.stringify() 序列化对象可枚举的自有属性. 103 * - JSON.parse() 还原js对象 104 */ 105 var obj = {x:1,y:{ 106 z:[false,null,""] 107 }}; 108 var s = JSON.stringify(obj); 109 var t = JSON.parse(s); //t 是 s 的深拷贝 110 console.log(s); 111 console.log(t);
时间: 2024-10-27 23:16:29