【问题标题】:Multi Level Inheritance in JavascriptJavascript中的多级继承
【发布时间】:2014-06-04 19:42:27
【问题描述】:

我正在尝试使用原型在 Javascript 中模拟继承。

我有一个名为 Model 的函数和一个模型类型 => Item。

var Model = function() { 
   this.names = ["name1", "name2"]; 
} 
Model.prototype.Item = function(args) { 
   this.init = function(item_name) { 
      this.names[0] = item_name; // ERROR: Cannot set property '0' of undefined
   } 
}
var m = new Model();
var i = new m.Item();
i.init("New Name"); // ERROR: Cannot set property '0' of undefined

如何从上面的init() 函数访问names 数组?

【问题讨论】:

  • 这条线应该是失败的var i = new Model.Item();。你是说(new Model).Item() 还是new Model().Item()
  • 抱歉,复制和粘贴问题。是m.Item()
  • 在 Item 构造函数中放置一个Console.log(this)。您会看到 this 指的是调用 new m.Item() 时创建的新对象,而不是调用 new Model() 时创建的对象。您已将 Item 实现为一个单独的类,该类恰好是 Model 原型对象的一个​​属性,而不是继承的类。子类无权访问其父类中的属性。
  • 你想要什么继承?你想让 Model 从 Item 继承吗?
  • ...您不需要在 JavaScript 中“模拟”继承。您只需要了解惯用的 JavaScript 继承是如何工作的。

标签: javascript inheritance multi-level


【解决方案1】:

Javascript 中的继承很棘手!阅读这篇文章,了解 Javascript 中传统的面向对象继承:http://blog.slaks.net/2013-09-03/traditional-inheritance-in-javascript/

var Model = function () {
    this.names = ["name1", "name2"];
};

var Item = function () {
    //When inheriting in Javascript you must 
    //call the inherited function's constructor manually.
    Model.call(this);
};

//Inherit Model's prototype so you get all of Model's methods.
Item.prototype = Object.create(Model.prototype);
Item.prototype.constructor = Item;

Item.prototype.init = function (item_name) {
    this.names[0] = item_name;
};

var Employee = function () {
    Model.call(this);
};

Employee.prototype = Object.create(Model.prototype);
Employee.prototype.constructor = Employee;

var myItem = new Item();
myItem.init("New Name");
//prints New Name, name2
console.log(myItem.names);


var myEmployee = new Employee();
//prints name1, name2
console.log(myEmployee.names);

更传统的面向对象语言 (C#) 中的类似代码:

public class Model
{
    public Model()
    {
        this.Names = new[] {"name1", "name2"};
    }
    public string[] Names { get; set; }
}

public class Item : Model
{
    public Item() : base() { }

    public void init(string item_name)
    {
        this.Names[0] = item_name;
    }
}

public class Employee : Model
{
    public Employee() : base() { }
}

var myItem = new Item();
myItem.init("New Name");
//prints New Name, name2
Console.WriteLine(String.Join(",", myItem.Names));

var myEmployee = new Employee();
//prints name1, name2
Console.WriteLine(String.Join(",", myEmployee.Names));

【讨论】:

  • 太棒了!非常感谢:)
  • @StevenWexler 如果将原始问题中的var m = new Model(); 放在Model.prototype.Item =.. 之前,然后将this.names[0] 替换为m.names[0],那会不会很愚蠢?我试图了解正确的做法
  • 你是对的。您应该在使用之前定义模型的工作方式。
  • @StevenWexler 所以如果这样做,它不会仍然是一个糟糕的 OOP 实践吗?
  • 如果你想遵循良好的 OOP 实践,你应该做你声称是“愚蠢”的事情。
【解决方案2】:

您遇到的问题是,在第二项Item 中,您对this 的引用不知道它是“父”对象Model

重写这个的一种方法是这样的:

var Model = function() { 
   this.names = ["name1", "name2"]; 
}

Model.prototype.init = function(item_name) {
    this.names[0] = item_name;
}
var Item = new Model();
Item.init("New Name");

console.log(i);

在这里提琴:http://jsfiddle.net/BksS3/1/

【讨论】:

    【解决方案3】:

    就使这项工作而言,这也可以。

    var Model = function() { 
       this.names = ["name1", "name2"]; 
    } 
    Model.prototype.Item = function(args) { 
       this.init = function(item_name) { 
          this.names[0] = item_name;
       } 
    }
    var m = new Model();
    var i = new m.Item();
    i.init.apply(m,["New Name"]); 
    

    【讨论】:

      【解决方案4】:

      Manager 类对象将访问来自 Person 和 Employee 的所有方法。 多级继承示例

            function Person(firstName,lastName,marks,age,gender) 
           {
            this.firstName = firstName;
            this.lastName = lastName;
            this.age=age;
            this.gender=gender;
           }
      
            Person.prototype.getFullname = function()
             {
               console.log("Full Name is "+this.firstName +' '+this.lastName);
             }
      
       function Employee(firstName,lastName, marks, rollno, salary) 
       {
      
           Person.call(this,firstName,lastName,marks, rollno, salary);
           this.rollno = rollno;
           this.salary=salary;
      
      
        }
      
        function Manager(firstName,lastName, marks, rollno, salary, code) {
      
            Employee.call(this, firstName,lastName,marks, rollno, salary, code);
      
            this.code = code;
        }
      
      
      
      Employee.prototype = Object.create(Person.prototype);
      Employee.prototype.constructor = Employee;
      
      Employee.prototype.getSalary = function()
             {
               console.log(`Salary of ${this.firstName} ${this.lastName} is ${this.salary}`);
             }
      
      
      Manager.prototype = Object.create(Employee.prototype);
      Manager.prototype.constructor = Manager;
      Manager.prototype.designation = function() {
            console.log("You'r designation is Manager");
        }
      var m = new Manager("shankar","singh", 21,100, 40000,"CS12");
      
       console.log(m);
         m.getFullname();
         m.getSalary();
          m.designation();
      
      
      </script>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-02
        • 2014-06-02
        • 2019-03-10
        • 1970-01-01
        相关资源
        最近更新 更多