#79 灵魂交换


  • 0
    administrators

    有两个不同的人,他们有不同的灵魂(prototype)。

    class A {
      constructor (name) {
        this.name = name
      }
      sayHi () {
        return `I am ${this.name}.`
      }
    }
    
    class B {
      constructor (name) {
        this.name = name
      }
      sayHi () {
        return `This is ${this.name}.`
      }
    }
    
    
    const a = new A('Jerry') 
    const b = new B('Lucy')
    
    a.sayHi() // => 'I am Jerry.'
    b.sayHi() // => 'This is Lucy.'
    
    a instanceof B // => false
    b instanceof A // => false
    

    请你完成 exchange,传入两个对象,可以交换他们的灵魂:

    exchange(a, b)
    a.sayHi() // => 'This is Jerry.'
    b.sayHi() // => 'I am Lucy.'
    
    a instanceof B // => true
    b instanceof A // => true
    

    注意不要触碰到这两个对象原来的类,例如:

    exchange(a, b)
    a.sayHi() // => 'This is Jerry.'
    b.sayHi() // => 'I am Lucy.'
    
    const c = new A('Tomy')
    c.sayHi() // => 应该返回 'I am Tomy.'
    

    你也不能使用 __proto__ 属性。


  • 1

    const exchange = (a, b) => {
      const protos = [a, b].map(o => Object.getPrototypeOf(o)); //这里的分号是必要的
      [b, a].forEach((o, i) => Object.setPrototypeOf(o, protos[i]))
    }
    

    PS:
    @ScriptOJ 话说为啥这里用不了<!--注释语法(虽然非标准,但是看着像一个箭头,比//逼格高)。。。node/chrome都是支持的,但是评测系统会提示Unexpected token,但是放在eval里却又没事。。。。又是一个bug
    0_1497590970312_upload-57d7729f-7e3c-4bef-b5f5-efded51b1d5d


  • 0
    administrators

    @CodeHz 因为要支持 ES7, 所以先经过 babel。


  • 0

    通过了测试,不过感觉有点臃肿

    const exchange = (a, b) => {
      let ap = a.constructor.prototype
      Object.setPrototypeOf(a, b.constructor.prototype)
      Object.setPrototypeOf(b, ap)
    }
    

    表单验证工具 https://github.com/WLDragon/SMValidator


  • 0

    @WLDragon 既然有setPrototypeOf怎么就不想想getPrototypeOf呢,晕


登录后回复
 

与 ScriptOJ 的连接断开,我们正在尝试重连,请耐心等待