4

假设我有两个构造函数:

var Person = function(xx,xx,xxx,xxxxxxx) {
  //Person initialization
}

var Man = function(xx,xx,xxx,xxx) {
  //Man initialization
}

我希望人从人延伸。

以下是我的想法:

给定一个创建的 Man 对象:

var m=new Man("xx",....);

1) 当一个属性m被访问时,它会在Man.prototype.

2)如果没有找到,它应该找到它Man.prototype.__prop__

所以我要做的是使Man.prototype.__prop__链接到Person.prototype.

我知道这是常见的方式:

function inherit(superClass) {
    function F() {}
    F.prototype = superClass.prototype;
    return new F;
}
Man.prototype=inherit(Person);

但是当我尝试这个时:

Man.prototype.prototype=Person.prototype.

为什么它不起作用?

4

3 回答 3

6

听起来您实际上想要将Man的实例链接到保留其构造函数中添加的任何属性的实例Person,在这种情况下,您可能真的想要这样的东西:

function Person(a, b) {
    this.a = a;
    this.b = b;
}

function Man() {}
Man.prototype = new Person("val1", "val2");

var m = new Man();
console.log(m.a);

...打印val1.

额外的杂谈

的目的inherit是从一个函数创建一个对象,该函数prototype是给定超类的函数(没有显式使用new),这正是它所做的。因此,以下打印string

function Person() {}
Person.prototype.test = "string";

function Man() {}

function inherit(superClass) {
    function F() {}
    F.prototype = superClass.prototype;
    return new F;
}

var t = inherit(Person);
console.log(t.test);

但是您通常希望将返回的对象分配给另一个函数的原型:

Man.prototype = inherit(Person);

var m = new Man();
console.log(m.test);

...所以m.test也打印string,这意味着使用创建的对象Man链接到Person's prototype)。

请注意,这Man.prototype.prototypeundefined和——这是重要的部分——也没有意义。函数有原型。其他对象(例如Man.prototype)没有。该prototype属性在任何其他情况下都不是神奇的。为随机对象的属性赋值prototype并没有什么特别的作用。这只是另一个属性。

还要注意,我们返回的东西是通过它的方式inherit链接到的,并且无法访问添加.PersonprototypePerson

于 2012-07-02T07:20:28.323 回答
3

我是怎么做的(关于你的例子):

var Person = function () {
}

// Define "Person" methods

var Man = function () {
}

Man.prototype = new Person();

// Define "Man" methods

更新

关于带参数的构造函数:刚刚发现这个可以真正帮助您弄清楚的问题(第二个答案,第一部分):JavaScript 继承:当构造函数有参数时

于 2012-07-02T06:29:18.473 回答
0

有很多通用方法可以做到这一点。我将提供其中三个:

1.) 使用 Function 对象作为构造函数和继承的新对象的原型对象。实现应如下所示:

var person = {
    toString : function() {
        return this.firstName + ' ' + this.lastName;
    }
}


function extend(constructor, obj) {
    var newObj = Object.create(constructor);
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            newObj[prop] = obj[prop];
        }
    }
    return newObj;
}

var man = extend(person, 
    {
        sex: "male", 
        age: "22"
    });

var name = extend(man, 
    {
        firstName: "Simo",
        lastName: "Endre"
    });

name.man;
name.toString();

2.) 在这种情况下,我们将使用 Function 对象作为构造函数,以模拟 C# 或 Java 等语言中的经典继承。对象的原型属性将用作构造函数,新创建的对象将继承对象原型根的所有属性。在这种情况下,对象的原型只有一种增强作用,有效的实现是在函数方法中完成的。

var Person = function(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

Person.prototype.toString = function() {
    return this.firstName + ' ' + this.lastName;
}

function inherit(func) {
    // passing function arguments into an array except the first one which is the function object itself
    var args = Array.prototype.slice.call(arguments, 1);

    // invoke the constructor passing the new Object and the rest of the arguments
    var obj = Object.create(func.prototype);
    func.apply(obj, args);        

    //return the new object
    return obj;   
}

var man = inherit(Person, "Simo", "Endre");
man.toString();

3.) 众所周知的继承模型:

function extend(o) {
  function F() {}

  // We'll set the newly created function prototype property to the object. 
  //This act as a constructor.
  F.prototype = o;

  // Using the `new` operator we'll get a new object whose prototype is o.
  return new F();
};
于 2012-07-02T11:18:12.297 回答