#javascript #oop
#javascript #ООП
Вопрос:
Я немного понимаю разницу между Javascript и Java, когда дело доходит до ООП. Я прочитал нижний абзац в книге по Javascript, которая у меня есть, но я не до конца понимаю, что это значит, можете ли вы подробнее объяснить и привести примеры, чтобы показать разницу между двумя языками?
«Во многих объектно-ориентированных языках программирования можно определить класс объектов, а затем создавать отдельные объекты, которые являются экземплярами этого класса».
Спасибо!
Ответ №1:
То, что большинство людей делают, это используют функции конструктора, например, так:
function MyClass(a, b) {
// Private instance properties
var x = "secret";
var y = "also secret";
// Public instance properties
this.a = a;
this.b = b;
// "Privileged" methods; can access private and public properties
this.foo = function () {
return x " " this.a;
};
}
// "Public" methods; cannot access private properties
MyClass.prototype.bar = function () {
return this.a " " this.b;
};
// Public shared properties; not recommended:
MyClass.prototype.w = "stuff";
// Static methods
MyClass.baz = function () {
return "i am useless";
};
Затем вы могли бы использовать эту функцию конструктора следующим образом:
var instance = new MyClass("hi", "Meen");
asssert.equal(instance.foo(), "secret hi");
assert.equal(instance.bar(), "hi Meen");
assert.equal(MyClass.baz(), "i am useless");
var also = new MyClass("hi", "Raynos");
instance.w = "more stuff";
assert.equal(also.w, "more stuff");
Если бы вы хотели использовать наследование, вы бы сделали что-то вроде:
function Inherited(a) {
// apply parent constructor function
MyClass.call(this, a, "Domenic");
}
Inherited.prototype = Object.create(MyClass.prototype);
var inherited = new Inherited("hello there good chap");
assert.equal(inherited.a, "hello there good chap");
assert.equal(inherited.foo(), "secret hello there good chap");
assert.equal(inherited.bar(), "hello there good chap Domenic");
Комментарии:
1. Вы просматриваете «частные» и «привилегированные», не объясняя, что они являются просто локальными переменными в замыкании и определяют стоимость времени выполнения, а также мешают выполнению прототипного OO. Это две параллельные конструкции, и они не особенно хорошо работают вместе.
2. Микрооптимизации никогда не были важны в моем опыте выполнения ООП на JavaScript; возможность использовать один из четырех принципов ООП, а именно. гораздо важнее инкапсуляция.
3. В этом случае вам не нужен прототип OO. У вас должны быть просто фабрики, которые мутируют
this
. Также обратите внимание, что «инкапсуляция» соответствует второму определению в википедии .4. Да, второе определение — это не то, что подразумевается под инкапсуляцией в контексте ООП, ср. blog.ploeh.dk/2011/05/24 /…
5. Meh, для этого вам не нужны локальные переменные, связанные с закрытием. Вы можете использовать разумное, хорошо документированное соглашение, такое
._internalName
как внутреннее, недокументированное и, вероятно, изменяющееся или взрывающееся при прикосновении к коду, использующему «класс». Это дает вам инкапсуляцию и прототипический OO.
Ответ №2:
Объектно-ориентированный javascript очень прост.
Вы создаете объект.
var Klass = {
method: function () {
},
constructor: function() {
},
...
};
И затем вы создаете экземпляр этого объекта с помощью прототипического наследования
// instantiate
var o = Object.create(Klass);
// initialize
o.constructor();
Это отличается от классического OO, потому что любой объект может быть «классом» в javascript. и есть только одна цепочка наследования, цепочка прототипов.
Обычно в классических языках OO классы наследуются друг от друга, а экземпляры будут иметь отдельную цепочку наследования.
Также в классическом OO у вас есть два объекта: фактический объект класса и схема для экземпляра (т. Е. static
). Этого не существует в javascript, потому что есть только один объект, blueprint.
Отказ от ответственности: Object.create
это ES5, поэтому вам нужна es5-shim для устаревших платформ.
Комментарии:
1. О, дорогой, не продвигай свой любимый недавно обнаруженный стиль прототипов как классов без хотя бы какого-либо заявления об отказе от ответственности… @Meen то, что делает Raynos, делается очень немногими людьми и является результатом какой-то статьи, которая стала популярной в течение последнего месяца; вы не увидите много кода JavaScript в дикой природе, подобного этому.
2. @Domenic Это практически одно и то же.
Klass.constructor.prototype === Klass
amp;amp;Constructor.prototype.constructor === Constructor
. Это вопрос личного стиля, и я нахожу это намного более читаемым и элегантным, чем возня с конструкторами,.prototype
иnew
. И на самом деле то, что я делаю, отражает примеры объектов es.next и классы es.next, сообщество ES отойдет от конструкторов. И, кроме того, помимо «Это не мой выбор стиля», есть ли что-то не так с конструкциями, которые я показываю?3. Это совсем не одно и то же. Этот стиль отделяет инициализацию от создания с помощью этого конструктора, что является существенным отличием, и что более важно, этот стиль используется очень немногими людьми на планете. Субъективные мнения о удобочитаемости и элегантности перевешиваются тем, хочет ли OP, чтобы его код был доступен для чтения тем, кто не читал сообщение в блоге Раушмайера.
4. @Domenic meh,
var KlassConstructor = Klass.constructor; var instance = new KlassConstructor(...);
. Они одинаковы. И инициализация, и построение всегда были отдельными,new
просто случается делать и то, и другое. Лично я бы сказал, что если кто-то не может прочитать код, тогда нужно изучить ES5.5. Примеры и Wirfs-предложение Брока «grawlixey» активно обсуждается; будут ли они приняты в ES.Next, совершенно неясно, как и то, будет ли сообщество адаптироваться к чему-либо подобному. Классы ES.next заменяют что-то гораздо более похожее на конструкторы, чем на примеры, и, что более важно, акцент на частных именах признает важность достижения инкапсуляции, так или иначе; в ES5 это достижимо только с помощью замыканий.
Ответ №3:
В Java вы можете создать класс, используя class
ключевое слово. Класс — это схема для его экземпляров (объектов).
например
class AClass { // AClass is a class
AClass() { } //this is the constructor which will be used to create instances of this class
}
А затем создайте и экземпляр класса:
AClass obj1 = new AClass(); // an instance of the class AClass
AClass obj2 = new AClasss(); //another instance of the class AClass
Итак, каждый объект в Java является экземпляром некоторого класса. И у вас может быть много разных экземпляров класса, но у вас не может быть никакого объекта без класса, который действует как их схема.
И в классе вы можете определить переменные-члены и методы, которые могут либо принадлежать самому классу, который будет общим для всех его экземпляров, либо принадлежать экземпляру, и в этом случае у каждого экземпляра будет своя копия.
В Javascript я в основном создаю объекты следующим образом:
var obj = { };
Итак, мне не нужно создавать какой-либо класс, чтобы фактически создать объект.
Комментарии:
1. Ха-ха, простота вашего ответа заставляет меня смеяться :). 1