Javascript Inheritance: de juiste manier?

Door Gamebuster op dinsdag 22 februari 2011 15:51 - Reacties (11)
Categorie: if(post.relatedTo("programming")), Views: 3.260

Ik ben al een tijd bezig met Javascript. Ik heb vele manieren gehad om OOP toe te passen op Javascript.

Tot kort was mijn standaard manier als volgt:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
function A1()
{
    this._prop1 = null;
    this._prop2 = null;
    this._prop3 = null;
    
    this.getProp1 = function()
    {
        return this._prop1;
    };
    
    this.getProp2 = function()
    {
        return this._prop2;
    };
    
    this.getProp3 = function()
    {
        return this._prop3;
    };
    
    this.setProp1 = function(prop1)
    {
        this._prop1 = prop1;
    };
    
    this.setProp2 = function(prop2)
    {
        this._prop2 = prop2;
    };
    
    this.setProp3 = function(prop3)
    {
        this._prop3 = prop3;
    };
}

B1.prototype = new A1();
function B1()
{
    A1.call(this);
    
    this._prop4 = null;
    
    this.getProp4 = function()
    {
        return this._prop4;
    };
    
    this.setProp4 = function(prop4)
    {
        this._prop4 = prop4;
    };
}



Wanneer ik nu een B1 object aanmaak, worden alle properties en functies van A1 netjes overgenomen. Ook geeft "new B1() instanceof A1" netjes "true" terug.

Echter, ik kwam vanmorgen mijn bed uit en dacht bij mezelf: Ik wijs hier functies toe als properties; ieder B1 object dat ik nu maak heeft al zijn functies opgeslagen in zijn eigen properties. Zou dit niet veel geheugen kosten?
Ik wed dat jullie ook allemaal met zulke vragen wakker worden

Nog zonder me aan te kleden ging ik direct achter de computer zitten, maakte een nieuw Javascript bestandje aan en herschreef mijn B1 class, onder de naam "B2", als volgt:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
function A2()
{
    this._prop1 = null;
    this._prop2 = null;
    this._prop3 = null;
}

A2.prototype.getProp1 = function()
{
    return this._prop1;
};

A2.prototype.getProp2 = function()
{
    return this._prop2;
};

A2.prototype.getProp3 = function()
{
    return this._prop3;
};

A2.prototype.setProp1 = function(prop1)
{
    this._prop1 = prop1;
};

A2.prototype.setProp2 = function(prop2)
{
    this._prop2 = prop2;
};

A2.prototype.setProp3 = function(prop3)
{
    this._prop3 = prop3;
};

B2.prototype = new A2();
function B2()
{
    A2.call(this);
    
    this._prop4 = null;
}

B2.prototype.setProp4 = function(prop4)
{
    this._prop4 = prop4;
};



Opnieuw, bij het maken van een nieuw B2 object geeft "new B2() instanceof A2" nog steeds netjes "true" terug. Ook werken alle methods nog.

Er is echter 1 groot verschil:
Bij het aanmaken van 10.000 B1 objecten wordt er in NodeJS 7199KiB aan geheugen gebruikt.
Bij het aanmaken van 10.000 B2 objecten wordt er in NodeJS 472KiB aan geheugen gebruikt.

testcode:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
function getMemUsage()
{
    return process.memoryUsage().heapUsed/1000;
}

var memStart = getMemUsage();

var array = new Array();
for(var i=0; i<10000; i++)
    array.push(new B1()); // voor 2e test gebruikte ik hier "B2", uiteraard.

console.log(Math.round(getMemUsage() - memStart)+"KiB");



Ik weet niet echt wat nou "de" manier is om Javascript classes te maken, maar tenzij ik nog nadelen van die 2e methode tegenkom, ga ik voortaan deze gebruiken.

Javascript: Drop Images, Resize & Upload

Door Gamebuster op donderdag 10 februari 2011 15:49 - Reacties (30)
Categorie: if(post.relatedTo("programming")), Views: 4.323

Op het forum, in "Lieve Devvers", werd er gevraagd of het uploadlimit van foto's voor in V&A verhoogd kon worden, zodat mensen hun 4000x3000-pixels grote afbeeldingen konden uploaden zonder deze eerst te hoeven verkleinen.

Stelletje luiaards, maar ach: wie wilt er nou niet lui zijn?

Er werd vervolgens gevraagd of er een mogelijkheid kon komen dat de afbeeldingen verkleind werden op de server na het uploaden, maar dit schijnt teveel serverload te kosten.

Echter, tegenwoordig heb je HTML5. In HTML5 heb je een paar leuke nieuwe features, namelijk:
-HTML5 File API, waarmee de gebruiker bestanden kan openen vanuit de webpagina zonder dat deze eerst geupload moet worden.
-HTML5 Canvas, waarop afbeeldingen "getekend" kunnen worden en waarvan je daarna weer een nieuwe afbeelding kunt maken.

Ik dacht dus bij mezelf, bij het lezen van dat topic: wat nou als je het HTML5 API gebruikt voor het inlezen van afbeeldingen, direct vanaf de computer van de gebruiker, en HTML5 Canvas gebruikt voor het verkleinen van deze afbeeldingen om tot slot de verkleinde afbeelding te verzenden naar de server via AJAX.

Een paar Google zoekacties later en ik vond voldoende info om dit uit te werken; Puur door HTML5 File API en HTML5 canvas te gebruiken, heb ik een "webapplicatie" waar de gebruiker zijn foto's kan dumpen, waarna deze direct verkleint en geupload worden.

Het resultaat:
> http://levensweg.net/ImageUpload/

Sleep een afbeelding op die pagina en het zal direct ingelezen, verkleind en geupload worden. Op dit moment staat-ie ingesteld op 300x200.

Helaas lijkt dit alleen nog maar te werken in Firefox 4. Safari & Chrome ondersteunen de File API nog maar deels, maar staan nog niet toe om de bestanden daadwerkelijk te openen; Google zegt hier nog mee bezig te zijn.

Omdat de File API gewoon netjes omschreven staat op w3.org (http://www.w3.org/TR/FileAPI/), verwacht ik echter dat toekomstige updates van browsers deze wel gaan ondersteunen, waaronder dus ook mijn image-uploader.

Broncode: http://levensweg.net/ImageUpload/source.zip

Note: ik bied geen enkele garantie dat de afbeeldingen online zullen blijven. Gebruik dit dus niet als image-host voor langer termijn; dit is puur een demo.