Может кто-то объяснять JavaScript prototypal наследование

Я не могу думать об определенном примере, когда хорошо выполнить явный GC.

В целом, выполняя явный GC может на самом деле нанести больше ущерба, чем хороший, потому что явный gc инициирует полный набор, который берет значительно дольше, поскольку это проходит каждый объект. Если этот явный gc заканчивает тем, что неоднократно позвонился, это могло бы легко привести к медленному приложению, поскольку много времени проведено, выполнив полный GCs.

, Кроме того, при осмотре через "кучу" с "кучей" анализатор и Вы подозреваете, что компонент библиотеки называет явный GC, можно повернуть его от добавления: gc =-XX: + DisableExplicitGC к параметрам JVM.

7
задан ekhaled 10 November 2009 в 21:22
поделиться

6 ответов

Я думаю, вы хотели установить что-то равное new animate () где-нибудь в вашем примере. Без использования new я немного поясню, что происходит:

var animate = function(){ console.log(0, 'animate'); };
animate.angular = function(){ console.log(1, 'animate.angular'); };
animate.circular = function(){ console.log(2, 'animate.circular'); };

animate.prototype.angular = function(){ console.log(3, 'animate.prototype.angular'); };
animate.prototype.circular = function(){ console.log(4, 'animate.prototype.circular'); };

Только первые две функции, # 1 и # 2, могут быть вызваны из переменной animate.

animate.angular();
animate.circular();

Если вы создаете ] new animate () , вы можете вызвать следующие два, # 3 и # 4, (но не # 1 или # 2).

var ani2 = new animate();

ani2.angular();
ani2.circular();

Также, animate () является функцией, а ani2 - нет.

console.log(5, typeof animate);
console.log(6, typeof ani2);
console.log(7, animate());

Хотя ani2 уже создан, вы можете добавлять к нему новые члены с помощью animate.prototype.

animate.prototype.bark = function(){ console.log(8, 'bark'); };
ani2.bark();

Однако переменная animate не наследует от своего прототипа.

console.log(9, typeof ani2.bark);
console.log(10, typeof animate.bark);

Обратите внимание, что ani2 не наследует члены, примененные непосредственно к анимировать переменную. Он наследуется только от animate.prototype.

animate.paperclip = function(){ console.log(11, "paperclip"); };

animate.paperclip();
console.log(12, typeof ani2.paperclip);
console.log(13, typeof animate.paperclip);

Вы также можете использовать ключевое слово this внутри функции конструктора, например animate, для добавления членов экземпляра в new потомков.

var Anime = function(a,b){ this.a=a; this.b=b; this.c=console; };
var anime1 = new Anime(14, 'anime1');
var anime2 = new Anime(15, 'anime2');
anime1.c.log(anime1.a, anime1.b);
anime2.c.log(anime2.a, anime2.b);

Anime.prototype.a = 16;
Anime.prototype.z = 'z';

var anime3 = new Anime(17, 'anime3');
anime3.c.log(18, anime3.a, anime3.b, anime3.z, " ", anime2.a, anime2.b, anime2.z, " ", anime1.a, anime1.b, anime1.z);
anime2.z='N';
anime3.c.log(19, anime3.a, anime3.b, anime3.z, " ", anime2.a, anime2.b, anime2.z, " ", anime1.a, anime1.b, anime1.z);

Память была автоматически выделена для отдельного экземпляра anime2 .z только потому, что он был изменен, anime1 и anime3 по-прежнему "разделяют" бережливое немодифицированное z.

Члены a, b и c не являются "общими" таким же образом. Они были выделены немедленно с помощью this в конструкторе new Anime () (не унаследовано от Anime.prototype). Кроме того, член a в прототипе всегда будет «индивидуализирован» конструктором.

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

console.log(20, typeof window.a, typeof window.b, typeof window.c);
var opps = Anime(21, 'zapp');
console.log(22, typeof window.a, typeof window.b, typeof window.c);
console.log(23, typeof opps);

Вот результат. И второе за то, что Том предлагает видео Дугласа Крокфорда!


/*
1 animate.angular
2 animate.circular
0 animate
3 animate.prototype.angular
4 animate.prototype.circular
5 function
6 object
0 animate
7 undefined
8 bark
9 function
10 undefined
11 paperclip
12 undefined
13 function
14 anime1
15 anime2
18 17 anime3 z 15 anime2 z 14 anime1 z
19 17 anime3 z 15 anime2 N 14 anime1 z
20 undefined undefined undefined
22 number string object
23 undefined
*/
6
ответ дан 6 December 2019 в 12:52
поделиться

Хотя иногда кажется, что это так, javascript не имеет классов, но работает с прототипами. Вы определяете прототип, затем вы можете создавать копии прототипа.

Начиная с:

var animate=function(){};
animate.angular=function(){/*does something here*/};

вы можете:

var a = new animate();
animate.angular();       // OK
a.circular();            // error: a.circular is not a function

Однако, если вы начнете с:

function animate(i){};
animate.prototype.angular = function() {};

, теперь вы можете

var a = new animate();
a.angular();

, конечно, это больше интересно, если у вас есть переменные экземпляра.

function animate(i) {
    this.x = i;
}
animate.prototype.angular = function() {
    this.x *= 2;
}

var a = new animate(5);
a.angular();
console.log(a.x);    // 10
3
ответ дан 6 December 2019 в 12:52
поделиться

Если вы можете уделить 3 часа времени, я бы посоветовал вам взглянуть на видео «Язык программирования JavaScript» из YUI Theater. Спикер / преподаватель - Дуглас Крокфорд, и он даст вам прочную основу для JS, на которой вы сможете строить.

С уважением

Том

2
ответ дан 6 December 2019 в 12:52
поделиться

Javascript - странный язык ... очень мощный, но не настолько сильно структурированный по сравнению с другими языками ...

Прототип как JavaScript позволяет вам экономить память, если вы собираетесь создавать несколько экземпляров класса ... Итак, если вы используете JS как ООП, вы должны определять свои функции как часть прототипа. Кроме того, есть способы имитировать наследование с помощью прототипа.

Я настоятельно рекомендую книгу «Javascript, the Good Parts» для множества хороших объяснений по этому поводу.

2
ответ дан 6 December 2019 в 12:52
поделиться

Prototype-based OOP gives you freedoms Classy OOP doesn't.

If you really want to learn about it, like many said, read Crockford's explanations, you won't get any better resource than that.

If you want quick benefits:

var Building = function() {
    this.openDoor = function() {};
};

var House = function() {
    this.closeDoor = function() {};
};
House.prototype = new Building();

var a = new House();
a.openDoor();
a.closeDoor();

Defining objects (which will represent what classes are in other languages) like this is WAY too nasty, so I will include a little tip in my answer:

Best way to build your system, is under a global namespace chosen by you, for example:

if (typeof MYAPP === 'undefined' || !MYAPP) {
    var MYAPP = {};
}

function New(className, classBody) {
    // This adds your "classes" to this MYAPP namespace so they can be instantiated
    // You need some magic here, so have fun with this function
}

New('Building', function() {
    this.openDoor = function() {};
});

New('House', function() {
    this.prototype = new MYAPP.Building();
    this.closeDoor = function() {};
});

// Now you can do the same as before but your application is cleaner :)
var a = new MYAPP.House();
a.openDoor();
a.closeDoor();

Cheers.

2
ответ дан 6 December 2019 в 12:52
поделиться

Другие уже упоминали Дугласа Крокфорда , проверьте Прототипное наследование на его сайте для получения дополнительной информации. Для контраста см. Классическое наследование .

Как и Гундерсон, я также рекомендую (тонкую) книгу Крокфорда JavaScript: Хорошие части .

1
ответ дан 6 December 2019 в 12:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: