簡體   English   中英

使用'new'創建對象時使用'return'

[英]Using 'return' when creating objects with 'new'

我今天發現了一些非常奇怪的事情:如果使用構造函數和new關鍵字創建對象,但是從構造函數return一個函數,它的行為如下:

  1. 新創建的“對象”是一個函數。
  2. 可以像平常一樣調用新函數,但是......
  3. 如果你保持一個參考this在構造函數, this引用正確從構造函數創建的對象。 這是你期望new回報。

這是一個例子:

function Constructor() {
  var self = this;

  this.name = 'instance';
  return function() {
    return self;
  }
}

因此,如果您像這樣實例化它: var instance = new Constructor()以下結果:

typeof instance    //returns "function"
typeof instance()  //returns "object"
instance()         //returns { name: 'instance' }

所以我猜我有三個問題:

  1. 這是合法的,它是否跨瀏覽器工作? 它真的很棒,我認為它可以在很多方面使用,但這種行為是否可靠?
  2. 導致此行為的后台會發生什么?
  3. (可能由2回答,但是......)新實例中是否有新對象(以'this'引用的對象),所以它都是自包含的並且被垃圾收集器正確清理了?
  1. 是的,當一個構造函數默認返回正在建造新的對象(被引用this ),你可以只要你返回一個對象將覆蓋返回值。 因為函數是一個對象,所以您可以像在示例中一樣返回它。 新創建的對象本身不是函數,但返回的函數在其變量作用域中引用新創建的對象。

  2. 見#1

  3. 這是因為函數創建了一個閉包,因此它繼續引用self變量,該變量恰好引用了正在構造的實際對象。 所以我不會說它在“內部”任何東西,而只是函數變量范圍的一部分。

要理解的是,您的功能與任何其他功能沒有任何不同。 就像你已經返回一個數組一樣,你只需要一個可以引用新對象的常規數組。

function Constructor() {

  this.name = 'instance';
  return [ this ];  // Instead return an Array that references the new object
}

嗯,這是一個非常好的問題,正如你可能已經猜到的那樣,不容易回答。

簡單地說:
1)是和是; 這是“傳統”編程語言中沒有的令人驚嘆的功能之一。
2)請閱讀關閉(下面的鏈接)
3)是(請閱讀更多)

您應該閱讀有關Javascript Closures的更多信息: http//jibbering.com/faq/notes/closures/
http://www.javascriptkit.com/javatutors/closures.shtml (這里有一些很好的工作示例)

更具體地說,寄生遺傳模型:
http://blog.higher-order.net/2008/02/21/javascript-parasitic-inheritance-power-constructors-and-instanceof/

我希望這有幫助

這就是你所說的閉包

它的作用是創建一個獨立的代碼環境(通常稱為對象)

typeof instance    //returns "function" - since it's not "fired" or called. just returns the function declaration (correct me if i'm wrong)
typeof instance()  //returns "object" - it returns an object since you called it
instance()         //returns an object also - you called it, but you didn't store it

使用閉包構建的對象的示例:

function Constructor() {
    var privateProperty = 'private';
    var privateMethod = function(){
        alert('called from public method');
    };

    //return only what's to be seen in public
    return {
        publicProperty: 'im public',
        publicMethod: function(){
            alert('called from public method');
        }
        getter: privateMethod //assign to call the private method
    }
}

var myObj = Constructor();
var pubProp = myObj.publicProperty; // pubProp = 'im public'
myObj.publicMethod()                //alert: 'called from public method';
myObj.getter()                      //alert: 'called from public method';

//cannot access since "private":
myObj.privateProperty
myObj.privateMethod

暫無
暫無

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

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