zoukankan      html  css  js  c++  java
  • JavaScript 操作对象属性(设置属性, setter/getter, 序列化)

    参考自<<JavaScript权威指南 第6版>>, 文字太多反而不易理清其中的关系, 直接上代码和注释

    /*
     * 对象的setter和getter属性:
     * 定义为一个或者两个和属性同名的函数, 这个函数不用function,而是使用get 或 set,
     * 作用和java中的getter/setter很类似. 但是他们并不是函数,所以调用方式也比较特别.
     */
    var demo = {
        data: 100,
        get get_data(){
            return this.data;
        },
        set set_data(data){
            this.data = data;
        }
    };
    console.log(demo.get_data);
    demo.set_data = 200;
    console.log(demo.get_data);
    
    
    //ECMScript 5 中定义了对象 propertyDescriptor 对象, 用来实现属性特性的查询和设置操作.
    console.log(Object.getOwnPropertyDescriptor({x:1},"x"));   // 查询自有属性描述符
    
    /*
     * Object.defineProperty():为已存在的对象添加自有属性或者修改自有属性,但是不能修改继承属性.
     * 如果需要同时修改多个属性, 则需要使用Object.defineProperties().
     */
    
    /* js 代码默认创建的对象是: 可读,可写,可配置,可枚举的和可扩展的
     * 可扩展指: 可以添加新属性. 
     *         判断方式: Object.isExtensible(obj);
     *         禁止方式: Object.preventExtensions(obj);
     */
    //为obj对象添加一个不可枚举的变量x, 所以输出的是{}
    var obj = {};
    Object.defineProperty(obj,"x",{value:1, writable:true,enumerable:false, configurable:true});
    console.log(obj); //"{}"
    console.log("x" in obj);//"true", 属性x是存在的
    Object.defineProperty(obj,"x",{writable:false});
    obj.x = 100;  // 不会报错, 但是什么都不会做.在严格模式中抛出 TypeError
    console.log(obj.x); //输出: 1, 没有被改变
    //通过配置来修改属性x
    Object.defineProperty(obj,"x",{value:2}); // 修改x的值, 直接修改不可以,通过配置修改就ok
    console.log(obj.x);//输出: 2
    Object.defineProperty(obj,"x",{get:function(){return 100;} }); // 修改属性x为一个存取器
    console.log(obj.x); // 输出: 100
    /*
     * Object.defineProperties()直接为要修改的对象添加3个属性, 然后返回到新对象r
     */
    var t = {s:100};
    var p = Object.defineProperties(t,{
        x:{value:1,writable:true,enumerable:true,configurable:true},
        y:{value:1,writable:true,enumerable:true,configurable:true},
        r:{
            get: function(){
                return Math.sqrt(this.x * this.x + this.y * this.y);
            },
            enumerable:true,
            configurable:true
        }
    });
    console.log(p); // { s: 100, x: 1, y: 1, r: [Getter] }
    console.log(p.r); //1.4142135623730951
    console.log(t); //{ s: 100, x: 1, y: 1, r: [Getter] } 原来的对象t也被修改了, 和p对象一样
    
    /*
     * 使用js自带的extend()函数只能简单复制属性名和值,不能复制属性的特性和getter/setter(简单地转换为静态的数据属性),
     * 下面进行深拷贝.
     */
    Object.defineProperty(Object.prototype,
            "extend",  //定义Object.prototype.extend
            {
                writable:true,
                enumerable:false,
                configurable:true,
                value:function(obj){
                    var names = Object.getOwnPropertyNames(obj); //得到所有的自有属性
                    for(var i=0;i<names.length;++i){
                        if(names[i] in this)
                            continue; //跳过已有属性
                        var desc = Object.getOwnPropertyDescriptor(obj,names[i]);
                        Object.defineProperty(this,names[i],desc); // 复制属性和属性的配置.
                    }
                }
            });
    
    var r ={};
    r.extend(p);
    console.log(r); //复制了p的属性和属性配置. 
    console.log(Object.getOwnPropertyDescriptor(r,"x"));
    
    /*设置对象的可扩展性:
     *     - 对象转换为不可扩展后就无法转成可扩展了.
     *  - preventExtensions 只影响对象本身, 原型链上新加入的属性也会加入到不可扩展的对象上.
     *更多方法: Object.seal()/Object.isSealed(), Object.freeze()/Object.isFreeze()
     */
    console.log(Object.isExtensible(r)); //"true"
    Object.preventExtensions(r);
    console.log(Object.isExtensible(r)); //"false"
    
    /*
     * 对象的序列化
     *         - JSON.stringify() 序列化对象可枚举的自有属性.
     *         - JSON.parse()  还原js对象
     */
    var obj = {x:1,y:{
        z:[false,null,""]
    }};
    var s = JSON.stringify(obj);
    var t = JSON.parse(s); //t 是 s 的深拷贝
    console.log(s);
    console.log(t);
    
  • 相关阅读:
    Android View相关知识问答
    AMS工作原理:activity启动
    Android系统启动概要
    源码分析: 图片加载框架Picasso源码分析
    Android组件化、模块化、插件化
    Android技术文章收集
    一个功能强大的日志工具类
    Android Hook技术
    虚函数与纯虚函数
    二叉树的深度并判断是否是平衡二叉树
  • 原文地址:https://www.cnblogs.com/roger9567/p/5035882.html
Copyright © 2011-2022 走看看