/** Define a properties () method in Object.prototype so 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 AR guments). The returned object defines four useful * methods:tostring (), descriptors (), hide (), and Show (). */(functionnamespace() {//Wrap Everything in a private function scope//This is the function, the becomes a method of all objectfunction Properties () {varNames//An array of property names if(Arguments.length = =0)//All own properties of thisNames = 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 listnames = Array.prototype.splice.call (arguments,0); //Return A new properties object representing the named Properties return NewProperties ( This, names); } //Make it a new nonenumerable property of Object.prototype. //The only value of the exported from this private function scope.Object.defineproperty (Object.prototype,"Properties", {value:properties, enumerable:false, writable:true, Configurable:true }); //This constructor function was 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 is the properties belong to This. names = names;//The names of the properties } //Make the properties represented by this object nonenumerableProperties.prototype.hide =function () {varo = 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 NonconfigurableProperties.prototype.freeze =function () {varo = 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, the maps names to descriptors for these properties. //Use the To copy properties along with their attributes://object.defineproperties (dest, Src.properties (). descriptors ());Properties.prototype.descriptors =function () {varo = This. O, desc = {}; This. Names.foreach (function (n) {if(!o.hasownproperty (n))return; Desc[n]=Object.getownpropertydescriptor (o,n); }); returndesc; }; //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 has no attributes listed.Properties.prototype.toString =function () {varo = This. o;//used in the nested function below varLines = This. Names.map (nametostring); return "{\ n"+ Lines.join (", \ n") +"\ n}"; function nametostring (n) {vars ="", 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"+NElses + = n +": "+ ((typeofdesc.value==="function")?"function":d Esc.value); returns; } }; //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.
Rhino Book Instance code: Add freeze, Hide, query to object descriptors