javascript - 在 Javascript 中扩展对象

标签 javascript oop

我有点迷失在让对象扩展到工作中。我已经阅读了数十个与此主题相关的网站,但我仍然不明智。似乎每个人都使用自己的方法来完成这项工作,我也是,我正在努力寻找扩展/继承对象的最佳方法。

我也知道有大量的框架/插件可以涵盖此功能,但我只想了解它的总体工作原理。更不用说这些框架中的大多数都包含许多我可能永远不会使用的其他东西,因此我正在尝试自己制作。

我能够扩展一个对象,一切似乎都正常,直到我开始向目标对象添加方法。要了解该问题,请参阅以下示例...

或者试试这个 JSFiddle

问题是,在初始化Rabbit 对象的新实例后,我无法访问Rabbit 的 方法changeName。 而且我不明白为什么会这样,即为什么它不识别该方法。

[*] 请查看下面我更新的代码(还有 JFiddle),现在一切似乎都正常。

如果这是一个好方法或者我缺少什么,请问 anoyne 能否提供建议?

var Class = (function(NewClass){
    if(NewClass.length != 0){
        var extend = function(target, source, args) {
            Object.getOwnPropertyNames(source).forEach(function(propName) {
                if(propName !== "Extend")
                {
                    Object.defineProperty(
                        target, propName,
                        Object.getOwnPropertyDescriptor(source, propName)
                    );
                }
                if (typeof source[propName] !== 'undefined'){
                    delete source[propName];
                }
            });

            return target;
        };
        var inherit = function(source, args){
            var baseClass = Object.getPrototypeOf(this); 
            baseClass.prototype = extend.call(this, baseClass, source, args);
        };
        if(NewClass.Extend){
            var Class = function(){ //// New Class Constructor ////
                if(typeof NewClass.Extend === 'function'){
                    NewClass.Extend.apply(this, arguments);
                    inherit.call(this, NewClass.Extend);
                    console.log(NewClass)
                    inherit.call(this, NewClass, arguments);
                    if(NewClass.Initialize){
                        NewClass.Initialize.call(this, arguments);
                    }
                }
            };
            Class.prototype.constructor = Class;
            return Class; 
        }
    }
});

var Animal =(function(args){//// constructor ////
    var self = this;
    self.name = typeof args !== 'undefined' ? args.name : null;
    self.bags = 0;
});

var Rabbit = new Class({
    Extend: Animal ,
    Initialize: function(){
        console.log(this.name)
    },
    changeName: function(a){

        console.log(this.name)
    }
});


var LittleRabbit = new Rabbit({name: "LittleRabbit", type: "None"});
console.log(LittleRabbit instanceof Rabbit)
console.log(LittleRabbit)
LittleRabbit.changeName("alex");

最佳答案

您的extend 函数工作错误,因为Object.getPrototypeOf返回原型(prototype),所以在更多情况下它是对象

var extend = function(source, args){
    var baseClass = Object.getPrototypeOf(this); 
    source.apply(this, args);

    //so here you just add property prototype to object, and this not same as set prototype to function.
    baseClass.prototype = Object.create(source.prototype);
};

所以你可以像下面的代码片段一样解决这个问题:

function Class(args) {
  if (arguments.length != 0) {
    var C = function() {
      if (typeof args.Extend == 'function') {
        args.Extend.apply(this, arguments)
      }
      if (args.Initialize) {
        args.Initialize.call(this);
      }
    };
    if (typeof args.Extend == 'function') {
      C.prototype = Object.create(args.Extend.prototype);
    }

    Object.keys(args).filter(function(el) {
      return ['Extend', 'Initialize'].indexOf(el) == -1
    }).forEach(function(el) {
      C.prototype[el] = args[el];
    });

    return C;
  }
};

var Animal = (function(args) { //// constructor ////
  var self = this;
  self.name = typeof args !== 'undefined' ? args.name : null;
  self.bags = 0;
});

var Rabbit = Class({
  Extend: Animal,
  Initialize: function() {
    console.log(this.name);
  },
  changeName: function(a) {
    this.name = a;
  }
});


var LittleRabbit = new Rabbit({
  name: "LittleRabbit",
  type: "None"
});
console.log(LittleRabbit instanceof Rabbit);
console.log(LittleRabbit instanceof Animal);
console.log(LittleRabbit.name);
LittleRabbit.changeName('new little rabbit');
console.log(LittleRabbit.name);

关于javascript - 在 Javascript 中扩展对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32763375/

相关文章:

c++ - 使用 Clion 的 C++ 简单程序 "expected ` ,' or ` .. .' before ' & &' token"

php - 如何使用来自其他 namespace 的对象以及如何在 PHP 中导入 namespace

javascript - 需要对 nodejs 概念进行一些澄清

javascript - jquery 复选框,如何获取所有选中的复选框并将它们添加到数组?

javascript - JavaScript中如何处理 float 精度?

javascript - 如何在构造函数中设置javascript私有(private)变量?

javascript - MongoDB 不是 okForStorage 错误

javascript - 删除字符串中重复的连续单词的最快算法?

c++ - 在 C++ 中管理成员函数执行

c# - 我应该在哪里放置功能以在类型之间进行转换?