2013-07-08 17 views
34

Zastanawiam się - jaka jest różnica między obiektami JavaScript, klasami i funkcjami? Czy mam rację sądząc, że klasy i funkcje są typami obiektów?Object vs Class vs Function

Co odróżnia klasę od funkcji? Czy naprawdę są one tym samym, tylko termin dla nich zmienia się w zależności od tego, w jaki sposób są one używane?

function func() { alert('foo'); } // a function 
func(); // call the function - alerts 'foo' 
var func2 = function() { alert('hello'); } // acts the same way as 'func' surely? 
func2(); // alerts 'hello' 

var Class = function() { alert('bar'); }; // a class 
var c = new Class(); // an istance of a class - alerts 'bar' 

Jasne, klasy mają metody i właściwości i może być instancja - ale wtedy mogłem zrobić to samo z byle funkcji - czy nie?

+29

Brak zajęcia w JavaScripcie. – Joe

+8

Niedawno wprowadzono w ECMA 6 klasy: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes –

+1

Klasy są obecnie powszechne w wielu bibliotekach post node.js Javascript itp. Nie jest już właściwe mówienie * nie ma klas w Javascript *. Istnieją teraz klasy, które nie są jeszcze dobrze obsługiwane przez implementacje przeglądarek (jeszcze), ale w wieku klas NPM i Node.js są bardzo podstawową koncepcją języka, który posuwa się naprzód (to wszystko jest tylko FYI, które doceniam w tym czasie napisania pierwszego komentarza tutaj było poprawne). – Liam

Odpowiedz

33

Jak już trzeba mieć świadomość już nie ma zajęcia w JavaScripcie. Zamiast tego funkcje w kodzie JavaScript mogą być zachowywane jak konstruktory poprzedzając wywołanie funkcji za pomocą słowa kluczowego new. Jest to znane jako constructor pattern.

W JavaScript wszystko jest obiektem, z wyjątkiem pierwotnych typów danych (boolean, number i string) oraz undefined. Z drugiej strony, null jest w rzeczywistości odniesieniem do obiektu, chociaż może się wydawać na początku inaczej. Z tego powodu typeof null zwraca "object".

Funkcje JavaScript są podobne do funkcji w Lua (tj. Są to obiekty wywoływalne). Dlatego też zamiast obiektu można użyć funkcji. Podobnie tablice są również obiektami JavaScript. Z drugiej strony obiekty mogą być traktowane jako tablice asocjacyjne.

Najważniejsze jest jednak to, że w JavaScript nie ma klas, ponieważ JavaScript jest prototypowym językiem zorientowanym obiektowo. Oznacza to, że obiekty w JavaScript bezpośrednio dziedziczą z innych obiektów. Dlatego nie potrzebujemy klas. Wszystko, czego potrzebujemy, to sposób na tworzenie i rozszerzanie obiektów.

Czytaj wątku Więcej informacji na temat spadku prototypal w JavaScript: Benefits of prototypal inheritance over classical?

+0

Dziękuję bardzo za odpowiedź! Czytałem na ten temat i myślę, że rozumiem to teraz.A więc radzisz użyć wzoru prototypowego ponad wzorcem konstruktora? –

+1

@SeanBone: Radzę nauczyć się wzoru prototypowego przed poznaniem wzorca konstruktora, ponieważ ułatwia to zrozumienie prototypowego dziedziczenia. Jednak wzorzec konstruktora jest szybszy niż wzorzec prototypowy w JavaScript. Dlatego jeśli chcesz napisać kod krytyczny dla wydajności, użycie wzorca konstruktora ma więcej sensu. Mimo to prototypowy wzór jest wciąż dość szybki i można być pewnym, że prawie nigdy nie będziesz potrzebował dodatkowego zwiększenia wydajności. Tłumacze JavaScript świetnie sobie radzą z optymalizacją kodu. Dlatego większość czasu powinieneś trzymać się wzoru prototypowego. –

+0

@AaditMShah Chciałbym poprawić ciebie na 'W JavaScript wszystko jest obiektem z wyjątkiem pierwotnych typów danych (boolean, number i string)'. W JavaScript 'boolean, number i string' zaczyna się od wielkich liter takich jak' Boolean, Number i String'. I ostatecznie wszystkie są dziedziczone po 'Object'. Wszystko w JavaScript oprócz 'undefined' dziedziczy po' Object' (na końcu łańcuchem dziedziczenia conajmniej). – bits

7

JavaScript nie ma klas, a funkcje są w rzeczywistości obiektami JavaScript (pierwszorzędni obywatele). Jedyna różnica między obiektami funkcji polega na tym, że są one na żądanie.

function func() { alert('foo'); } // a function - Prawidłowe

func(); // call the function - alerts 'foo' - Prawidłowe

var func2 = function() { alert('foo'); } // same as 'func' surely? - Nie, func2 jest inny obiekt, który najwyraźniej robi to samo, kiedy dzwonił. Jest to funkcja bez nazwy zapisanej w zmiennej Class.

var c = new Class(); - Funkcja połączeń zapisana w Class dostarczająca nowy pusty obiekt jako this i zwracająca ten obiekt. Funkcje nazwane jako new functionA() powinny działać jako konstruktorzy i przygotować nowo utworzony obiekt (this). W twoim przypadku - konstruktor nie robi nic z obiektem i po prostu ostrzega bar.

+2

Powinieneś wyjaśnić ostatnie zdanie. – adrianp

3

Nie ma klas w javascript. Istnieją jednak sposoby, aby funkcja zachowywała się jak klasa w innych językach.

Bardzo dobre wyjaśnienie znajduje się tutaj 3 way to define a class in js

Również znalazłem bardzo dobre referencje dla OOP in Javascript

+0

Od ECMAScript 2015 tam ** są ** klasy w JavaScript – Liam

2

obiektu jest typu baza w JavaScript to znaczy wszystkie typy danych określonych przez użytkownika dziedziczy obiekt w taki czy inny sposób. Jeśli więc zdefiniujesz funkcję lub klasę [notatka jak na razie JS nie obsługuje konstrukcji klasowej, ale jest ona proponowana w ECMAScript w wersji 6], domyślnie dziedziczy po typie Object.

Klasy są w rzeczywistości używane do enkapsulacji funkcji logicznych i właściwości do jednego typu/encji i można je "nowe" za pomocą składni konstruktora. Jeśli więc zdefiniujesz klasę "Klient", możesz utworzyć instancję wiele razy, a każda instancja/obiekt może mieć różne wartości. Mogą nawet udostępniać wartości, jeśli zdefiniujesz wartość klasy na podstawie prototypu.

Ponieważ JS obecnie nie obsługuje konstrukcji klas, funkcje mogą rzeczywiście działać zarówno jako metoda indywidualna, jak i jako kontener dla innych funkcji lub typów.

Mam nadzieję, że z ECMAScript 6 będziemy mieli wyraźne rozgraniczenie między tymi konstruktami podobnymi do tego, co mamy w innych językach takich jak C#, Java itp

+0

Rodzaje prymitywne nie dziedziczą. Dlatego są nazywane prymitywnymi. – zeroflagL

+0

Dzięki za wyjaśnienia. Zaktualizowałem odpowiedź. –

11

klasę w JS:

function Animal(){ 

    // Private property 
    var alive=true; 

    // Private method 
    function fight(){ //... } 

    // Public method which can access private variables 
    this.isAlive = function() { return alive; } 

    // Public property 
    this.name = "Joe"; 
} 

// Public method 
Animal.prototype.play = function() { alert("Bow wow!"); } 

// .. and so on 

Teraz, kiedy stwórz jego obiekt

var obj = new Animal(); 

Możesz spodziewać się czegokolwiek z tego obiektu, jak z przedmiotów w innym języku. Tylko wysiłki, aby to osiągnąć, były nieco inne. Powinieneś także przyjrzeć się inheritance in JS.


Wracając też pytanie, będę ją przeredagować jak:

Class : A representation of a set with common properties. 
object : One from the set with the same properties. 


var Class = function() {alert('bar');}; // A set of function which alert 'bar' 
var object = new Class();    // One of the functions who alert's 'bar'. 
+0

Programowanie oparte na prototypach nie jest "sposobem, w jaki ludzie dowiedzą się naśladować praktyki zorientowane obiektowo". Jest ** jednym ze sposobów programowania obiektowego, wymyślonego na długo przed JavaScriptem i alternatywą dla programowania opartego na klasach. – zeroflagL

+0

@zeroflagL Mój zły, myliłem się, aby stwierdzić, że wcześniej. – loxxy

20

Aktualizacja 2015

Są zajęcia w javascript oni po prostu nie są stosowane w starszych przeglądarkach. enter image description here

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

Ma konstruktorów extentions i tym podobne.

class Cat { 
    constructor(name) { 
    this.name = name; 
    } 

    speak() { 
    console.log(this.name + ' makes a noise.'); 
    } 
} 

class Lion extends Cat { 
    speak() { 
    super.speak(); 
    console.log(this.name + ' roars.'); 
    } 
} 
+0

Dziękujemy za zaktualizowaną odpowiedź! – Mintberry

+2

Myślę, że ważne jest, aby nie używać nowych klas konstruktorów do najnowszej wersji JavaScript, więc są one obsługiwane tylko jako takie, a są tylko nową składnią, w rzeczywistości są funkcjami, które zostały zaprojektowane jako syntaktyczny cukier, aby kod był lepiej zorganizowany nie działają inaczej niż konstruktory funkcji. – Binvention

+0

Nadal nie są to "klasy" w klasycznym znaczeniu dziedziczenia, lecz jedynie cukier syntaktyczny używany do łączenia obiektów powiązanych z innymi obiektami (OLOO) w sposób zbliżony do zachowania klasycznego dziedziczenia. W JavaScript nie ma klas pomimo słowa kluczowego, które daje ci to złudzenie. – codemagician

0

również uzyskać zajęcia w ES6 które wyglądają tak:

//class 
class Cat { 
    //constructor 
    constructor() { 
     this.name = 'Snowball'; 
    } 

    //method 
    meow() { 
     console.log('Hello, nyah! My name is ' + this.name + ' nyah!~'); 
    } 
}; 
+0

ta metoda wymaga "funkcji", prawda? – sorak

+0

@sorak już nie, zobacz https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions – StaticBeagle