Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Что такого делает Object.create? (https://javascript.ru/forum/misc/55821-chto-takogo-delaet-object-create.html)

sexbot 15.05.2015 19:54

Что такого делает Object.create?
 
function Animal(name, sound) {
  this.name = name;
  this.sound = sound;
}

Animal.prototype.say = function() {
  console.log('%s says %s', this.name, this.sound);
};

function Cat() {
  Animal.call(this, "cat", "meow");
}

Cat.prototype = new Animal();
// Cat.prototype = Animal.prototype;
// Cat.prototype = Object.create(Animal.prototype);

var cat = new Cat();
cat.say(); // cat says meow

console.log(cat instanceof Cat); // true
console.log(cat instanceof Animal); // true
console.log(cat.constructor.name); // "Animal"?!


function inherit(Child, Parent) {
  Child.prototype = Object.create(Parent.prototype);
  Child.prototype.constructor = Child;
  Child.prototype.super = function() {
    Parent.apply(this, arguments);
  };
}

function Dog() {
  this.super("dog", "woof");
}

inherit(Dog, Animal);

var dog = new Dog;
dog.say();
console.log(dog.constructor.name);


Это код просто для примера. Мне непонятно почему при наследовании предпочтительнее делать `Child.prototype = Object.create(Parent.prototype)` вместо простого `Child.prototype = new Parent()`?

Decode 15.05.2015 20:59

Цитата:

Сообщение от sexbot (Сообщение 371033)
Это код просто для примера. Мне непонятно почему при наследовании предпочтительнее делать `Child.prototype = Object.create(Parent.prototype)` вместо простого `Child.prototype = new Parent()`?

new Parent() - это создание нового объекта
Child.prototype = Object.create(Parent.prototype) - наследование методов

https://learn.javascript.ru/class-inheritance

sexbot 15.05.2015 21:12

function inherit(Child, Parent) {
  Child.prototype = Object.create(Parent.prototype);
  Child.prototype.constructor = Child;
  Child.prototype.parent = Parent;
}

// `super` is reserved word
function sup(obj, method) {
  var args = Array.prototype.slice.call(arguments, 2)
  return obj.parent.prototype[method].apply(obj, args);
}

function Animal(name, sound) {
  this.name = name;
  this.sound = sound;
}

Animal.prototype.say = function() {
  console.log('%s says %s', this.name, this.sound);
};

function Cat() {
  this.counter = 0;
  this.parent.call(this, "cat", "meow");
}

inherit(Cat, Animal);

Cat.prototype.say = function(){
  sup(this, "say");
  console.log("method called %s times", ++this.counter);
};

var cat = new Cat();
cat.say();
cat.say();
cat.say();


Я еще магии немного принес, только вот что-то мне не нравится моя функция `sup`

sexbot 15.05.2015 21:19

Профиксил:

function sup(o, meth) {
  var args = Array.prototype.slice.call(arguments, 2);
  var proto = Object.getPrototypeOf(Object.getPrototypeOf(o));
  return proto[meth].apply(o, args);
}

devote 15.05.2015 21:29

new Parent() - создание экземпляра с выполнением конструктора Parent
Object.create(Parent.prototype) - создание экземпляра без выполнения конструктора Parent


function Ololo() {}
Ololo.prototype = Parent.prototype;
new Ololo() - тоже что делает Object.create

nerv_ 15.05.2015 21:39

забудьте уже эти велосипеды и просто используйте es6
http://babeljs.io/docs/learn-es6/#classes

fuckJS 15.05.2015 21:44

Ваш код функционально примерно эквивалентен этому:
Animal={
 clone: function(name, sound){
  var o=Object.create(this)
  o.name=name; o.sound=sound
  return o
},
 say: function(){console.log(this.name+" says "+this.sound)}
}

Cat=Animal.clone("cat", "meow")
Dog=Animal.clone("dog", "woof")

Cat.say() //>>>> cat says meow
Dog.say() //>>>> dog says woof

Отсюда должно быть понятно, что он делает. Он создает новый объект, и ставит ему в прототип аргумент.

fuckJS 15.05.2015 21:50

Цитата:

Сообщение от devote
тоже что делает Object.create

строго говоря, не то же самое. Он помимо этого вешает кучу соплей а-ля Java

sexbot 15.05.2015 23:00

А насчет такой функции что скажите?

function extendClass(Child, Parent) {
  var proto = Object.create(Parent.prototype);
  proto.constructor = Child;
  proto.superClass = Parent;
  proto.__super__ = Parent.prototype;

  // Как переименовать этот метод?
  proto.initialize = function () {
    this.superClass.apply(this, arguments);
  };

  // Как переименовать этот метод? С with работать не будет.
  // instance.super(method, arg1, arg2, ...)
  proto.super = function (method) {
    var args = Array.prototype.slice.call(arguments, 1);
    return this.__super__[method].apply(this, args);
  };

  extend(proto, Child.prototype);
  Child.prototype = proto;
}


extend:
function extend(target, source) {
  var names = Object.getOwnPropertyNames(source)
    , length = name.length;

  for (var i = 0; i < length; ++i) {
    var desc = Object.getOwnPropertyDescriptor(source, names[i]);
    Object.defineProperty(target, names[i], desc);
  }

  return target;
}


У меня проблемы с именованием переменных.

sexbot 16.05.2015 00:45

function extend(target, source) {
  var names = Object.getOwnPropertyNames(source)
    , length = names.length;

  for (var i = 0; i < length; ++i) {
    var desc = Object.getOwnPropertyDescriptor(source, names[i]);
    Object.defineProperty(target, names[i], desc);
  }

  return target;
}

function inherit(Child, Parent) {
  var proto = Object.create(Parent.prototype);
  proto.constructor = Child;
  proto.parent = Parent.prototype;
  extend(proto, Child.prototype);
  Child.prototype = proto; 
}

function Animal(name, sound) {
  this.name = name;
  this.sound = sound;
}

Animal.prototype.say = function() {
  console.log("%s says %s", this.name, this.sound);
};

function Cat() {
  this.parent.constructor.call(this, "cat", "meow");
}

Cat.prototype.lick = function(what) {
  console.log("%s licking his %s", this.name, what);
};

inherit(Cat, Animal);

var cat = new Cat;
cat.say();
cat.lick("balls");


Часовой пояс GMT +3, время: 05:02.