zoukankan      html  css  js  c++  java
  • 犀牛书的实例代码:给对象添加freeze, hide, 查询descriptors

        /*
         * Define a properties() method in Object.prototype that returns an
         * object representing the named properties of the object on which it
         * is invoked (or representing all own properties of the object, if
         * invoked with no arguments).  The returned object defines four useful
         * methods: toString(), descriptors(), hide(), and show().
         */
        (function namespace() {  // Wrap everything in a private function scope
    
            // This is the function that becomes a method of all object
            function properties() {
                var names;  // An array of property names
                if (arguments.length == 0)  // All own properties of this
                    names = Object.getOwnPropertyNames(this);
                else if (arguments.length == 1 && Array.isArray(arguments[0]))
                    names = arguments[0];   // Or an array of names
                else                        // Or the names in the argument list
                    names = Array.prototype.splice.call(arguments, 0);
    
                // Return a new Properties object representing the named properties
                return new Properties(this, names);
            }
    
            // Make it a new nonenumerable property of Object.prototype.
            // This is the only value exported from this private function scope.
            Object.defineProperty(Object.prototype, "properties", {
                value: properties,
                enumerable: false, writable: true, configurable: true
            });
    
            // This constructor function is invoked by the properties() function above.
            // The Properties class represents a set of properties of an object.
            function Properties(o, names) {
                this.o = o;            // The object that the properties belong to
                this.names = names;    // The names of the properties
            }
    
            // Make the properties represented by this object nonenumerable
            Properties.prototype.hide = function() {
                var o = this.o, hidden = { enumerable: false };
                this.names.forEach(function(n) {
                    if (o.hasOwnProperty(n))
                        Object.defineProperty(o, n, hidden);
                });
                return this;
            };
    
            // Make these properties read-only and nonconfigurable
            Properties.prototype.freeze = function() {
                var o = this.o, frozen = { writable: false, configurable: false };
                this.names.forEach(function(n) {
                    if (o.hasOwnProperty(n))
                        Object.defineProperty(o, n, frozen);
                });
                return this;
            };
    
            // Return an object that maps names to descriptors for these properties.
            // Use this to copy properties along with their attributes:
            //   Object.defineProperties(dest, src.properties().descriptors());
            Properties.prototype.descriptors = function() {
                var o = this.o, desc = {};
                this.names.forEach(function(n) {
                    if (!o.hasOwnProperty(n)) return;
                    desc[n] = Object.getOwnPropertyDescriptor(o,n);
                });
                return desc;
            };
    
            // Return a nicely formatted list of properties, listing the
            // name, value and attributes. Uses the term "permanent" to mean
            // nonconfigurable, "readonly" to mean nonwritable, and "hidden"
            // to mean nonenumerable. Regular enumerable, writable, configurable
            // properties have no attributes listed.
            Properties.prototype.toString = function() {
                var o = this.o; // Used in the nested function below
                var lines = this.names.map(nameToString);
                return "{
      " + lines.join(",
      ") + "
    }";
    
                function nameToString(n) {
                    var s = "", desc = Object.getOwnPropertyDescriptor(o, n);
                    if (!desc) return "nonexistent " + n + ": undefined";
                    if (!desc.configurable) s += "permanent ";
                    if ((desc.get && !desc.set) || !desc.writable) s += "readonly ";
                    if (!desc.enumerable) s += "hidden ";
                    if (desc.get || desc.set) s += "accessor " + n
                    else s += n + ": " + ((typeof desc.value==="function")?"function"
                            :desc.value);
                    return s;
                }
            };
    
            // Finally, make the instance methods of the prototype object above
            // nonenumerable, using the methods we've defined here.
            Properties.prototype.properties().hide();
        }()); // Invoke the enclosing function as soon as we're done defining it.
  • 相关阅读:
    [BZOJ 4318] OSU!
    [BZOJ 4720][NOIP 2016] 换教室
    [Tyvj 1729] 文艺平衡树
    [BZOJ 1500]维修数列 [Splay Tree从进阶到住院]
    [学习笔记] CDQ分治 从感性理解到彻底晕菜
    [COGS 1752] 摩基亚Mokia
    [Tyvj 1730] 二逼平衡树
    [学习笔记] Splay Tree 从入门到放弃
    [Tyvj 1728] 普通平衡树
    [BZOJ 3594] 方伯伯的玉米田
  • 原文地址:https://www.cnblogs.com/diligenceday/p/5543504.html
Copyright © 2011-2022 走看看