Skip to content

Instantly share code, notes, and snippets.

@johnpryan
Last active August 9, 2016 21:13
Show Gist options
  • Save johnpryan/044c6479f058dfb1200d861b8aba3eb7 to your computer and use it in GitHub Desktop.
Save johnpryan/044c6479f058dfb1200d861b8aba3eb7 to your computer and use it in GitHub Desktop.
js interop enumerable properties
<!DOCTYPE html>
<html>
<head>
<title>js_interop_bug</title>
<link rel="stylesheet" href="styles.css">
<script src="index.js" type="text/javascript"></script>
<script defer src="main.dart" type="application/dart"></script>
<script defer src="packages/browser/dart.js"></script>
</head>
<body>
<div id="output"></div>
</body>
</html>
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties
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 = [];
do {
if (iterateSelfBool) {
Object.getOwnPropertyNames(obj).forEach(function (prop) {
if (props.indexOf(prop) === -1 && includePropCb(obj, prop)) {
props.push(prop);
}
});
}
if (!iteratePrototypeBool) {
break;
}
iterateSelfBool = true;
} while (obj = Object.getPrototypeOf(obj));
return props;
}
};
function printKeys(foo) {
var props = SimplePropertyRetriever.getPrototypeNonenumerables(foo);
for (var i = 0; i < props.length; i++) {
console.log("key: " + props[i]);
}
}
@JS()
library example;
import 'dart:html';
import 'package:js/js.dart';
external printKeys(Foo foo);
@anonymous
@JS()
class Foo {
set bar(String b);
external factory Foo();
}
void main() {
var foo = new Foo()
..bar = "hello world";
printKeys(foo);
}
key: constructor
key: toString
key: toLocaleString
key: valueOf
key: hasOwnProperty
key: isPrototypeOf
key: propertyIsEnumerable
key: __defineGetter__
key: __lookupGetter__
key: __defineSetter__
key: __lookupSetter__
key: __proto__
name: 'js_interop_bug'
version: 0.0.1
environment:
sdk: '>=1.0.0 <2.0.0'
dependencies:
browser: '>=0.10.0 <0.11.0'
js: '>=0.6.0 <0.7.0'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment