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;
}
```
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to