JavaScript: The Definitive Guide, Sixth Editio javaScript权威指南(第6版) pdf 文字版-文字版, javascript电子书, 和javascript 有关的电子书:

9.8.6 Property Descriptors

9.8.6 Property Descriptors


§6.7 described the property descriptors of ECMAScript 5 but didn’t include many examples of their use. We conclude this section on ECMAScript 5 with an extended

9.8 Classes in ECMAScript 5 | 243

example that will demonstrate many operations on ECMAScript 5 properties. Example 9-23 will add a properties() method (nonenumerable, of course) to Object.prototype. The return value of this method is an object that represents a list of properties and defines useful methods for displaying the properties and attributes (useful for debugging), for obtaining property descriptors (useful when you want to copy properties along with their attributes), and for setting attributes on the properties (useful alternatives to the hideProps() and freezeProps() functions defined earlier). This one example demonstrates most of the property-related features of ECMAScript 5, and also uses a modular coding technique that will be discussed in the next section.

Example 9-23. ECMAScript 5 properties utilities

/*

*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.

9.8 Classes in ECMAScript 5 | 245

欢迎转载,转载请注明来自一手册:http://yishouce.com/book/1/31389.html
友情链接It题库(ittiku.com)| 版权归yishouce.com所有| 友链等可联系 admin#yishouce.com|粤ICP备16001685号-1