【问题标题】:JavaScript inheritance with Object.create()?使用 Object.create() 进行 JavaScript 继承?
【发布时间】:2023-03-20 03:55:01
【问题描述】:

如何使用 Object.create() 进行继承?我尝试了这些,但没有一个有效:

var B = function() {};
var A = function() {};
A = Object.create(B);
A.prototype.C = function() {};

var B = function() {};
var A = function() {};
A.prototype.C = function() {};
A = Object.create(B);

var B = function() {};
A = Object.create(B);
var A = function() {};
A.prototype.C = function() {};

没有任何效果。我应该如何使用这个新的 Object.create() 函数?

【问题讨论】:

标签: javascript object inheritance object-create


【解决方案1】:

在 JavaScript 中有几种实现继承的方法

构造继承。如果您不需要调用超类型构造函数时使用:

function Rectangle(length, width) { 
    this.length = length;
    this.width = width;
}

Rectangle.prototype.getArea = function() {
    return this.length * this.width;
};

// inherits from Rectangle
function Square(size) { 
    this.length = size;
    this.width = size;
}

Square.prototype = Object.create(Rectangle.prototype);

var rect = new Rectangle(6, 8);
var square = new Square(10);

console.log(rect.getArea());                // 48
console.log(square.getArea());              // 100
console.log(rect instanceof Rectangle);     // true
console.log(rect instanceof Object);        // true
console.log(square instanceof Square);      // true
console.log(square instanceof Rectangle);   // true
console.log(square instanceof Object);      // true

构造函数窃取。如果需要调用超类型构造函数时使用:

function Rectangle(length, width) { 
    this.length = length;
    this.width = width;
}

Rectangle.prototype.getArea = function() {
    return this.length * this.width;
};

// inherits from Rectangle
function Square(size) { 
    Rectangle.call(this, size, size);
}

Square.prototype = Object.create(Rectangle.prototype);

var rect = new Rectangle(6, 8);
var square = new Square(10);

console.log(rect.getArea());                // 48
console.log(square.getArea());              // 100
console.log(rect instanceof Rectangle);     // true
console.log(rect instanceof Object);        // true
console.log(square instanceof Square);      // true
console.log(square instanceof Rectangle);   // true
console.log(square instanceof Object);      // true

【讨论】:

  • 我看到 Square.prototype.constructor = Square;在某个地方,它不需要?
【解决方案2】:

Object.create() 用于继承对象,而不是像您尝试做的构造函数。它几乎创建了一个新对象,并将旧对象集作为其原型父对象。

var A = function() { };
A.prototype.x = 10;
A.prototype.say = function() { alert(this.x) };

var a = new A();
a.say(); //alerts 10

var b = Object.create(a);
b.say(); //alerts 10
b.x = 'hello';
b.say(); //alerts 'hello'

只是为了确保 b 不只是 a 的克隆,

a.x = 'goodbye';
delete b.x;
b.say(); //alerts 'goodbye'

【讨论】:

  • 该死,那不适合我的情况。我需要定义一个扩展另一个“类”的“类”。
  • 原型继承的要点是,“类”和“对象”之间没有严格的区别,因为类也是对象。
  • 我希望有Object.clone(obj) 会产生与JSON.parse(JSON.stringify(obj)) 相同的结果。
  • there will be,但我希望它被称为Object.clone()Object.assign() 我觉得很奇怪
  • 你将如何创建另一个继承自 a 的 b 类实例,并且:1. 不会更改 b 的先前实例 2. 将在新的 10 个实例中重用 b 的代码?
【解决方案3】:

我为此使用的模式是将每种类型包装在一个模块中,并公开createprototype 属性,如下所示:

var Vehicle = (function(){
        var exports = {};
        exports.prototype = {};
        exports.prototype.init = function() {
                this.mph = 5;
        };
        exports.prototype.go = function() {
                console.log("Going " + this.mph.toString() + " mph.");
        };

        exports.create = function() {
                var ret = Object.create(exports.prototype);
                ret.init();
                return ret;
        };

        return exports;
})();

然后我可以像这样构建派生类型:

var Car = (function () {
        var exports = {};
        exports.prototype = Object.create(Vehicle.prototype);
        exports.prototype.init = function() {
                Vehicle.prototype.init.apply(this, arguments);
                this.wheels = 4;
        };

        exports.create = function() {
                var ret = Object.create(exports.prototype);
                ret.init();
                return ret;
        };

        return exports; 

})();

使用这种模式,每种类型都有自己的create() 函数。

【讨论】:

  • 后续:这些天,如果我觉得需要制作类似类的东西,我会使用 Coffeescript,如果我不需要,我会使用匿名对象。
【解决方案4】:

Douglas 的 Object.create 的原始文档在这里 http://javascript.crockford.com/prototypal.html 。确保你已经包含了方法的定义

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

【讨论】:

【解决方案5】:

您可以自己定义 Object.create,但如果它不是本地的,您将不得不处理在您用于对象的每个 for in 循环中枚举它。

到目前为止,只有新的 webkits-Safari5 和 Chrome 原生支持它。

【讨论】:

  • Object.createObject 的属性,而不是Object.prototype 的属性,因此自己定义它不会将其添加到所有对象的枚举属性列表中。
【解决方案6】:

您可以在 Mozilla 开发中心找到有关 JavaScript inheritance 的有用信息。

【讨论】:

    【解决方案7】:

    好吧,这已经晚了几年,但对于其他偶然发现这一点的人来说。您可以在 FF 和 Chrome 中使用 Object.assign。

    在此示例中,当使用 create 创建 Cube 时。首先 Object.create(this) 使用 z 属性创建对象,然后使用 Object.assign(obj, Square.create(x,y)) 它将调用 Square.create 并返回并将其附加到存储在 obj 中的 Cube .

     var Square = {
            x: 0,
            y: 0,
    
            create: function(x,y) {
                var obj = Object.create(this);
                obj.x = x;
                obj.y = y;
                return obj;
            }
        };
    
     var Cube = {
    
            z: 0,
    
            create:function(x,y,z) {
                var obj = Object.create(this);
                Object.assign(obj, Square.create(x,y)); // assign(target,sources...)
                obj.z = z;
                return obj;
            }
        };
    
    // Your code
    var MyCube = Cube.create(20,30,40);
    console.log(MyCube);
    

    【讨论】:

      猜你喜欢
      • 2016-02-15
      • 2015-03-20
      • 2023-03-22
      • 2012-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多