犀牛书的实例代码:给对象添加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 "{\n  " + lines.join(",\n  ") + "\n}";

            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.
时间: 2024-12-26 06:50:25

犀牛书的实例代码:给对象添加freeze, hide, 查询descriptors的相关文章

点击按钮添加或者删除一行实例代码

点击按钮添加或者删除一行实例代码:网站在填写表达的时候又很多的选择空间,甚至可以自行添加需要添加的内容,例如可以点击按钮添加一个表达项,如果不需要的话可以点击一个按钮删除,下面就简单介绍一下如何实现此效果.代码实例如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="author" content="http://www

jQuery打印json格式对象实例代码

jQuery打印json格式对象实例代码:所谓的json格式对象其实就是对象直接量,很多教程多说这是json对象,其实这是不正确.下面是一段打印json格式对象的实例代码,希望能够对初学者有所帮助.代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.soft

jQuery添加和删除元素class属性实例代码

jQuery添加和删除元素class属性实例代码:元素的的class属性一般是用来设置样式之用,所以添加或者删除都意味着改变元素的样式,下面就介绍一下如何使用jQuery来删除和添加元素的class属性值,希望能够给大家带来一定的帮助.代码实例如下: function switchTeachControl() { var target=$("#thediv"); if(target.hasClass("controlOff")) { target.removeCla

将表单元素转换为json格式对象实例代码

将表单元素转换为json格式对象实例代码:在实际引用中,有可能需要将表单元素转换为json格式对象,也就是对象直接量以便于处理,下面就是一段这样的实例代码.代码实例如下: <script type="text/javascript"> (function($){ $.fn.serializeObject=function(){ var inputs=$(this).find("input,textarea,select"); var o={}; $.ea

鼠标指针停止运动触发事件实例代码

鼠标指针停止运动触发事件实例代码:在js中有有内置的鼠标各种事件,比如click事件,mousemove事件等等,但是并没有鼠标指针停止运动这个事件,下面就利用jquery模拟实现此效果,希望能够给需要的朋友带来一定的帮助.代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="ht

你会如何给全局对象添加toString()方法

首先,在讨论如何给所有方法window对象添加tostring方法的时候,我们先来说说window的对象继承与对象实例,以及构造函数的this指针,还有变量的提升与方法的调用方式,最终一探window对象与Window方法(函数)的处理方式. 在说window对象之前,请让我们一起写一个实例的方法暖暖身,跳水之前应该做热身动作,虽然我们不跳水,不过写代码也需要做一个热身,这样才能适应下面的高难度动作. 废话好多,裁判看不下去了,开始准备你的姿势,让我们开场就拿个满分,吓死裁判,但是看到裁判吓到自

(转)深入理解JavaScript的闭包特性 如何给循环中的对象添加事件

深入理解JavaScript的闭包特性如何给循环中的对象添加事件 初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript的闭包特性. 有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4. 1.  <!DOCTYPE HTML> 2.  <html> 3.  <head&g

给对象添加方法和属性

为了减少所写JS代码对全局环境的污染, 可以采用对象写法来实现命名空间技术, 以使得局部变量和函数都在对象中作为属性存在,它们组成某个主题(对象名称体现)的相关属性和方法的集合. 如下例: var MyLib = {}; // global Object cointainer MyLib.value = 1; MyLib.increment = function() { MyLib.value++; } MyLib.show = function() { alert(MyLib.value);

深入理解JavaScript的闭包特性如何给循环中的对象添加事件

初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript的闭包特性. 有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4. 1.  <!DOCTYPE HTML> 2.  <html> 3.  <head> 4.  <meta charset="utf