簡體   English   中英

JavaScript中的var thing和function thing()有什么區別?

[英]What is the difference between var thing and function thing() in JavaScript?

我只是想知道以下JavaScript對象聲明之間的區別。 具體來說,事物類中的事物對象文字和事物1對象之間的區別。

碼:

var thing = {
    sanity:0,
    init:function(){
        //code
    },
    send:function(){
        //code
    }
}

function thing(){
    this.sanity = 0;
    this.init = function(){
        //code
    };
    this.send = function(){
        //code
    };
}

thing1 = new thing();

靜態對象/對象文字

靜態對象或對象文字不需要使用new運算符進行實例化,也可以像單例一樣運行。 請考慮以下示例:

碼:

var staticObject1 = {
 a: 123,
 b: 456
};
var staticObject2 = staticObject1;
console.log(staticObject1, staticObject2);
staticObject2.b = "hats";
console.log(staticObject1, staticObject2);

輸出:

Object a=123 b=456  Object a=123 b=456
Object a=123 b=hats Object a=123 b=hats

請注意,更改staticObject2.b也會影響staticObject1.b 然而,這可能並不總是期望的效果。 許多庫(如Dojo )提供了一種對象克隆方法,如果要復制靜態對象,可以緩解這種情況。 繼續前面的示例,請考慮以下事項:

碼:

var staticObject3 = dojo.clone(staticObject1); // See the doc in the link above
staticObject1.a = "pants";
console.log(staticObject1, staticObject2, staticObject3);

輸出:

Object a=pants b=hats Object a=pants b=hats Object a=123 b=hats

請注意, staticObject1staticObject2的成員的值是相同的,而staticObject3不受對這些其他對象的更改的影響。

靜態對象對於創建項目或庫命名空間也很有用,而不是填滿全局范圍,並提升兼容性,就像沒有人的業務一樣。

在創建需要可移植性或互操作性的庫時,這非常有用。 這可以在流行的庫中看到,例如Dojo,YUI和ExtJs,其中所有或大多數方法分別被稱為dojo.examplMethod()YUI().exampleMethod() Ext.exampleMethod()Ext.exampleMethod()

靜態對象也可以被認為與C / C ++中的struct類似。

類構造函數/實例化對象

JavaScript中的類基於原型繼承,這是一個更復雜的主題,可以在這里這里這里閱讀

與靜態對象相反,由於JavaScript的closuer屬性,這種對象創建方法為私有范圍對象成員和方法提供了獨特的機會。 請考慮以下私有類成員示例:

碼:

var SomeObject = function() {
    var privateMember = "I am a private member";
    this.publicMember = "I am a public member";

    this.publicMethod = function() {
        console.log(privateMember, this.publicMember);
    };
};

var o = new SomeObject();
console.log(typeof o.privateMember, typeof o.publicMember);
o.publicMethod();

輸出:

undefined string
I am a private member I am a public member

請注意, typeof o.privateMember是“未定義的”,不能在對象外部訪問,但是來自內部。

也可以制作私有方法,但不是那么簡單,但仍然很容易實現。 問題在於,值this私有方法默認的內部window和兩種技術之一必須應用,以確保this指的是我們中工作,在這種情況下,對象實例SomeObject 請考慮以下示例:

碼:

var SomeObject = function() {
    var privateMember = "I am a private member";
    var privateMethod = function() {
        console.log(this.publicMember);
    };

    this.publicMember = "I am a public member";
    this.publicMethod = function() {
        console.log(privateMember, this.publicMember);
    };
    this.privateMethodWrapper = function() {
        privateMethod.call(this);
    }
};

var o = new SomeObject();
console.log(typeof o.privateMethod, typeof o.publicMethod, typeof o.privateMethodWrapper);
o.privateMethodWrapper();

輸出:

undefined function function
I am a public member

請注意,withing privateMethodWrapper() privatemethod使用執行call和傳遞this對函數的上下文。 這一切都很好; 但是,以下技術是優選的(在我看來),因為它簡化了調用范圍並產生相同的結果。 上一個示例可以更改為以下內容:

碼:

var SomeObject = function() {
    var self          = this;
    var privateMember = "I am a private member";
    var privateMethod = function() {
        console.log(self.publicMember);
    };

    this.publicMember = "I am a public member";
    this.publicMethod = function() {
        console.log(privateMember, this.publicMember);
    };
    this.privateMethodWrapper = function() {
        privateMethod();
    }
};

var o = new SomeObject();
console.log(typeof o.privateMethod, typeof o.publicMethod, typeof o.privateMethodWrapper);
o.privateMethodWrapper();

輸出:

undefined function function
I am a public member

這個答案是我博客上帖子的基礎,我在這里給出了更多的例子。 希望有所幫助;)

案例2引用了javascript 類構造函數 一個明顯的區別是變量還不是一個對象,所以你不能在內部引用thing1.sanity。 您必須在調用任何內部成員之前通過創建所述類的實例來初始化該類:

var myConstructor = function() {
    this.sanity = 0;
}

// wont work
alert(myConstructor.sanity);

// works
var thing1 = new myConstructor();
alert(thing1.sanity);

這篇文章比我的快速示例更深入:

類構造函數與對象文字

不同之處在於thing1對象與thing1類相關聯,並且將繼承(不是字面上) thing1原型。

例如,您可以稍后寫

thing.prototype.initAndSend = function() { this.init(); this.send(); };

然后,您將能夠編寫thing1.initAndSend()而無需修改thing1 另外, thing1.constructor將等於thing方法,而{}.constructor等於Object

順便說一句,標准慣例是大寫類名。

使用第一種方法,您將聲明一個對象。 對於第二個,您將聲明一個類,您可以從中實例化(即創建)許多不同的副本。

函數是對象和構造函數(您可以使用new實例化它們)。

散列表/對象( {} )無法實例化,因此它們通常用作數據結構。 我不太確定將它們稱為“物體”是否明智。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM