-
Notifications
You must be signed in to change notification settings - Fork 18
/
object.extensions.js
118 lines (110 loc) · 3.17 KB
/
object.extensions.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
* Object._isFunction(object) -> Boolean
* - object(Any): an object to test against
* Tests whether an object is a Function object.
*
* As per ECMA-262, ed3; 15.3.4.2: "The toString function is not generic;
* it throws a TypeError exception if its this value is not a Function object..."
*
*
**/
Object._isFunction = function(o) {
try {
Function.prototype.toString.call(o);
} catch(e) {
return false;
};
return true;
};
// Experimental
Object._isFunction2 = function(o) {
return Object.prototype.toString
.call(o).indexOf('Function') != -1;
}
/**
* Object.directProperties(object) -> Array
*
* Returns array of object's "direct" properties (i.e. those that are NOT resolved via object's prototype chain)
*
**/
Object.directProperties = function(o) {
var result = [], hop = Object.prototype.hasOwnProperty;
for (var prop in o) {
hop.call(o, prop) && result.push(prop);
}
return result;
};
/**
* Object.isEvent(object) -> Boolean
* - object(Any): Object to test
*
* Returns true if passed object "partially" conforms to a DOM2 Event interface
* The method uses somewhat naive duck-typing by verifying types of some of the properties as per:
*
* http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event
*
* Most of the time, though, we want to either stop event, invoke #element method or
* access some specific property (.target, .currentTarget, etc.)
* In those cases, it would make sense to test for those particular methods (before calling them)
*
* Maybe Object.isExtendedEvent is the way to go?
*
* function toggleAll(e) {
* if (Object.isEvent(e)) e.stop();
* // $$('div.toggleable').invoke('toggle');
* }
*
**/
Object.isEvent = function(object) {
return !!(object &&
object.target &&
Object.isNumber(object.target.nodeType) &&
Object.isString(object.type));
};
/**
* Object.isClass(object) -> Boolean
* - object(Any): Object to test
*
* Returns true if passed object was created via Class.create
* (it's somewhat naive in a way that it simply tests for prototype.initialize method on an object)
*
* Object.isClass(Hash); // true
* Object.isClass({}); // false
* Object.isClass(function(){}); // false
*
**/
Object.isClass = function(object) {
return Object.isFunction(object) &&
object.prototype &&
Object.isFunction(object.prototype.initialize);
};
/**
* Object.methodize(object) -> Object
*
* Returns a clone of a passed in object but with all functions methodized
*
*
*
// maybe try the "plain vanilla" way (?),
// since converting object to an array and then back to an object seems excessive
// eliminating #inject should make things faster as well
var methodized = { };
for (var prop in object) {
if (!object[prop].methodize) continue;
methodized[prop] = (function(prop){
return object[prop].methodize();
})(prop);
}
return methodized;
*/
Object.methodize = function(object) {
return Object.keys(object).inject({ }, function(m, name) {
m[name] = object[name].methodize();
return m;
});
};
Object.isNodeList = function(object) {
return !!object &&
typeof object.length != 'undefined' &&
typeof object.item != 'undefined'
}