Jakie techniki można zastosować do zdefiniowania klasy w JavaScript i jakie są ich kompromisy?

686

Wolę używać OOP w dużych projektach, takich jak ten, nad którym teraz pracuję. Muszę utworzyć kilka klas w JavaScript, ale jeśli się nie mylę, istnieje co najmniej kilka sposobów na zrobienie tego. Jaka byłaby składnia i dlaczego miałaby być wykonana w ten sposób?

Chciałbym uniknąć korzystania z bibliotek stron trzecich - przynajmniej na początku.
Szukając innych odpowiedzi, znalazłem artykuł Programowanie obiektowe w JavaScript, Część I: Dziedziczenie - Doc JavaScript, który omawia programowanie obiektowe w JavaScript. Czy istnieje lepszy sposób na dziedziczenie?

Karim
źródło
Uwaga: jest to duplikat stackoverflow.com/questions/355848
Jason S
3
Osobiście lubię deklarować członków klasy wewnątrz ciała funkcji. Używam techniki „naprawiania tego”, aby stworzyć zamknięcie, aby zachowywało się bardziej jak klasa. Mam szczegółowy przykład na moim blogu: ncombo.wordpress.com/2012/12/30/…
Jon
Przeniesiłem większość funkcji C ++ OOP do JavaScript z prostą i naturalną składnią. Zobacz moją odpowiedź tutaj: stackoverflow.com/a/18239463/1115652
W JavaScript nie ma klas. Ale jeśli chcesz symulować zachowanie podobne do klas w JS, możesz. Zobacz szczegóły w: symfony-world.blogspot.com/2013/10/…
ducin

Odpowiedzi:

743

Oto sposób na zrobienie tego bez użycia zewnętrznych bibliotek:

// Define a class like this
function Person(name, gender){

   // Add object properties like this
   this.name = name;
   this.gender = gender;
}

// Add methods like this.  All Person objects will be able to invoke this
Person.prototype.speak = function(){
    alert("Howdy, my name is" + this.name);
};

// Instantiate new objects with 'new'
var person = new Person("Bob", "M");

// Invoke methods like this
person.speak(); // alerts "Howdy, my name is Bob"

Teraz prawdziwa odpowiedź jest o wiele bardziej złożona. Na przykład nie ma czegoś takiego jak klasy w JavaScript. JavaScript używa prototypeopartego na schemacie dziedziczenia.

Ponadto istnieje wiele popularnych bibliotek JavaScript, które mają swój własny styl przybliżania klasowej funkcjonalności w JavaScript. Będziesz chciał sprawdzić przynajmniej Prototyp i jQuery .

Zdecydowanie, który z nich jest „najlepszy”, jest świetnym sposobem na rozpoczęcie świętej wojny na przepełnieniu stosu. Jeśli bierzesz udział w większym projekcie, w którym jest dużo JavaScript, zdecydowanie warto nauczyć się popularnej biblioteki i zrobić to po swojemu. Jestem prototypem, ale Stack Overflow wydaje się skłaniać ku jQuery.

O ile istnieje tylko „jeden sposób na zrobienie tego”, bez żadnych zależności od bibliotek zewnętrznych, sposób, w jaki napisałem, jest w zasadzie taki.

Tryptyk
źródło
48
Ale to nie działa jak język X, gdzie nauczyłem się jednego prawdziwego sposobu, w jaki powinno działać coś, co jest używane do tworzenia instancji obiektów :(
Erik Reppen
2
Według developer.mozilla.org/en-US/docs/Web/JavaScript/... właściwości powinny być dodawane do prototypu ( „Person.prototype.name =«»;”)
DaveD
1
@DaveD - może tak, ale już nie wydaje się ..?
Kieren Johnstone,
6
jQuery nie zapewnia nawet możliwości tworzenia funkcjonalności podobnej do klasy ??? (Wszystkie klasy, które ma, to klasy CSS) Powinieneś usunąć go z tej części odpowiedzi.
Bergi,
7
Od drugiej połowy 2015 roku został wydany nowy standard EcmaScript 6, więc proponuję zrobić to w nowy sposób (dużo czystszy i łatwiejszy) es6-features.org/#ClassDefinition
DevWL
213

Najlepszym sposobem zdefiniowania klasy w JavaScript jest brak zdefiniowania klasy.

Poważnie.

Istnieje kilka różnych rodzajów orientacji obiektowej, niektóre z nich to:

  • oparty na klasach OO (po raz pierwszy wprowadzony przez Smalltalk)
  • prototypowy OO (po raz pierwszy wprowadzony przez Self)
  • oparty na multimethod OO (chyba po raz pierwszy wprowadzony przez CommonLoops)
  • OO oparte na predykacie (bez pomysłu)

I prawdopodobnie inne, o których nie wiem.

JavaScript implementuje OO oparte na prototypach. W OO opartym na prototypach nowe obiekty są tworzone przez kopiowanie innych obiektów (zamiast tworzenia instancji z szablonu klasy), a metody żyją bezpośrednio w obiektach zamiast w klasach. Dziedziczenie odbywa się poprzez przekazanie: jeśli obiekt nie ma metody ani właściwości, jest sprawdzany na swoim prototypie (obiektach, z których został sklonowany), a następnie na prototypach prototypu i tak dalej.

Innymi słowy: nie ma klas.

JavaScript ma całkiem niezłą modyfikację tego modelu: konstruktorów. Nie tylko możesz tworzyć obiekty poprzez kopiowanie istniejących, ale możesz też konstruować je „z powietrza”, że tak powiem. Jeśli wywołasz funkcję za pomocą newsłowa kluczowego, funkcja ta stanie się konstruktorem, a thissłowo kluczowe nie będzie wskazywało na bieżący obiekt, lecz na nowo utworzony „pusty”. Możesz więc skonfigurować obiekt w dowolny sposób. W ten sposób konstruktory JavaScript mogą przyjąć jedną z ról klas w tradycyjnym OO opartym na klasach: służąc jako szablon lub plan dla nowych obiektów.

Teraz JavaScript jest bardzo potężnym językiem, więc jeśli chcesz, możesz łatwo wdrożyć oparty na klasach system OO w JavaScript . Jednak powinieneś to zrobić tylko wtedy, gdy naprawdę tego potrzebujesz, a nie tylko dlatego, że tak właśnie robi Java.

Jörg W Mittag
źródło
„Jeśli wywołasz funkcję z nowym słowem kluczowym, funkcja ta stanie się konstruktorem, a to słowo kluczowe nie będzie wskazywało na bieżący obiekt, lecz na nowo utworzony„ pusty ”. Jeśli wywołasz funkcję bez nowego słowa kluczowego, odniesie się to do kontekstu wywołania, domyślnie do obiektu globalnego (okno). W trybie ścisłym wartość domyślna to niezdefiniowana. Wywołaj, zastosuj i powiąż kontekst kontekstu jako pierwszy parametr. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Elias Hasle
83

Klasy ES2015

W specyfikacji ES2015 można użyć składni klasy, która jest po prostu cukrem w stosunku do prototypowego systemu.

class Person {
  constructor(name) {
    this.name = name;
  }
  toString() {
    return `My name is ${ this.name }.`;
  }
}

class Employee extends Person {
  constructor(name, hours) {
    super(name);
    this.hours = hours;
  }
  toString() {
    return `${ super.toString() } I work ${ this.hours } hours.`;
  }
}

Korzyści

Główną zaletą jest to, że narzędziom do analizy statycznej łatwiej jest ukierunkować tę składnię. Łatwiej jest również innym osobom pochodzącym z języków klasowych używać języka jako poliglota.

Ostrzeżenia

Uważaj na jego obecne ograniczenia. Aby uzyskać własności prywatne, należy skorzystać z symboli lub słabych map . W przyszłych wydaniach klasy najprawdopodobniej zostaną rozszerzone o te brakujące funkcje.

Wsparcie

Obsługa przeglądarek nie jest w tej chwili zbyt dobra (obsługiwana przez prawie wszystkich oprócz IE), ale możesz teraz korzystać z tych funkcji za pomocą transpilatora takiego jak Babel .

Zasoby

Dołek
źródło
56

Wolę używać Daniela X. Moore'a {SUPER: SYSTEM}. Jest to dyscyplina, która zapewnia korzyści, takie jak zmienne rzeczywistych instancji, dziedziczenie oparte na cechach, hierarchie klas i opcje konfiguracji. Poniższy przykład ilustruje użycie prawdziwych zmiennych instancji, które moim zdaniem są największą zaletą. Jeśli nie potrzebujesz zmiennych instancji i jesteś zadowolony z samych zmiennych publicznych lub prywatnych, prawdopodobnie istnieją prostsze systemy.

function Person(I) {
  I = I || {};

  Object.reverseMerge(I, {
    name: "McLovin",
    age: 25,
    homeState: "Hawaii"
  });

  return {
    introduce: function() {
      return "Hi I'm " + I.name + " and I'm " + I.age;
    }
  };
}

var fogel = Person({
  age: "old enough"
});
fogel.introduce(); // "Hi I'm McLovin and I'm old enough"

Wow, to nie jest zbyt przydatne, ale spójrz na dodanie podklasy:

function Ninja(I) {
  I = I || {};

  Object.reverseMerge(I, {
    belt: "black"
  });

  // Ninja is a subclass of person
  return Object.extend(Person(I), {
    greetChallenger: function() {
      return "In all my " + I.age + " years as a ninja, I've never met a challenger as worthy as you...";
    }
  });
}

var resig = Ninja({name: "John Resig"});

resig.introduce(); // "Hi I'm John Resig and I'm 25"

Kolejną zaletą jest możliwość dziedziczenia modułów i cech.

// The Bindable module
function Bindable() {

  var eventCallbacks = {};

  return {
    bind: function(event, callback) {
      eventCallbacks[event] = eventCallbacks[event] || [];

      eventCallbacks[event].push(callback);
    },

    trigger: function(event) {
      var callbacks = eventCallbacks[event];

      if(callbacks && callbacks.length) {
        var self = this;
        callbacks.forEach(function(callback) {
          callback(self);
        });
      }
    },
  };
}

Przykład posiadania klasy person obejmuje moduł do powiązania.

function Person(I) {
  I = I || {};

  Object.reverseMerge(I, {
    name: "McLovin",
    age: 25,
    homeState: "Hawaii"
  });

  var self = {
    introduce: function() {
      return "Hi I'm " + I.name + " and I'm " + I.age;
    }
  };

  // Including the Bindable module
  Object.extend(self, Bindable());

  return self;
}

var person = Person();
person.bind("eat", function() {
  alert(person.introduce() + " and I'm eating!");
});

person.trigger("eat"); // Blasts the alert!

Ujawnienie: Jestem Daniel X. Moore i to jest moje {SUPER: SYSTEM}. Jest to najlepszy sposób na zdefiniowanie klasy w JavaScript.

Daniel X Moore
źródło
@DanielXMoore „Zmienne instancji są współużytkowane przez poszczególne instancje klasy” To nie są zmienne instancji, to są zmienne statyczne / klasowe.
JAB
2
@JAB Niepoprawne, zmienne statyczne / klasowe są wspólne dla wszystkich instancji klasy. Każda instancja ma własne zmienne instancji.
Daniel X Moore
(Innymi słowy, używając normalnego znaczenia terminu „zmienna instancji”, to, czy zmienna jest zmienną, jest ortogonalna do poziomu dostępności zmiennej).
JAB
2
Prawie zabrzmiałeś jak superbohater, twierdząc, że najlepszy xD
Dadan
Łatwe podejście do zdefiniowania klasy JavaScript za pomocą obiektów javascript: wapgee.com/story/i/203
Ilyas karim
41
var Animal = function(options) {
    var name = options.name;
    var animal = {};

    animal.getName = function() {
        return name;
    };

    var somePrivateMethod = function() {

    };

    return animal;
};

// usage
var cat = Animal({name: 'tiger'});
liammclennan
źródło
Jest to bardzo elegancki sposób na zbudowanie użytecznej struktury obiektu bez konieczności importowania czegokolwiek. Korzystałem z systemu klas Resiga, ale może mi się to bardziej podobać. Dziękuję Ci.
Tim Scollick
29
Problem z tym podejściem polega na tym, że za każdym razem, gdy tworzysz nową instancję Animal, przedefiniuje ona funkcje, a nie zdefiniuje je tylko raz za pomocą prototypu.
Justin
33

Poniżej znajdują się sposoby tworzenia obiektów w javascript, których do tej pory używałem

Przykład 1:

obj = new Object();
obj.name = 'test';
obj.sayHello = function() {
    console.log('Hello '+ this.name);
}

Przykład 2:

obj = {};
obj.name = 'test';
obj.sayHello = function() {
    console.log('Hello '+ this.name);
}
obj.sayHello();

Przykład 3:

var obj = function(nameParam) {
    this.name = nameParam;
}
obj.prototype.sayHello = function() {
    console.log('Hello '+ this.name);
}

Przykład 4: Rzeczywiste zalety Object.create (). sprawdź [ten link]

var Obj = {
    init: function(nameParam) {
        this.name = nameParam;
    },
    sayHello: function() {
        console.log('Hello '+ this.name);
    }
};
var usrObj = Object.create(Obj);  // <== one level of inheritance

usrObj.init('Bob');
usrObj.sayHello();

Przykład 5 (dostosowany obiekt Crockforda. Tworzenie):

Object.build = function(o) {
   var initArgs = Array.prototype.slice.call(arguments,1)
   function F() {
      if((typeof o.init === 'function') && initArgs.length) {
         o.init.apply(this,initArgs)
      }
   }
   F.prototype = o
   return new F()
}
MY_GLOBAL = {i: 1, nextId: function(){return this.i++}}  // For example

var userB = {
    init: function(nameParam) {
        this.id = MY_GLOBAL.nextId();
        this.name = nameParam;
    },
    sayHello: function() {
        console.log('Hello '+ this.name);
    }
};
var bob = Object.build(userB, 'Bob');  // Different from your code
bob.sayHello();


Aby aktualizować odpowiedź za pomocą ES6 / ES2015

Klasa jest zdefiniowana w następujący sposób:

class Person {
    constructor(strName, numAge) {
        this.name = strName;
        this.age = numAge;
    }

    toString() {
        return '((Class::Person) named ' + this.name + ' & of age ' + this.age + ')';
    }
}

let objPerson = new Person("Bob",33);
console.log(objPerson.toString());
Amol M. Kulkarni
źródło
1
@Justin: Daj mi znać, co jest nieważne?
Amol M. Kulkarni,
Studiując te notacje, natknąłem się również na this.set (). Na przykład: this.set („port”, 3000). Domyślam się, że służy to do ustawienia właściwości portu dla obiektu. Jeśli tak, dlaczego nie używamy bezpośrednio: {port: 3000}. Czy jest jakaś dokumentacja, w której mogę uzyskać więcej szczegółów.
adityah
24

Myślę, że powinieneś przeczytać Douglas Crockford Prototypal Inheritance in JavaScript and Classical Inheritance in JavaScript .

Przykłady z jego strony:

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
};

Efekt? Umożliwi to dodanie metod w bardziej elegancki sposób:

function Parenizor(value) {
    this.setValue(value);
}

Parenizor.method('setValue', function (value) {
    this.value = value;
    return this;
});

Polecam także jego filmy: Advanced JavaScript .

Więcej filmów można znaleźć na jego stronie: http://javascript.crockford.com/ W książce Johna Reisiga można znaleźć wiele przykładów ze strony Douglasa Crockfora.

Jarek
źródło
25
Czy to tylko ja? Jak do cholery jest to bardziej eleganckie? Nazwałbym definicje funkcji rzeczywistymi 'strings'jak wiele nazw, ale elegancki nie jest jedną z nich ...
fgysin przywraca Monikę
4
@JAB, ale odbicie jest wyjątkiem, a nie regułą. Przy użyciu powyższej metody musisz zadeklarować wszystkie swoje metody za pomocą ciągów.
Kirk Woll,
16

Ponieważ nie zaakceptuję planu fabryki YUI / Crockford i ponieważ lubię utrzymywać wszystko w spokoju i rozszerzać, oto moja odmiana:

function Person(params)
{
  this.name = params.name || defaultnamevalue;
  this.role = params.role || defaultrolevalue;

  if(typeof(this.speak)=='undefined') //guarantees one time prototyping
  {
    Person.prototype.speak = function() {/* do whatever */};
  }
}

var Robert = new Person({name:'Bob'});

gdzie najlepiej jest przeprowadzić test typu na prototypie pierwszej metody

annakata
źródło
Lubię to. Najczęściej używam standardowej składni JS, ponieważ nie podoba mi się pomysł kopiowania funkcji do każdej instancji obiektu. Zawsze jednak tęskniłem za pięknem samodzielnego rozwiązania i to całkiem dobrze rozwiązuje.
Łukasz Korzybski
1
Nie jestem pewien, ale zrozumiałem, że zdefiniowanie funkcji prototypowej wewnątrz zakresu (nieco jako zamknięcie) funkcji powoduje wyciek pamięci, ponieważ śmieciarz nie może tam dotrzeć w przypadku tych klas.
Sanne
15

Jeśli wybierasz proste, możesz całkowicie uniknąć słowa kluczowego „nowy” i po prostu użyć metod fabrycznych. Czasami wolę to, ponieważ lubię używać JSON do tworzenia obiektów.

function getSomeObj(var1, var2){
  var obj = {
     instancevar1: var1,
     instancevar2: var2,
     someMethod: function(param)
     {  
          //stuff; 
     }
  };
  return obj;
}

var myobj = getSomeObj("var1", "var2");
myobj.someMethod("bla");

Nie jestem jednak pewien, jaka jest wydajność w przypadku dużych obiektów.

Sam
źródło
Linia obj.instancevar1 = var1 nie jest konieczna, ponieważ wewnętrzny obiekt będzie miał dostęp do parametrów getSomeObj ().
Tryptyk
Łał. Boli mnie mózg, ale ma w sobie pewną elegancję. Więc część „obj.instancevar1 = var1” jest początkiem pewnego rodzaju konstruktora, tak sądzę?
Karim
Właśnie zobaczyłem komentarz Tryptyka. Widzę. Więc możesz po prostu zrobić coś takiego jak „instancevar1: var1”, gdzie tworzony jest obiekt wewnętrzny.
Karim
Dokładnie ... kiedy użyjesz {} do zdefiniowania obiektu, ma on dostęp do zmiennych, które są obecnie w zasięgu.
Sam
10
Dzięki takiemu podejściu tracisz możliwość dziedziczenia, a ponieważ nie używasz obj.prototype.something, definiujesz funkcje za każdym razem, gdy używasz obiektu = więcej pamięci i wolniej.
jakieś
12
var Student = (function () {
    function Student(firstname, lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.fullname = firstname + " " + lastname;
    }

    Student.prototype.sayMyName = function () {
        return this.fullname;
    };

    return Student;
}());

var user = new Student("Jane", "User");
var user_fullname = user.sayMyName();

W ten sposób TypeScript kompiluje klasę z konstruktorem do JavaScript.

Mick
źródło
10

Prosty sposób to:

function Foo(a) {
  var that=this;

  function privateMethod() { .. }

  // public methods
  that.add = function(b) {
    return a + b;
  };
  that.avg = function(b) {
    return that.add(b) / 2; // calling another public method
  };
}

var x = new Foo(10);
alert(x.add(2)); // 12
alert(x.avg(20)); // 15

Powodem thatjest to, że thismożna powiązać z czymś innym, jeśli podasz metodę jako procedurę obsługi zdarzeń, więc zapiszesz wartość podczas tworzenia wystąpienia i użyjesz jej później.

Edycja: zdecydowanie nie jest to najlepszy sposób, tylko prosty sposób. Czekam też na dobre odpowiedzi!

orip
źródło
1
Konstrukcja that = ta konstrukcja nie jest tutaj konieczna. Ponadto metody add () i avg () zostaną skopiowane dla każdego „wystąpienia” klasy Foo, zamiast dzielone między nimi.
Tryptyk
1
Czy w takim przypadku jest to konieczne (sorta), ale nie jest to prosta sprawa, którą podałeś.
Tryptyk
9

Prawdopodobnie chcesz utworzyć typ za pomocą wzoru składania:

    // Here is the constructor section.
    var myType = function () {
        var N = {}, // Enclosed (private) members are here.
            X = this; // Exposed (public) members are here.

        (function ENCLOSED_FIELDS() {
            N.toggle = false;
            N.text = '';
        }());

        (function EXPOSED_FIELDS() {
            X.count = 0;
            X.numbers = [1, 2, 3];
        }());

        // The properties below have access to the enclosed fields.
        // Careful with functions exposed within the closure of the
        // constructor, each new instance will have it's own copy.
        (function EXPOSED_PROPERTIES_WITHIN_CONSTRUCTOR() {
            Object.defineProperty(X, 'toggle', {
                get: function () {
                    var before = N.toggle;
                    N.toggle = !N.toggle;
                    return before;
                }
            });

            Object.defineProperty(X, 'text', {
                get: function () {
                    return N.text;
                },
                set: function (value) {
                    N.text = value;
                }
            });
        }());
    };

    // Here is the prototype section.
    (function PROTOTYPE() {
        var P = myType.prototype;

        (function EXPOSED_PROPERTIES_WITHIN_PROTOTYPE() {
            Object.defineProperty(P, 'numberLength', {
                get: function () {
                    return this.numbers.length;
                }
            });
        }());

        (function EXPOSED_METHODS() {
            P.incrementNumbersByCount = function () {
                var i;
                for (i = 0; i < this.numbers.length; i++) {
                    this.numbers[i] += this.count;
                }
            };
            P.tweak = function () {
                if (this.toggle) {
                    this.count++;
                }
                this.text = 'tweaked';
            };
        }());
    }());

Ten kod da ci typ o nazwie myType . Będzie miał wewnętrzne pola prywatne o nazwie przełączanie i tekst . Będzie także miał tych odsłoniętych członków: liczba pól i liczby ; przełącznik właściwości , tekst i liczba Długość ; metody incrementNumbersByCount i tweak .

Wzór składania jest szczegółowo opisany tutaj: Wzór składania Javascript

intrepidis
źródło
3

Golf kod dla użytkownika @ liammclennan odpowiedź .

var Animal = function (args) {
  return {
    name: args.name,

    getName: function () {
      return this.name; // member access
    },

    callGetName: function () {
      return this.getName(); // method call
    }
  };
};

var cat = Animal({ name: 'tiger' });
console.log(cat.callGetName());

tponthieux
źródło
2

MooTools (My Object Oriented Tools) koncentruje się na idei klas . Możesz nawet rozszerzyć i wdrożyć z dziedziczeniem.

Po opanowaniu tworzy absurdalnie potężny javascript.

Ryan Florence
źródło
2

Klasy obiektowe z dziedziczeniem

var baseObject = 
{
     // Replication / Constructor function
     new : function(){
         return Object.create(this);   
     },

    aProperty : null,
    aMethod : function(param){
      alert("Heres your " + param + "!");
    },
}


newObject = baseObject.new();
newObject.aProperty = "Hello";

anotherObject = Object.create(baseObject); 
anotherObject.aProperty = "There";

console.log(newObject.aProperty) // "Hello"
console.log(anotherObject.aProperty) // "There"
console.log(baseObject.aProperty) // null

Proste, słodkie i gotowe.

Ulad Kasach
źródło
1

Baza

function Base(kind) {
    this.kind = kind;
}

Klasa

// Shared var
var _greeting;

(function _init() {
    Class.prototype = new Base();
    Class.prototype.constructor = Class;
    Class.prototype.log = function() { _log.apply(this, arguments); }
    _greeting = "Good afternoon!";
})();

function Class(name, kind) {
    Base.call(this, kind);
    this.name = name;
}

// Shared function
function _log() {
    console.log(_greeting + " Me name is " + this.name + " and I'm a " + this.kind);
}

Akcja

var c = new Class("Joe", "Object");
c.log(); // "Good afternoon! Me name is Joe and I'm a Object"
Mikael Dúi Bolinder
źródło
1

Na przykładzie Tryptyku może to być jeszcze prostsze:

    // Define a class and instantiate it
    var ThePerson = new function Person(name, gender) {
        // Add class data members
        this.name = name;
        this.gender = gender;
        // Add class methods
        this.hello = function () { alert('Hello, this is ' + this.name); }
    }("Bob", "M"); // this instantiates the 'new' object

    // Use the object
    ThePerson.hello(); // alerts "Hello, this is Bob"

Tworzy to tylko instancję pojedynczego obiektu, ale nadal jest przydatne, jeśli chcesz zawrzeć grupę nazw zmiennych i metod w klasie. Zwykle do konstruktora nie byłyby argumenty „Bob, M”, na przykład, gdyby metody były wywołaniami systemu z własnymi danymi, takimi jak baza danych lub sieć.

Nadal jestem zbyt nowy w JS, żeby zrozumieć, dlaczego to nie wykorzystuje prototype.

Roland
źródło
0

JavaScript jest zorientowany obiektowo , ale radykalnie różni się od innych OOP języków , takich jak Java, C # lub C ++. Nie próbuj tego tak rozumieć. Wyrzuć tę starą wiedzę i zacznij od nowa. JavaScript wymaga innego myślenia.

Sugerowałbym, aby uzyskać dobry podręcznik lub coś na ten temat. Sam uważam, że samouczki ExtJS są dla mnie najlepsze, chociaż nie korzystałem z frameworka przed ani po jego przeczytaniu. Ale daje dobre wyjaśnienie tego, co jest w świecie JavaScript. Przepraszamy, ta treść została usunięta. Oto link do archiwum.org zamiast tego. Działa dzisiaj. : P

Vilx-
źródło
2
Obiektowy? Myślałem, że to działa .
Peter Mortensen
Link „Samouczki ExtJS” jest uszkodzony.
Peter Mortensen
Wydaje mi się, że bardziej objaśniające byłoby wyjaśnienie, że funkcje w javascript są obiektami, a reguły javascript o zakresie nawiasów powodują enkapsulację każdego bloku funkcji.
mibbit
-1

//new way using this and new
function Persons(name) {
  this.name = name;
  this.greeting = function() {
    alert('Hi! I\'m ' + this.name + '.');
  };
}

var gee=new Persons("gee");
gee.greeting();

var gray=new Persons("gray");
gray.greeting();

//old way
function createPerson(name){
 var obj={};
 obj.name=name;
 obj.greeting = function(){
 console.log("hello I am"+obj.name);
 }; 
  return obj;
}

var gita=createPerson('Gita');
gita.greeting();

Avinash Maurya
źródło