Created
January 11, 2016 21:37
-
-
Save brettz9/aa962f46baf4d8d3a77b to your computer and use it in GitHub Desktop.
Property utilities
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function getAllPropertyNames(obj) { | |
| var props = []; | |
| do { | |
| Object.getOwnPropertyNames(obj).forEach(function (prop) { | |
| if (props.indexOf(prop) === -1) { | |
| props.push(prop); | |
| } | |
| }); | |
| } while (obj = Object.getPrototypeOf(obj)); | |
| return props; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Submitted to https://developer.mozilla.org/en-US/docs/Enumerability_and_ownership_of_properties | |
| // Note that this is not the most efficient algorithm for all cases, but useful for a quick demonstration | |
| var SimplePropertyRetriever = { | |
| getOwnEnumerables: function (obj) { | |
| return this._getPropertyNames(obj, true, false, this._enumerable); // Or could use for..in filtered with hasOwnProperty or just this: return Object.keys(obj); | |
| }, | |
| getOwnNonenumerables: function (obj) { | |
| return this._getPropertyNames(obj, true, false, this._notEnumerable); | |
| }, | |
| getOwnEnumerablesAndNonenumerables: function (obj) { | |
| return this._getPropertyNames(obj, true, false, this._enumerableAndNotEnumerable); // Or just use: return Object.getOwnPropertyNames(obj); | |
| }, | |
| getPrototypeEnumerables: function (obj) { | |
| return this._getPropertyNames(obj, false, true, this._enumerable); | |
| }, | |
| getPrototypeNonenumerables: function (obj) { | |
| return this._getPropertyNames(obj, false, true, this._notEnumerable); | |
| }, | |
| getPrototypeEnumerablesAndNonenumerables: function (obj) { | |
| return this._getPropertyNames(obj, false, true, this._enumerableAndNotEnumerable); | |
| }, | |
| getOwnAndPrototypeEnumerables: function (obj) { | |
| return this._getPropertyNames(obj, true, true, this._enumerable); // Or could use unfiltered for..in | |
| }, | |
| getOwnAndPrototypeNonenumerables: function (obj) { | |
| return this._getPropertyNames(obj, true, true, this._notEnumerable); | |
| }, | |
| getOwnAndPrototypeEnumerablesAndNonenumerables: function (obj) { | |
| return this._getPropertyNames(obj, true, true, this._enumerableAndNotEnumerable); | |
| }, | |
| // Private static property checker callbacks | |
| _enumerable : function (obj, prop) { | |
| return obj.propertyIsEnumerable(prop); | |
| }, | |
| _notEnumerable : function (obj, prop) { | |
| return !obj.propertyIsEnumerable(prop); | |
| }, | |
| _enumerableAndNotEnumerable : function (obj, prop) { | |
| return true; | |
| }, | |
| // Inspired by http://stackoverflow.com/a/8024294/271577 | |
| _getPropertyNames : function getAllPropertyNames(obj, iterateSelfBool, iteratePrototypeBool, includePropCb) { | |
| var props = []; | |
| while (obj) { | |
| if (iterateSelfBool) { | |
| Object.getOwnPropertyNames(obj).forEach(function (prop) { | |
| if (props.indexOf(prop) === -1 && includePropCb(obj, prop)) { | |
| props.push(prop); | |
| } | |
| }); | |
| } | |
| if (!iteratePrototypeBool) { | |
| break; | |
| } | |
| iterateSelfBool = true; | |
| obj = Object.getPrototypeOf(obj); | |
| }; | |
| return props; | |
| } | |
| }; | |
| function getNonenumerablePropertyNames(obj) { | |
| var props = []; | |
| do { | |
| Object.getOwnPropertyNames(obj).forEach(function (prop) { | |
| if (props.indexOf(prop) === -1 && !obj.propertyIsEnumerable(prop)) { | |
| props.push(prop); | |
| } | |
| }); | |
| } while (obj = Object.getPrototypeOf(obj)); | |
| return props; | |
| } | |
| // Credit http://stackoverflow.com/a/8024294/271577 | |
| function getAllPropertyNames(obj) { | |
| var props = []; | |
| do { | |
| Object.getOwnPropertyNames(obj).forEach(function (prop) { | |
| if (props.indexOf(prop) === -1) { | |
| props.push(prop); | |
| } | |
| }); | |
| } while (obj = Object.getPrototypeOf(obj)); | |
| return props; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function () { | |
| // Dependencies: Object.keys, Object.getOwnPropertyNames, Object.hasOwnProperty | |
| /** | |
| // Obtaining Keys/Properties as Array | |
| Object.keys: direct enumerable | |
| getOwnPropertyNames: direct enumerable and nonenumerable | |
| ?: direct nonenumerable | |
| use for-in: direct and indirect enumerable | |
| getAllPropertyNames (custom function): direct and indirect enumerable and nonenumerable | |
| ?: direct and indirect nonenumerable | |
| ?: indirect enumerable | |
| ?: indirect enumerable and nonenumerable | |
| ?: indirect nonenumerable | |
| */ | |
| function PropertyRetriever (obj) { | |
| this.obj = obj; | |
| } | |
| PropertyRetriever.prototype.getOwnEnumerables = function () { | |
| var obj = this.obj; | |
| return Object.keys(obj); // Could also use for-in with hasOwnProperty | |
| }; | |
| PropertyRetriever.prototype.getOwnNonenumerables = function () { | |
| var obj = this.obj; | |
| return Object.getOwnPropertyNames(obj).reduce(function (prev, prop) { | |
| if (prev.indexOf(prop) === -1 && !obj.propertyIsEnumerable(prop)) { | |
| prev.push(prop); | |
| } | |
| }, []); | |
| }; | |
| PropertyRetriever.prototype.getOwnEnumerablesAndNonenumerables = function () { | |
| var obj = this.obj; | |
| return Object.getOwnPropertyNames(obj); | |
| }; | |
| PropertyRetriever.prototype.getPrototypeEnumerables = function () { | |
| var obj = this.obj; | |
| }; | |
| PropertyRetriever.prototype.getPrototypeNonenumerables = function () { | |
| var obj = this.obj; | |
| }; | |
| PropertyRetriever.prototype.getPrototypeEnumerablesAndNonenumerables = function () { | |
| var obj = this.obj; | |
| }; | |
| PropertyRetriever.prototype.getOwnAndPrototypeEnumerables = function () { | |
| var obj = this.obj; | |
| }; | |
| PropertyRetriever.prototype.getOwnAndPrototypeNonenumerables = function () { | |
| var obj = this.obj; | |
| }; | |
| PropertyRetriever.prototype.getOwnAndPrototypeEnumerablesAndNonenumerables = function () { | |
| var obj = this.obj; | |
| }; | |
| /* | |
| // Enumeration | |
| use Object.keys: direct enumerable | |
| use getOwnPropertyNames: direct enumerable and nonenumerable | |
| ?: direct nonenumerable | |
| for-in: direct and indirect enumerable | |
| use getAllPropertyNames (custom function): direct and indirect enumerable and nonenumerable | |
| ?: direct and indirect nonenumerable | |
| ?: indirect enumerable | |
| ?: indirect enumerable and nonenumerable | |
| ?: indirect nonenumerable | |
| */ | |
| function PropertyEnumerator () { | |
| } | |
| PropertyRetriever.prototype.enumerateOwnEnumerables = function (cb) { | |
| var obj = this.obj; | |
| for (var prop in obj) { | |
| if (obj.hasOwnProperty(prop)) { | |
| cb(obj[prop], prop, obj); | |
| } | |
| } | |
| }; | |
| PropertyRetriever.prototype.enumerateOwnNonenumerables = function (cb) { | |
| }; | |
| PropertyRetriever.prototype.enumerateOwnEnumerablesAndNonenumerables = function (cb) { | |
| }; | |
| PropertyRetriever.prototype.enumeratePrototypeEnumerables = function (cb) { | |
| var obj = this.obj; | |
| for (var prop in obj) { | |
| if (!obj.hasOwnProperty(prop)) { | |
| cb(obj[prop], prop, obj); | |
| } | |
| } | |
| }; | |
| PropertyRetriever.prototype.enumeratePrototypeNonenumerables = function (cb) { | |
| }; | |
| PropertyRetriever.prototype.enumeratePrototypeEnumerablesAndNonenumerables = function (cb) { | |
| }; | |
| PropertyRetriever.prototype.enumerateOwnAndPrototypeEnumerables = function (cb) { | |
| var obj = this.obj; | |
| for (var prop in obj) { | |
| cb(obj[prop], prop, obj); | |
| } | |
| }; | |
| PropertyRetriever.prototype.enumerateOwnAndPrototypeNonenumerables = function (cb) { | |
| }; | |
| PropertyRetriever.prototype.enumerateOwnAndPrototypeEnumerablesAndNonenumerables = function (cb) { | |
| }; | |
| // MULTIPLE-INHERITING CLASS (PropertyEnumerator AND PropertyRetriever) | |
| function PropertyEnumeratorRetriever () { | |
| } | |
| PropertyEnumeratorRetriever.prototype = new PropertyEnumerator; | |
| for (var method in PropertyRetriever.prototype) { | |
| PropertyEnumeratorRetriever.prototype[method] = PropertyRetriever.prototype[method]; | |
| } | |
| // EXPORTS | |
| this.PropertyRetriever = PropertyRetriever; | |
| this.PropertyEnumerator = PropertyEnumerator; | |
| this.PropertyEnumeratorRetriever = PropertyEnumeratorRetriever; | |
| }()); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Could implement other Array methods, like some(), filter(), etc. | |
| function PropertyMapper () { | |
| } | |
| PropertyMapper.prototype.mapOwnEnumerables = function (cb) { | |
| }; | |
| PropertyMapper.prototype.mapOwnNonenumerables = function (cb) { | |
| }; | |
| PropertyMapper.prototype.mapOwnEnumerablesAndNonenumerables = function (cb) { | |
| }; | |
| PropertyMapper.prototype.mapPrototypeEnumerables = function (cb) { | |
| }; | |
| PropertyMapper.prototype.mapPrototypeNonenumerables = function (cb) { | |
| }; | |
| PropertyMapper.prototype.mapPrototypeEnumerablesAndNonenumerables = function (cb) { | |
| }; | |
| PropertyMapper.prototype.mapOwnAndPrototypeEnumerables = function (cb) { | |
| var obj = this.obj; | |
| var ret = []; | |
| for (var prop in obj) { | |
| ret.push(cb(obj[prop], prop, obj)); | |
| } | |
| return ret; | |
| }; | |
| PropertyMapper.prototype.mapOwnAndPrototypeNonenumerables = function (cb) { | |
| }; | |
| PropertyMapper.prototype.mapOwnAndPrototypeEnumerablesAndNonenumerables = function (cb) { | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment