/*=== basic object string boolean true number object string boolean true number object string boolean false string object string boolean false undefined ===*/ print('basic'); function basicTest() { var proto = { proto: 'prototype' }; var obj; function test(o, n) { var t = o.hasOwnProperty(n); print(typeof o, typeof n, typeof t, t, typeof o[n]); } obj = Object.create(proto); obj.foo = 1; obj.bar = 2; // own property test(obj, 'foo'); test(obj, 'bar'); // ancestor property (not found) test(obj, 'proto'); // non-existent property test(obj, 'non-existent'); } try { basicTest(); } catch (e) { print(e); } /*=== coercion toString() name TypeError toString() name TypeError toString() name boolean boolean false toString() name boolean boolean false toString() name number boolean false toString() name object boolean false toString() name object boolean false toString() name object boolean false ===*/ print('coercion'); function coercionTest() { var objThis, objProp; function test(this_value, prop_name) { try { t = Object.prototype.hasOwnProperty.call(this_value, prop_name); print(typeof this_value, typeof t, t); } catch (e) { print(e.name); } } objThis = { toString: function () { print('toString() this'); return 'tostring-this'; }, valueOf: function () { print('valueOf() this'); return 'valueof-this'; } }; objProp = { toString: function () { print('toString() name'); return 'tostring-name'; }, valueOf: function () { print('valueOf() name'); return 'valueof-name'; } }; // ToObject(this) will throw a TypeError for undefined and null, but this // only happens after ToString() is called for property name (V8 does not // seem to do this) test(undefined, objProp); test(null, objProp); test(true, objProp); test(false, objProp); test(123, objProp); test([1,2], objProp); test({ foo: 1, bar: 2 }, objProp); // First argument is already an object so it won't get coerced; second // argument gets coerced to a string test(objThis, objProp); } try { coercionTest(); } catch (e) { print(e); }