开发者问题收集

原型链继承

2017-03-26
199

我正在研究原型链的底层原理,但在构建函数时遇到了一些困难。我想构建一个函数,该函数将接收一个对象并添加到该对象的原型中。我做错了什么?

function getObject(obj) {
  function F() {}
  F.prototype.say = function(){
    console.log("Hello", this.name);
  }.bind(obj);

  obj.prototype = Object.create(F.prototype);
  return obj;
}

var r = getObject({ name: "James"});

r.name
r.say()

// r = { name: "James" } 
// r.say() "Hello James"

我得到了我想要的东西。我受到限制,不允许使用 ES6 类...我知道对吧?

function getObject(obj) {
  function F() { }
  F.prototype.say = function(){
    console.log("Hello", this.name);
  };
  const output = Object.create(F.prototype);
  return Object.assign(output, obj);
}

var r = getObject({ name: "James"});
r // { name: "James" }
r.name  // "James"
r.say() // "Hello James"
3个回答

我修改了代码。对象没有原型。函数有原型,可用于链接。希望这有帮助。

function getObject(obj) {
    function F() {}
    F.prototype = Object.create(obj);

    F.prototype.say = function(){
        console.log("Hello", this.name);
    }.bind(obj);

    return new F();
}

var r = getObject({ name: "James"});

console.log(r.name); // James
r.say() // Hello James
Basavaraj Sonnad
2017-03-27

您可以向对象添加方法,例如 obj.something = function() {};

至于方法链,您需要在继承的函数中返回 this

因此,类似这样的方法可以解决您的问题

function getObject(obj) {
    obj.say = function() {
        console.log(`Hello ${this.name}`);
        return this;
    }
    obj.hi = function() {
        console.log('hi');
        return this;
    }
    return obj;
}

var newObj = getObject({});

newObj.say().hi();
// Helo A K
// hi

此外,您还将 obj.prototypes 指定为等于类,而不是类原型。因此,如果您将来想使一个原型等于类原型,请使用 obj.prototype = Object.create(anothingObj.prototype);

Luis Estevez
2017-03-26

您正在明确地在对象上添加原型属性。 obj.prototype = undefined ,当您使用 new 关键字调用它时,它只会向该属性添加一个空对象。所以新的 obj 将是 obj = {name:'james' ,prototype:{}> 。现在,对象的原型属性将指向函数 F 的原型。正确的方法是通过 Object.create。您可以像这样模仿相同的行为

 if(!Object.create){ 
 Object.create = function(o) { 
 function F() {} 
 F.prototype = o ;
  return new F(); 
 }; 
}

您可以查看 MDN Docs 以获取有关 Object.create polyfill 的详细说明

Mohit Garg
2017-03-26