domenic at domenicdenicola.com (2013-12-10T01:34:28.757Z)
On 12/3/2013 11:29 AM, Allen Wirfs-Brock wrote:
> I don't have the time right now, but as a rough approximation take the
> most recent specification of [MixinProperties](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-mixinproperties) (which is the guts of
> Object.mixin)
> rewrite in in JS. Replace each call of RebindSuper(x,y) with
> x.toMethod(y). Replace each call of SameValue(GetSuperBinding(x),
> source) with (typeof x === "function"),
This should be pretty close
```js
function Assert(test) {
if (!test) {
throw new Error("Assertion failure");
}
}
function Type(value) {
switch (typeof value) {
case "string":
return "String";
case "number":
return "Number";
case "boolean":
return "Boolean";
case "symbol";
return "Symbol";
case "undefined";
return "Undefined";
case "object":
if (value === null) {
return "Null";
}
case "function":
return "Object";
}
}
// 6.2.4.2 IsDataDescriptor
function IsDataDescriptor(Desc) {
// step 1
if (Desc === undefined) {
return false;
}
// step 2
if (!("value" in desc || "writable" in desc)) {
return false;
}
// step 3
return true;
}
// 7.4.2 IteratorNext
function IteratorNext(iterator, value) {
// Step 2-3
const result = iterator.next(value);
// Step 4
if (Type(result) !== "Object") {
throw new TypeError();
}
// Step 5
return result;
}
// 7.4.3 IteratorComplete
function IteratorComplete(iterResult) {
// Step 1
Assert(Type(iterResult) === "Object");
// Step 2
const { done } = iterResult;
// Step 3
return !!done;
}
// 7.4.5 IteratorStep
function IteratorStep(iterator, value) {
// Step 2-3
const result = IteratorNext(iterator, value);
// Step 4-5
const done = IteratorComplete(result);
// Step 6
if (done) {
return false;
}
//Step 7
return result;
}
// 19.1.2.15 Object.mixin
function mixin(target, source) {
// step 1-2
const to = ToObject(target);
// step 3-4
const from = ToObject(source);
// step 5
return MixinProperties(to, from);
}
// 19.1.2.15.1 MixinProperties
function MixinProperties(target, source) {
// step 1
Assert(Type(target) === "Object");
// step 2
Assert(Type(source) === "Object");
// step 3 - 4
const keys = Object.getOwnPropertyKeys(source).values();
// step 5
let gotAllNames = false;
// step 6
let pendingException = undefined;
// step 7
while (gotAllNames === false) {
// step 7.a - 7.b
const next = IteratorStep(keys);
// step 7.c
if (next === false) {
gotAllNames = true;
// step 7.d
} else {
// step 7.d.i - 7.d.ii
const nextKey = IteratorValue(next);
// step 7.d.iv
const desc = Object.getOwnPropertyDescriptor(source, nextKey);
// step 7.d.v
if (desc !== undefined) {
// step 7.d.v.1
if (IsDataDescriptor(desc)) {
// step 7.d.v.1.a
const propValue = desc.value;
// step 7.d.v.1.b
if (typeof propValue === "function") {
try {
// step 7.d.v.1.b.i
const newFunc =
MixinProperties(propValue.toMethod(target), propValue);
// step 7.d.v.1.b.iii
desc.value = newFunc;
} catch (e) {
// step 7.d.v.1.b.ii
if (pendingException === undefined) {
pendingException = e;
}
}
}
} else {
// step 7.d.v.2.a
const getter = desc.get;
// step 7.d.v.2.b
if (typeof getter === "function") {
try {
// step 7.d.v.2.b.i
const newFunc = MixinProperties(getter.toMethod(target),
getter);
// step 7.d.v.2.b.iii
desc.get = newFunc;
} catch (e) {
// step 7.d.v.2.b.ii
if (pendingException === undefined) {
pendingException = e;
}
}
}
// step 7.d.v.2.c
const setter = desc.set;
// step 7.d.v.2.d
if (typeof setter === "function") {
try {
// step 7.d.v.2.d.i
const newFunc = MixinProperties(setter.toMethod(target),
setter);
// step 7.d.v.2.d.iii
desc.set = newFunc;
} catch (e) {
// step 7.d.v.2.d.ii
if (pendingException === undefined) {
pendingException = e;
}
}
}
}
}
try {
// step 7.d.v.3
Object.defineProperty(target, nextKey, desc);
} catch (e) {
// step 7.d.v.4
if (pendingException === undefined) {
pendingException = e;
}
}
}
}
// step 8
if (pendingException !== undefined) {
throw pendingException;
}
// step 9
return target;
}
```
On 12/3/2013 11:29 AM, Allen Wirfs-Brock wrote: > I don't have the time right now, but as a rough approximation take the > most recent specification of MixinProperties (which is the guts of > Object.mixin) > http://people.mozilla.org/~jorendorff/es6-draft.html#sec-mixinproperties > <http://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-mixinproperties> and > rewrite in in JS. Replace each call of RebindSuper(x,y) with > x.toMethod(y). Replace each call of SameValue(GetSuperBinding(x), > source) with (typeof x === "function"), This should be pretty close ```js function Assert(test) { if (!test) { throw new Error("Assertion failure"); } } function Type(value) { switch (typeof value) { case "string": return "String"; case "number": return "Number"; case "boolean": return "Boolean"; case "symbol"; return "Symbol"; case "undefined"; return "Undefined"; case "object": if (value === null) { return "Null"; } case "function": return "Object"; } } // 6.2.4.2 IsDataDescriptor function IsDataDescriptor(Desc) { // step 1 if (Desc === undefined) { return false; } // step 2 if (!("value" in desc || "writable" in desc)) { return false; } // step 3 return true; } // 7.4.2 IteratorNext function IteratorNext(iterator, value) { // Step 2-3 const result = iterator.next(value); // Step 4 if (Type(result) !== "Object") { throw new TypeError(); } // Step 5 return result; } // 7.4.3 IteratorComplete function IteratorComplete(iterResult) { // Step 1 Assert(Type(iterResult) === "Object"); // Step 2 const { done } = iterResult; // Step 3 return !!done; } // 7.4.5 IteratorStep function IteratorStep(iterator, value) { // Step 2-3 const result = IteratorNext(iterator, value); // Step 4-5 const done = IteratorComplete(result); // Step 6 if (done) { return false; } //Step 7 return result; } // 19.1.2.15 Object.mixin function mixin(target, source) { // step 1-2 const to = ToObject(target); // step 3-4 const from = ToObject(source); // step 5 return MixinProperties(to, from); } // 19.1.2.15.1 MixinProperties function MixinProperties(target, source) { // step 1 Assert(Type(target) === "Object"); // step 2 Assert(Type(source) === "Object"); // step 3 - 4 const keys = Object.getOwnPropertyKeys(source).values(); // step 5 let gotAllNames = false; // step 6 let pendingException = undefined; // step 7 while (gotAllNames === false) { // step 7.a - 7.b const next = IteratorStep(keys); // step 7.c if (next === false) { gotAllNames = true; // step 7.d } else { // step 7.d.i - 7.d.ii const nextKey = IteratorValue(next); // step 7.d.iv const desc = Object.getOwnPropertyDescriptor(source, nextKey); // step 7.d.v if (desc !== undefined) { // step 7.d.v.1 if (IsDataDescriptor(desc)) { // step 7.d.v.1.a const propValue = desc.value; // step 7.d.v.1.b if (typeof propValue === "function") { try { // step 7.d.v.1.b.i const newFunc = MixinProperties(propValue.toMethod(target), propValue); // step 7.d.v.1.b.iii desc.value = newFunc; } catch (e) { // step 7.d.v.1.b.ii if (pendingException === undefined) { pendingException = e; } } } } else { // step 7.d.v.2.a const getter = desc.get; // step 7.d.v.2.b if (typeof getter === "function") { try { // step 7.d.v.2.b.i const newFunc = MixinProperties(getter.toMethod(target), getter); // step 7.d.v.2.b.iii desc.get = newFunc; } catch (e) { // step 7.d.v.2.b.ii if (pendingException === undefined) { pendingException = e; } } } // step 7.d.v.2.c const setter = desc.set; // step 7.d.v.2.d if (typeof setter === "function") { try { // step 7.d.v.2.d.i const newFunc = MixinProperties(setter.toMethod(target), setter); // step 7.d.v.2.d.iii desc.set = newFunc; } catch (e) { // step 7.d.v.2.d.ii if (pendingException === undefined) { pendingException = e; } } } } } try { // step 7.d.v.3 Object.defineProperty(target, nextKey, desc); } catch (e) { // step 7.d.v.4 if (pendingException === undefined) { pendingException = e; } } } } // step 8 if (pendingException !== undefined) { throw pendingException; } // step 9 return target; } ```