Vinnaren i pepparkakshustävlingen!
2018-06-14, 14:50
  #1
Bannlyst
Begriper inte vad som är vad här och hur de fungerar ihop. Man skapar ett object och den tilldelas en prototype som är tom. Object innehåller sen olika prototypes. Om jag definierar ett object:

var funnyGuy = {};

Vad har man gjort då? Den är tom men innehåller ändå en prototyp som i sin tur innehåller ett object?

Tacksam om någon kan förklara tydligt och ingående.
Citera
2018-06-14, 21:20
  #2
Medlem
I JavaScript så skapas generellt alla objekt med en referens till ett annat objekt. Du kan se det som påtvingad arv (inheritance), men med skillnaden att du ärver ifrån ett objekt och inte ifrån en mall (class) - som är standard i de flesta andra programmeringsspråk.

I ditt exempel:
Kod:
var funnyGuy = {}; // använd gärna "const" istället (sök)
Så betyder det typ detta:
Kod:
var funnyGuy = Object.create(Object.prototype, { });
Skulle du ändra något objekt i Object.prototype, så kommer alla instanser som refererar till Object.prototype att beröras:
Kod:
const funnyGuy = { name: 'John Doe' };
Object.prototype.getName = function() {
  return this.name;
};
console.log(funnyGuy.getName()) // skriver ut "John Doe"
Detsamma gäller även funktioner, strängar och siffror:
Kod:
const name = "";
Object.getPrototypeOf(name) === String.prototype // true
const age  = 123;
Object.getPrototypeOf(age) === Number.prototype // true
const add = (a, b) => a + b;
Object.getPrototypeOf(add) === Function.prototype // true
Men en prototype kan också ha en referens till en annan prototype och på detta sättet skapa en kedja:
Kod:
Object.getPrototypeOf(Function.prototype) === Object.prototype; // true
Object.getPrototypeOf(String.prototype) === Object.prototype; // true
Object.getPrototypeOf(Number.prototype) === Object.prototype; // true
Som du ser kan du manipulera alla objekt indirekt via att endast skapa en nytt attribut på Object.prototype. Detta är generellt dåligt:
Kod:
const names = [];
Object.prototype.size = 123;
if(names.size) { // utvecklaren blandar ihop "size" med "length"
  console.log('BANG!');
}
Detta är generellt dåligt. Du kan undvika en prototype-kedja via att använda Object.create(null) om du verkligen vill, men det generella svaret är att alltid undvika bibliotek och kod som manipulerar Object.prototype:
Kod:
const john = Object.create(null); // prova med bara {}
Object.getPrototypeOf(john) === Object.prototype // false
Dessa egenskaper ovanför är en av JavaScript missförstådda egenskaper men samtidigt betydligt kraftfullt om det används rätt. Speciellt personer som kommer ifrån en "backend" värld brukar uppvisa stora kunskapsbrister i det jag har beskrivit ovanför, då de inte förstår att man ärver ifrån ett objekt (påtvingat) och inte ifrån en mall (klass). Man har dock lagt till ett nytt "class" koncept på senare år, just för att göra det enklare för sådana personer att förstå.
__________________
Senast redigerad av trellen 2018-06-14 kl. 21:23.
Citera
2018-06-16, 21:00
  #3
Bannlyst
Citat:
Ursprungligen postat av trellen
I JavaScript så skapas generellt alla objekt med en referens till ett annat objekt. Du kan se det som påtvingad arv (inheritance), men med skillnaden att du ärver ifrån ett objekt och inte ifrån en mall (class) - som är standard i de flesta andra programmeringsspråk.

I ditt exempel:
Kod:
var funnyGuy = {}; // använd gärna "const" istället (sök)
Så betyder det typ detta:
Kod:
var funnyGuy = Object.create(Object.prototype, { });
Skulle du ändra något objekt i Object.prototype, så kommer alla instanser som refererar till Object.prototype att beröras:
Kod:
const funnyGuy = { name: 'John Doe' };
Object.prototype.getName = function() {
  return this.name;
};
console.log(funnyGuy.getName()) // skriver ut "John Doe"
Detsamma gäller även funktioner, strängar och siffror:
Kod:
const name = "";
Object.getPrototypeOf(name) === String.prototype // true
const age  = 123;
Object.getPrototypeOf(age) === Number.prototype // true
const add = (a, b) => a + b;
Object.getPrototypeOf(add) === Function.prototype // true
Men en prototype kan också ha en referens till en annan prototype och på detta sättet skapa en kedja:
Kod:
Object.getPrototypeOf(Function.prototype) === Object.prototype; // true
Object.getPrototypeOf(String.prototype) === Object.prototype; // true
Object.getPrototypeOf(Number.prototype) === Object.prototype; // true
Som du ser kan du manipulera alla objekt indirekt via att endast skapa en nytt attribut på Object.prototype. Detta är generellt dåligt:
Kod:
const names = [];
Object.prototype.size = 123;
if(names.size) { // utvecklaren blandar ihop "size" med "length"
  console.log('BANG!');
}
Detta är generellt dåligt. Du kan undvika en prototype-kedja via att använda Object.create(null) om du verkligen vill, men det generella svaret är att alltid undvika bibliotek och kod som manipulerar Object.prototype:
Kod:
const john = Object.create(null); // prova med bara {}
Object.getPrototypeOf(john) === Object.prototype // false
Dessa egenskaper ovanför är en av JavaScript missförstådda egenskaper men samtidigt betydligt kraftfullt om det används rätt. Speciellt personer som kommer ifrån en "backend" värld brukar uppvisa stora kunskapsbrister i det jag har beskrivit ovanför, då de inte förstår att man ärver ifrån ett objekt (påtvingat) och inte ifrån en mall (klass). Man har dock lagt till ett nytt "class" koncept på senare år, just för att göra det enklare för sådana personer att förstå.
Schysst! Vad är det för objekt jag kan ändra, hur ser det liksom ut när alla instanser ändras?

När ett objekt skapas och får en prototyp, finns det olika egenskaper i denna prototyp som du menar att jag kan ändra varmed alla instanser ändras?

var funnyguy // jag avänder const i forsättningen, men för att inte ägna mig åt begreppsförvirring så håller jag mig till var.

funnyguy är dock en tom prototyp som inte tilldelats några egenskaper, men om den tilldelas egendkaper, hur ser det ut då?

När du skriver

var funnyGuy = Object.create(Object.prototype, { });

borde inte 'John Doe' stå innanför {}?
Citera
2018-06-16, 23:36
  #4
Medlem
Citat:
Ursprungligen postat av goldcashier
Schysst! Vad är det för objekt jag kan ändra, hur ser det liksom ut när alla instanser ändras?

När ett objekt skapas och får en prototyp, finns det olika egenskaper i denna prototyp som du menar att jag kan ändra varmed alla instanser ändras?
Ja, det var precis det jag visade flera exempel på.
Citat:
funnyguy är dock en tom prototyp som inte tilldelats några egenskaper, men om den tilldelas egendkaper, hur ser det ut då?

När du skriver

var funnyGuy = Object.create(Object.prototype, { });

borde inte 'John Doe' stå innanför {}?
Nej, funnyGuy är inget tomt objekt. Det var det jag precis visade, att i princip alla objekt innehåller en referens till en prototyp, som om den ändras kommer påverka alla objekt som refererar till denna "prototyp".

Angående Object.create: https://developer.mozilla.org/en-US/.../Object/create
Citera
2018-06-17, 13:49
  #5
Bannlyst
Citat:
Ursprungligen postat av trellen
Ja, det var precis det jag visade flera exempel på.

Nej, funnyGuy är inget tomt objekt. Det var det jag precis visade, att i princip alla objekt innehåller en referens till en prototyp, som om den ändras kommer påverka alla objekt som refererar till denna "prototyp".

Angående Object.create: https://developer.mozilla.org/en-US/.../Object/create
funnyguy är inget tomt objekt men dennes prototyp är det? Ska man definiera properties i prototypen? Typ namn, efternamn, ålder osv?

Krångligt värre. Vad är det ens bra för?

I boken tar de detta exempel:

Citat:
var person = {
getName: function () {
return "The name is " + this.function + " " + this.lastname;
}
};

var funnyguy = Object.create(person) ;
funnyguy.firstName = "Conan" ;
funnyguy.lastName = "Obrien" ;

alert(funnyguy.getName() ) ;


Förstår inte vad de gör. De skapar en variabel som innehåller funktionen getName och som ska returnera namn när vi anropar den. Därefter skapas en ny variabel. Object.create förstår jag inte ens vad den gör när den refererar till en ny Object.create innanför parentesen.

I ditt exempel

Citat:
const funnyGuy = { name: 'John Doe' };
Object.prototype.getName = function() {
return this.name;
};
console.log(funnyGuy.getName()) // skriver ut "John Doe"
Om John Doe ändras till Robert, har jag ändrat ett objekt så att det påverkar alla andra instanser?

Hänger verkligen inte med.
Citera
2018-06-17, 15:48
  #6
Medlem
Citat:
Ursprungligen postat av goldcashier
Förstår inte vad de gör. De skapar en variabel som innehåller funktionen getName och som ska returnera namn när vi anropar den. Därefter skapas en ny variabel. Object.create förstår jag inte ens vad den gör när den refererar till en ny Object.create innanför parentesen.

Alla objekt i javascript har en prototyp, som är en referens till ett annat objekt. Object.create(proto[, propertiesObject]) ger dig ett nytt objekt vars prototyp är satt till parametern proto.

Det går ganska enkelt att skriva Object.create-funktionen själv, se nedanstående codepen för exempel så kanske det klarnar. (Det här är bara ett exempel, undvik generellt setPrototypeOf-funktionen i din egen kod. Använd istället Object.create.)
https://codepen.io/anon/pen/PaOpKj?editors=0010

Det som händer i koden är att vi skapar ett tomt objekt, och sätter dess prototyp till objektet "person".
Sedan tilldelar vi vårt nya objekt en name-egenskap (ex Mikael).
Sen anropar vi metoden stateName på Mikael.
Javascript-tolken kommer då titta om Mikael har stateName-funktionen definierad. Det har den inte. Då börjar tolken klättra uppför prototyp-trädet tills den hittar en sådan. Så den tittar i Mikaels prototyp, som är Person, och hittar den, och exekverar anropet.
Citera
2018-06-17, 16:27
  #7
Medlem
Kan för övrigt rekommendera dig att kolla upp funfunfunction på youtube och hans tutorials på Object Creation, så får du det mer på djupet.
Citera

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Det är enkelt att registrera ett nytt konto

Bli medlem

Logga in

Har du redan ett konto? Logga in här

Logga in