javaScript構造函數顯式提供返回值

最近再看jQuery源碼時,發現了一個這樣有趣的事。javascript

看下面一段代碼:java

 

 

var jquery = function () {

    // return new jquery.fn.init();
    // return new Object();
    // return 'a'
    // return {a:1}
};

jquery.fn = jquery.prototype = {
    constructor: jquery
};

jquery.fn.init = function () {
};

jquery.fn.init.prototype = jquery.fn;

var a = new jquery();
console.log(a);

 輸出結果以下:jquery

這和咱們預期相符,a應該是jquery的一個實例,下面引用一段高程的原話。函數

要建立一個構造函數的新實例,必須使用new操做符。以這種方式調用構造函數實際上會經歷如下4個步驟:this

  1. 建立一個新對象
  2. 將構造函數的做用域賦給新對象(所以this就指向了這個新對象)
  3. 執行構造函數中的代碼(爲這個新對象添加屬性)
  4. 返回新對象

因此使用new操做符調用構造函數(其實函數以前並無區別,所謂構造函數也只是由於使用的是new操做符調用而已),若是構造函數沒有顯式返回值,則會返回一個構造函數的實例。那麼問題來了,若是構造函數顯示的提供了返回值呢?看下面的代碼:spa

var jquery = function () {

    // return new jquery.fn.init();
    // return new Object();
    return 'a'
    // return {a:1}
};

jquery.fn = jquery.prototype = {
    constructor: jquery
};

jquery.fn.init = function () {
};

jquery.fn.init.prototype = jquery.fn;

var a = new jquery();
console.log(a);

這裏咱們顯示的返回了一個字符串'a',可是發現a依然是jquery的一個實例prototype

再換種狀況:3d

var jquery = function () {

    // return new jquery.fn.init();
    // return new Object();
    // return 'a'
    return {a:1}
};

jquery.fn = jquery.prototype = {
    constructor: jquery
};

jquery.fn.init = function () {
};

jquery.fn.init.prototype = jquery.fn;

var a = new jquery();
console.log(a);

此次咱們返回的是一個對象,而後經過new操做符調用以後發現,a再也不是jquery的實例了,而是咱們指定的對象。code

通過反覆試驗和查閱資料,得出結論:htm

在javaScript中,若是在構造函數中顯式的返回了複雜的對象時,此時使用new操做符調用構造函數將返回構造函數中指定的對象;當構造函數中顯示返回的是相似於字符串和數字時,此時使用new操做符調用構造函數將返回構造函數的實例化對象。

這是javaScript語言的一個奇怪的特徵,但有些時候這個特徵確實有用。

好比說著名的jQuery中就用到了這個特性:

看下面這段代碼:

"use strict";

var jquery = function () {
    return new jquery.fn.init();
};

jquery.fn = jquery.prototype = {
    constructor: jquery
};

jquery.fn.init = function () {
};

jquery.fn.init.prototype = jquery.fn;

var a = new jquery();
var b = jquery();
console.log(a);
console.log(b);

咱們會發現,對於jquery這個函數,無論是用new操做符調用仍是不用new操做符調用,其返回值都是同樣的,這就得益於上面所提到了javaScript的這個古怪的特性了。

這樣一來你就不用每次使用jQuery的時候,都須要new $('#id')了,由於new $('#id')和$('#id')返回值是同樣的。

 

參考資料:

https://www.bennadel.com/blog/2522-providing-a-return-value-in-a-javascript-constructor.htm

http://www.w3dev.cn/article/20150912/javascript-constructor-return-value.aspx

https://stackoverflow.com/questions/1978049/what-values-can-a-constructor-return-to-avoid-returning-this

相關文章
相關標籤/搜索