Jaka jest różnica między dodaniem właściwości do obiektu funkcyjnego VS, dodając nieruchomość do prototypu obiektów. Zobacz kod poniżej.

var foo = function() { this.name = alert("test") };

foo.newProp = function() { ... };
var value = new foo();

// vs

foo.prototype.newProp = function() { ... }
var value = new foo();

Moje zamieszanie jest tym, co dzieje się wartością, gdy ten kod jest uruchamiany dla każdego, a dotknięte jest "ten".

0
DarkFm 24 czerwiec 2017, 09:00

3 odpowiedzi

Najlepsza odpowiedź

Po pierwsze, wiemy, że funkcje są niczym oprócz obiektów, ponieważ możemy dołączyć do niego właściwości. To dzieje się w przypadku1. Po prostu przyklejamy nieruchomość do function Foo

Przypadek 1

var Foo = function(){
    this.name = "myname";
}

Foo.newProp = function(){}; 

Nieruchomość dołączona do funkcji może być po prostu dostępna jako sposób dostępu do właściwości obiektu.

Przypadek 2

W tym przypadku ta sama właściwość siedzi na tej funkcji prototype. Gdy każdy obiekt jest tworzony przy użyciu tego function Foo, domyślnie otrzyma dostęp do tej funkcji.

Podczas wywołania funkcji za pomocą tego obiektu kontekst this będzie znać obiekt wywołujący tę funkcję i {X1}} wskazuje do obiektu.

Foo.prototype.newProp = function(){ console.log("function on prototype");}

var value = new Foo();

console.log(value);

Również w przypadku 2, ponieważ dodajemy właściwości do prototypu funkcji, nie siedzą na obiekcie wykonanym za pomocą tej funkcji, ale na proto tego obiektu. Sprawdź ten ekran pokazany poniżej:

enter image description here

Oznacza to, że istnieje wspólna lokalizacja pamięci, do której każdy obiekt uzyskuje dostęp do tej nieruchomości, a zatem jest również skuteczny pamięć.

Zawsze możesz iść dalej i modyfikować tę nieruchomość, nadając ją, definiując ją bezpośrednio na obiekcie jako:

value.newProp = function(){ console.log("modified property") };

Teraz, jeśli zadzwonisz do tej funkcji, znajdzie go bezpośrednio na obiekcie i nie przejdziesz w dół łańcucha prototypowego, aby uzyskać dostęp do niej z wspólnej lokalizacji pamięci I.E prototypem function Foo

1
Rahul Arora 25 czerwiec 2017, 06:09

foo.newprop = funkcja () {...};?

Dotyczy to funkcji na poziomie funkcji (klasy).

Możesz uzyskać do niego dostęp bezpośrednio bez użycia obiektu.

foo.newProp() // call it.

foo.prototype.Newprop = funkcja () {...};?

To zdefiniować poziom instancji newProp (object or class instance).

Trzeba zdefiniować obiekt za pomocą new, a następnie tylko będziesz mógł uzyskać do niego dostęp.

var value = new foo();
value.newProp() // call it

Definiując funkcję za pomocą prototypu, udostępniasz go wszystkim + nowo zdefiniowanym obiektem danej funkcji

0
RIYAJ KHAN 24 czerwiec 2017, 06:21

Intro

Ponieważ funkcje są obiektami, sprawa 1 jest niczym więcej niż dodawaniem nieruchomości do obiektu. Przypadek 2 jest bardziej interesujący. Rozważ następujący kod:

function f (name) {
  this.name = name;
}

f.prototype.sayHello = function () {
  console.log("Hello I'm " + this.name + " !");
};

var x = new f("X");
var y = new f("Y");
<button type="button" onclick="x.sayHello()">x.sayHello()</button>
<button type="button" onclick="y.sayHello()">y.sayHello()</button>

Zauważ, że w tym kodzie nie ma nic takiego jak x.sayHello = function () {...}. Pomyśl o tym dwa razy i zadaj sobie pytanie:

Ponieważ x.sayHello nigdy nie jest wyraźnie zdefiniowany, co jest podstawowym mechanizmem, który zapobiega awarii programu?

Oto jest pytanie.

Przedstawić magię

Na szczęście nie ma nic magicznego, tylko wewnętrznego przetwórstwa JavaScript. Rzeczywiście, gdy tworzysz obiekt z new, lub gdy zadzwonisz do funkcji, jest coś, co dzieje się za sceną , w której zaangażowany jest właściwość prototype.

Kiedy piszesz new f(), silnik JavaScript:

  1. Tworzy nowy obiekt.
  2. Ustawia this do nowego obiektu.
  3. Wykonuje f.
  4. Dodaje właściwość __proto__ do nowego obiektu.
  5. Wiąże __proto__ do f.prototype.
  6. Zwraca nowy obiekt.

Kiedy piszesz x.sayHello(), silnik JavaScript:

  1. Wygląda na x.
  2. Idzie do kroku 6, jeśli zostanie znaleziony sayHello.
  3. Wygląda na x.__proto__ inaczej.
  4. Idzie do kroku 6, jeśli zostanie znaleziony sayHello.
  5. Podnosi wyjątek i wychodzi inaczej.
  6. Ustawia this do x.
  7. Wykonuje sayHello.

Kluczowe punkty do podświetlenia:

  • Gdy używasz słowa kluczowego new, JavaScript tworzy łańcuch prototypowy, tj. Silnik wykonuje następujące zadanie: x.__proto__ = f.prototype.
  • Gdy próbujesz zadzwonić do funkcji, JavaScript wykonuje wyszukiwanie przez ten łańcuch prototypowy. Na przykład, gdy piszesz x.sayHello(), jeśli javascript nie znajdzie sayHello do x, wygląda na x.__proto__, która jest f.prototype.
  • Wartość this zależy od kontekstu. Na przykład, gdy piszesz x.sayHello(), this x x, kiedy piszesz y.sayHello(), this y, kiedy piszesz {{}. X7}}, this to nowy obiekt. Więcej o this.

Dla ninja

Wdrożenie niestandardowe:

function instanciate (f, args) {
  var object = {};
  f.apply(object, args);
  object.__proto__ = f.prototype;
  return object;
}

function execute (object, fName, args) {
  var f = lookup(object, fName);
  if (typeof f !== "function") {
    throw "not a function";
  } else {
    f.apply(object, args);
  }
}

function lookup (object, key) {
  do {
    if (object.hasOwnProperty(key)) {
      return object[key];
    } else {
      object = object.__proto__;
    }
  }
  while (object !== null);
}

function f (name) {
  this.name = name;
}

f.prototype.sayHello = function () {
  console.log("Hello I'm " + this.name + " !");
};

var x = instanciate(f, ["X"]);
var y = instanciate(f, ["Y"]);
<button 
  type="button"
  onclick="execute(x, &quot;sayHello&quot;)"
>execute(x, "sayHello")</button>
<button
  type="button"
  onclick="execute(y, &quot;sayHello&quot;)"
>execute(y, "sayHello")</button>

Dygresja

Obiekt globalny nie jest wyjątkowy:

f.prototype.__proto__ = window.__proto__;
window.__proto__ = f.prototype;
name = "John Doe";
sayHello(); // "Hello I'm John Doe !"

Powiązane linki

1
leaf 10 styczeń 2018, 07:12