2012-07-13 113 views
4

我發現在JavaScript中很難理解OOP。JavaScript OOP類和聲明

通常我會希望創建一個類,然後從該類創建對象。

但是,根據一個教程,以下內容會產生一個對象。

var egg = {} 

難道我沒有做過一個名爲egg的對象,但實際上沒有上課。

如果那是我會怎麼做,從一個對象的多個對象的情況:S

而且根據不同的教程的對象是由像下面,這是完全的區別是什麼,我上面說:S

var Block = function(){ 

} 

誰能幫我解開我的困惑:(

+0

[構造函數和對象之間的差異]可能的重複(http://stackoverflow.com/questions/4559207/difference-between-a-constructor-and-an-object) – qwertymk 2012-07-13 22:16:49

+0

但這樣做不會毀掉整個點OOP? – 2012-07-13 22:17:33

+0

btw。你在'var Block = ...'語句中缺少一個新的東西 – 2012-07-13 22:23:22

回答

2

JavaScript是與迄今爲止學到的不同的語言。你不能指望事情和你改變語言時一樣。

快速偷看:在JavaScript中,您可以將一個函數分配給一個變量。我敢打賭,你已經使用其它語言,這是不可能的:

var myCounter = 1; 
var myFunction = function(x){ return x + 1; }; 

再回到你的問題:在javascript中有沒有「真正的類」。只有對象。我知道這聽起來可能聽起來很混亂。

Javascript的對象模型被稱爲「原型繼承」。它不同於「經典」(雙關意圖)的繼承。而且它也是not very cleanly implemented。基本上,你從一個縮小的對象集合(數組,對象,而不是類)開始,然後使用這些對象來構建其他對象。他們之間的關係可以是「類和實例」,但他們不必這樣做。他們也可以是其他種類的關係。

由於沒有類,所以不能創建它們。但是你可以創建一個常規的對象,將它分配給變量Car,並且只是想「我要用這個對象來創建很多其他對象,而其他對象默認會有一些屬性,比如方法和東西,讓他們表現得像汽車一樣「。語言允許你這樣做。汽車將像其他語言中的類一樣行事,它產生的對象將「像汽車的實例」一樣。

但是,對於javascript來說,它們看起來像是一些對象,它們之間有一些關係。

從某種意義上說,原型繼承是經典繼承的「超集」。你可以做經典的繼承,但也可以做其他事情。

2

有我不只是做一個指定的對象不蛋居然作出 類。

沒錯。所有你在做的是實例化基地Object對象 - 你還沒有做任何事情,你可以使的實例。

在JavaScript中,沒有形式化的類概念 - 僅僅通過實例化而不是調用函數來實現它們的模擬。

function Animal() { this.animal = true; } 
Animal.prototype.sayHi = function() { alert(this.name+' says hi!'); } 
function Dog(name) { this.name = name; } 
Dog.prototype = new Animal(); 
... 
var fido = new Dog('Fido'); 
fido.sayHi(); //"Fido says hi!"; 

注意第4行只是模擬繼承的幾種方法之一。

所以在JavaScript中,類和函數都只是函數。沒有任何固有的東西可以防止用於實例化的函數在沒有new運算符的情況下被調用,反之亦然。

在前一種情況下,常見的解決方法是檢查構造是「類」(如果調用並沒有實例化,構造函數會Object)和重新路由的必要:

function Dog(name) { 
    //if we weren't instantiated, the constructor will be Object, not Dog 
    if(this.constructor != Dog) return new Dog(name); 
    this.name = name; 
} 
var fido = Dog(); //bad - invocation should be instantiation 
+1

這是最簡單的,儘管是一種天真的方式,它需要實例化基礎對象才能設置原型鏈。足以回答這個問題。我寫了一篇關於在JS中構成正確繼承的文章。 http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html – 2012-07-13 22:31:17

+0

你說得很對,胡安 - 這絕對是實現繼承的幾種方法中最簡單的方法(它們都不是完美,都有特色)。我將它包含在這裏,以免混淆答案的主要觀點。我會檢查你的帖子。 – Utkanos 2012-07-13 22:38:42

+0

我其實也寫了關於緩解調用構造函數時沒有新運算符的問題:) http://js-bits.blogspot.com/2010/08/constructors-without-using-new.html似乎是什麼你在做這個測試。構造函數' – 2012-07-13 23:19:54

2

var egg = {}是一個對象,但它不是一個對象的實例。

在JavaScript中,簡單地說這種方式基本上是js的單例的概念,意味着它正是它的意思。

//this is a js singleton, and all properties of this object are public. 
var egg = { 
    name: 'humpty', 
    smush: function() { console.log('splat!'); }, 
    weight: '4oz' 
}; 
console.log(egg.weight); //4oz 

而,較傳統型對象將被使得它的功能,然後可以實例化:

var Egg = function(name, weight) { 
    var name = name; 
    this.smush = function() { console.log('splat!'); } 
    this.weight = weight; 
}; 
var e2 = new Egg('dumpty','6oz'); 
console.log(e2.name); //will not return name. (since i wrote var name and not this.name, its "private" and thus cannot be accessed.) 
console.log(e2.weight); //4oz 
+0

「未定義,因爲我們有範圍」是什麼意思?你從未分配過'this.name = name'。另外,爲什麼當已經有一個(參數)時創建一個局部變量名稱。回答這個問題,但它不是很清楚 – 2012-07-13 23:17:43

+0

哦,我只是做了一個說明,在我們的Egg()對象中,你可以通過區分var x和this.x來阻止僅僅是公開的事情......我將重寫它更清楚 – Kristian 2012-07-14 00:21:37

10

的上述兩個實例都是正確的。把它簡單地放在JavaScript中是一個對象。類不存在,但有很多方法可以模仿它們。我最喜歡的方法如下:現在

var myClass = function() { <----------------------------- class declaration 

      var prop1, 
       prop2, <------------------------------------ private properties 
       prop3; 

      var addMe = function(arg1, arg2) { <------------ private method 
       var result = arg1 + arg2; 
       return result; 
      } 

      var obj = { <------------------------------------- constructor method 
       Prop1: prop1, 
       Prop2: value2, <----------------------------- public properties 
       Prop3: value3, 

       Method: function() { <------------------------ public method 
        obj.prop3 = obj.prop1 + obj.prop2; 
        return obj.prop3; 
       } 
      } 

      obj.Prop4 = addme(prop1, prop2); <-------------- public property set 
                   with the private method 
      return obj; 
    } 

    var myClassObj = new myClass; 

myClassObj是MyClass的一個對象有四個公共屬性 PROP1,PROP2,Prop3,Prop4和一個叫方法