javascript中的原型链

时间:2012-07-02 06:26:28

标签: javascript prototype

假设我有两个构造函数:

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

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

我希望Man从Person延伸。

以下是我的想法:

给定一个创建的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.

为什么它不起作用?

3 个答案:

答案 0 :(得分: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

额外的Ramblings

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的{​​{1}})。< / p>

请注意prototypeMan.prototype.prototype而且 - 这是重要的部分 - 也毫无意义。函数有原型。其他对象(例如undefined)则没有。 Man.prototype属性在任何其他上下文中都不是神奇的。为随机对象的prototype属性赋值不会做任何特殊操作。这只是另一个属性。

另请注意,我们从prototype返回的内容通过其inheritPerson相关联,并且无法访问添加到实例的任何属性 prototype

答案 1 :(得分:3)

我是怎么做的(就你的例子而言):

var Person = function () {
}

// Define "Person" methods

var Man = function () {
}

Man.prototype = new Person();

// Define "Man" methods

<强>更新

关于带参数的构造函数:刚刚发现这个SO问题可以真正帮助你搞清楚(第二个答案,第一部分):JavaScript inheritance: when constructor has arguments

答案 2 :(得分: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等语言中的经典继承。对象的prototype属性将用于构造函数的角色,新创建的对象将继承对象原型根中的所有属性。在这种情况下,对象的原型只有一种增强角色,有效的实现是在函数方法中完成的。

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();
};
相关问题