jeresig (owner)

Forks

Revisions

gist: 153271 Download_button fork
public
Description:
Determining if an object comes from an object literal appears to be tricky - especially if you don't serialize functions and work across windows. Edit isObjectLiteral to come up with a potential solution - and make sure that it works in all browsers.
Public Clone URL: git://gist.github.com/153271.git
Embed All Files: show embed
isObjectLiteral.html #
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
<!DOCTYPE html>
<html>
<head>
        <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
        <!-- Online here: http://ejohn.org/files/bugs/isObjectLiteral/ -->
        <title>isObjectLiteral</title>
        <style>
        li { background: green; } li.FAIL { background: red; }
        iframe { display: none; }
        </style>
</head>
<body>
<ul id="results"></ul>
<script>
 
function isObjectLiteral(obj){
        // Implement me!
        return false;
 
        // Other Solutions:
 
        // Uses function serialization which doesn't work in all browsers
        //return /^function Object/.test( obj.constructor );
 
        // Doesn't work with object from other windows
        //return Object.prototype.toString.call(obj) === "[object Object]";
}
 
// Function serialization is not permitted
// Does not work across all browsers
Function.prototype.toString = function(){};
 
// The use case that we want to match
log("{}", {}, true);
 
// Instantiated objects shouldn't be matched
log("new Date", new Date, false);
 
var fn = function(){};
 
// Makes the function a little more realistic
// (and harder to detect, incidentally)
fn.prototype = {someMethod: function(){}};
 
// Functions shouldn't be matched
log("fn", fn, false);
 
// Again, instantiated objects shouldn't be matched
log("new fn", new fn, false);
 
/* Note:
* The restriction against instantiated functions is
* due to the fact that this method will be used for
* deep-cloning an object. Instantiated objects will
* just have their reference copied over, whereas
* plain objects will need to be completely cloned.
*/
 
var iframe = document.createElement("iframe");
document.body.appendChild(iframe);
 
var doc = iframe.contentDocument || iframe.contentWindow.document;
doc.open();
doc.write("<body onload='window.top.iframeDone(Object);'>");
doc.close();
 
function iframeDone(otherObject){
        // Objects from other windows should be matched
        log("new otherObject", new otherObject, true);
}
 
function log(msg, a, b) {
  var pass = isObjectLiteral(a) === b ? "PASS" : "FAIL";
 
  document.getElementById("results").innerHTML +=
        "<li class='" + pass + "'>" + msg + "</li>";
}
</script>
</body>
</html>