Skip to content

Instantly share code, notes, and snippets.

@WebReflection
Created August 20, 2011 08:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WebReflection/1158853 to your computer and use it in GitHub Desktop.
Save WebReflection/1158853 to your computer and use it in GitHub Desktop.
implementing "in" operator as generic object method
(function(Object, String){
// (C) WebReflection - Mit Style License
// @about implementing "in" operator as generic object method
// returns primitive value or object itself
function toValue(obj) {
switch (true) {
case isInstanceOf(obj, Boolean):
case isInstanceOf(obj, Number):
case isInstanceOf(obj, String):
return obj.valueOf();
default:
return obj;
}
}
// reduce occurrences of "instanceof" for minified code
function isInstanceOf(obj, constructor) {
return obj instanceof constructor;
}
var // block of private variables
// used to grab indeOf and toString
// should be trashed automatically
array = [],
// quirk implementation, enough here
indexOf = array.indexOf || function (value) {
var i = this.length;
while (i-- && this[i] !== value) {}
return i;
},
// minifiers shortcuts
proto = Object.prototype,
toString = proto.toString,
floor = Math.floor,
FALSE = false,
// make it compatible with different
// JS implementations, Rhino too
ARRAY = toString.call(array)
;
// do not redefine if present
"in" in proto || Object.defineProperty(proto, "in", {
// force defaults (just in case)
writable: FALSE,
enumerable: FALSE,
configurable: FALSE,
// the "in" method
value: function (obj) {
var
// reused later on
value, key,
// minifiers shortcut
self = this
;
// operation is both context
// and argument dependent
switch (typeof obj) {
// obj is Array or generic Object
case "object":
// "value".in(["some", "value"]); // true
if (toString.call(obj) === ARRAY) {
return -1 < indexOf.call(obj, toValue(self));
}
// "value".in({some: "value"}); // true
value = toValue(self);
for (key in obj) {
// inherited too as is for "in" operator
if (obj[key] === value) {
return true;
}
}
return FALSE;
//* hard to say if anything that's not object
// should accepted as "in" argument
// if you think so, comment out this part
// just removing first slash of this comment
case "string":
// "bc".in("abcd"); // true
if (isInstanceOf(self, String)) {
return -1 < obj.indexOf(self);
}
case "number":
// (3).in(15); // true as part of gcd
if (isInstanceOf(self, Number)) {
value = obj / self;
return floor(value) === value;
}
//*/
}
return FALSE;
}
});
}(Object, String));
/* da test, add a sash to perform the test => //* rather than /*
alert([
0 in [3,4,5], // true, index 0 exists
(4).in([3,4,5]), // true, array contains value 0
(3).in(15), // true, 15 can be divided by 3
3..in({three: 3}), // true, object has a property with value 3
"three" in {three: 3}, // true, three as property name
"bc".in("abcd"), // true, string "abcd" contains "bc"
"b".in(["a","b","c"]), // true, array contains value "b"
"b".in({a:"b"}), // true, object has no property with value "b"
(0).in([3,4,5]), // false, array does not contain value 0
(2).in({three: 3}), // false, object has no property with value 2
"three".in({three: 3}), // false, object has no property with value "three"
"b" in ["a","b","c"] // false, b is not a valid index
].join("\n"));
//*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment