JavaScript ES6 - 如何超级构造对象,就像它可以使用" new"?

时间:2016-09-13 22:43:59

标签: javascript ecmascript-6

class Foo extends Object {
    constructor(value) {
        super(value)
    }
}

a = new Object(10);
b = new Foo(10);

console.log(a.valueOf() === b.valueOf()) // false, why?

上次我检查过,创建了一个扩展另一个类的类,除了调用超级类之外什么都不做。在子类中使用this的构造函数'构造函数影响this的方式与使用new创建的超类实例受影响的方式相同。

那么为什么会出现这种不一致,是否有任何解决方法?

我尝试创建一个实例化的类,返回传递给其构造函数的第一个参数的任何值,但是已经分配了其他属性。

1 个答案:

答案 0 :(得分:0)

问题是Object仅在NewTarget未定义或不是Object构造函数本身时才强制对象。否则,它返回一个继承自NewTarget的.prototype

的普通对象
  

使用可选参数 value 调用Object函数时,   采取以下步骤:

     
      
  1. 如果NewTarget既不是未定义也不是活动函数,那么      
        
    1. 返回OrdinaryCreateFromConstructor(NewTarget,"%ObjectPrototype%")。
    2.   
  2.   
  3. 如果 value 为null,未定义或未提供,请返回ObjectCreate(%ObjectPrototype%)。
  4.   
  5. 返回ToObject)。
  6.   

在您的情况下,当您实例化Foo时,NewTarget将为Foo,因此this值将初始化为Object.create(Foo.prototype),而不是new Object(value)

所以你不能直接这样做。但是有手动方法:

function valueOf(value) {
  var result;
  [Boolean, Number, String, Symbol, Object].some(function(F) {
    try { result = F.prototype.valueOf.call(value); return true; }
    catch(err) { return false }
  });
  return result;
}
class Foo {
  constructor(value) {
    if(Object(value) === value) // Is an object
      return value; /* or maybe `return this`? */
    switch(typeof value) {
        case 'boolean': return Reflect.construct(Boolean, [value], Foo);
        case 'number': return Reflect.construct(Number, [value], Foo);
        case 'string': return Reflect.construct(String, [value], Foo);
        case 'symbol': return Reflect.construct(Symbol, [value], Foo);
    }
    // For undefined and null, let it return `this`
  }
}

console.log(valueOf(new Object(true)) === valueOf(new Foo(true)));
console.log(valueOf(new Object(10)) === valueOf(new Foo(10)));
console.log(valueOf(new Object("ab")) === valueOf(new Foo("ab")));

请注意,您需要自定义函数才能获得适当的值。这是因为,即使new Foo('10')返回一个数字对象,它也会继承自Foo.prototype,其原型链中不包含Number.prototype。但我想这是有意的,否则你可以直接return Object(value)