Наследование JavaScript с помощью Object.create()?

Как мне наследовать с помощью 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()?


person Tower    schedule 20.06.2010    source источник
comment
возможный дубликат использование Object.create вместо нового   -  person Bergi    schedule 31.01.2013


Ответы (7)


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'
person Chetan S    schedule 20.06.2010
comment
Блин, тогда это не подходит для моей ситуации. Мне нужно определить класс, который расширяет другой класс. - person Tower; 20.06.2010
comment
Смысл прототипного наследования в том, что у вас нет жесткого различия между классом и объектом, поскольку класс тоже является объектом. - person Kos; 09.12.2011
comment
Я бы хотел, чтобы Object.clone(obj) давал тот же результат, что и JSON.parse(JSON.stringify(obj)). - person trusktr; 06.04.2014
comment
будет, но я хотелось бы, чтобы он назывался Object.clone(). Object.assign() мне кажется странным - person code_monk; 04.12.2014
comment
Как вы создадите другой экземпляр класса b, унаследованный от a, и: 1. не измените предыдущий экземпляр b 2. будете повторно использовать этот код b в новых 10 экземплярах? - person Artem G; 25.06.2015

Существует несколько способов наследования в 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
person Vlad Bezden    schedule 02.01.2014
comment
Я вижу Square.prototype.constructor = Square; в где-то, это не нужно? - person c0ming; 10.05.2017

Шаблон, который я использую для этого, заключается в том, чтобы обернуть каждый тип в модуль и предоставить свойства create и prototype, например:

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().

person Sean McMillan    schedule 05.04.2011
comment
Дополнение: в настоящее время я использую Coffeescript, если чувствую необходимость создавать вещи, подобные классу, или анонимный объект, если я этого не делаю. - person Sean McMillan; 07.01.2015


Вы можете определить Object.create самостоятельно, но если он не является родным, вам придется иметь дело с его перечислением в каждом цикле for in, который вы используете для объектов.

Пока только новые веб-киты — Safari5 и Chrome изначально поддерживают его.

person kennebec    schedule 20.06.2010
comment
Object.create является свойством Object, а не Object.prototype, поэтому его самостоятельное определение не добавит его в список перечисляемых свойств для всех объектов. - person kpozin; 13.03.2012

Вы можете найти полезную информацию о наследовании JavaScript в Центре разработки Mozilla.

person el.pescado    schedule 20.06.2010

Ну, это годы с опозданием, но для всех, кто наткнулся на это. Вы можете использовать Object.assign в FF и Chrome.

В этом примере, когда куб создается с помощью create. Сначала Object.create(this) создает объект со свойством z, затем с помощью Object.assign(obj, Square.create(x,y)) он вызовет Square.create и вернет и добавит его в Cube, хранящийся в obj .

 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);
person Aven Cherus    schedule 07.02.2016