摘要:為何構(gòu)造函數(shù)不直接返回呢而是在中間搞了一個(gè)讀過源碼的都知道,這個(gè)函數(shù)實(shí)際是的初始化函數(shù)。
如題,這個(gè)問題我曾經(jīng)在支付寶的電話面試?yán)锩孀詈笠粋€(gè)問題被問到過,后來也沒有去看到底為何不需要new,現(xiàn)在我們就來剖析下。
而且當(dāng)你在看jquery源碼的時(shí)候,如果一開始就搞不懂這樣的問題,抑或jQuery.fn.init.prototype =jQuery.fn 這樣的問題也搞不懂的話,那基本后面的東西都是懵的。
首先回顧下,我們一般是如何寫插件的,通常是這樣的
function Kissy () { } Kissy.prototype.alert = function () { } // 實(shí)例化必須要有,否則無法調(diào)用原型鏈上的alert方法 var kissy = new Kissy() kissy.alert() // 如果我們直接這樣調(diào)用 Kissy().alert() // 就會報(bào)錯alert不是一個(gè)function。這里涉及到原型繼承,new 一個(gè)構(gòu)造函數(shù)和 執(zhí)行普通函數(shù)的區(qū)別,不在贅述。
回歸一個(gè)知識點(diǎn),有助于我們理解后面我們講解的內(nèi)容
構(gòu)造函數(shù)有return值怎么辦?
構(gòu)造函數(shù)里沒有顯式調(diào)用return時(shí),默認(rèn)是返回this對象,也就是新創(chuàng)建的實(shí)例對象。
當(dāng)構(gòu)造函數(shù)里調(diào)用return時(shí),分兩種情況:
1.return的是五種簡單數(shù)據(jù)類型:String,Number,Boolean,Null,Undefined。
這種情況下,忽視r(shí)eturn值,依然返回this對象。
2.return的是Object
這種情況下,不再返回this對象,而是返回return語句的返回值。
如何改造上面的代碼,可以不用new函數(shù),直接調(diào)用到alert方法呢?很簡單。改造如下:
function Kissy () { return Kissy.prototype }
當(dāng)我們直接調(diào)用Kissy()函數(shù)的時(shí)候,不是返回的null或undefined而是返回Kissy的原型,即返回了一個(gè)原型對象,這個(gè)對象上是有alert方法的,這就好像我們熟悉的下面的代碼一樣
var obj = { name: "zj", getName: function() { console.log(this.name) } } obj.getName() // zj
接下來,我們仿造jquery源碼又來改造下:
function Kissy () { return new Kissy.fn.init() } Kissy.fn = Kissy.prototype = { constructor: Kissy, init: function() { console.log("init") } } Kissy.fn.init.prototype = Kissy.fn Kissy.fn.alert = function() { alert("0000") } Kissy().alert() // 00000
無非就是在Kissy上面增加了一個(gè)fn屬性,這個(gè)屬性指向了Kissy.prototype。這樣的目的是便于我們開發(fā)插件的時(shí)候,在原型上增加方法可以直接這么寫Kissy.fn.alert 僅此而已。為何構(gòu)造函數(shù)不直接返回
Kissy.fn呢 而是在中間搞了一個(gè)init.讀過jquery源碼的都知道,jquery.fn.init 這個(gè)函數(shù)實(shí)際是jquery的初始化函數(shù)。這里就不在展開了。
return new Kissy.fn.init()
構(gòu)造函數(shù)返回了一個(gè)Kissy.fn.init()這個(gè)函數(shù)的一個(gè)實(shí)例。當(dāng)然就會繼承這個(gè)實(shí)例上的原型,而原型又被我們重置了
Kissy.fn.init.prototype = Kissy.fn
所以就能調(diào)用到Kissy.fn上面的alert方法了,不信大家可以試試哦。
再來看jquery的源碼,對比剛剛分析的代碼,是不是基本一模一樣,只是jquery源碼fn.init方法有比較多初始化的內(nèi)容。
jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery ); }, jQuery.fn = jQuery.prototype = { //fn即對應(yīng)prototype constructor: jQuery, init: function( selector, context, rootjQuery ) { ... return this; } ... } jQuery.fn.init.prototype = jQuery.fn;
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/93879.html
摘要:本文已完結(jié),請看下文求索的動畫快于嗎為何續(xù)本文源自對問題動畫性能優(yōu)于的原理是什么的回答。是這樣的嗎請看下文求索的動畫快于嗎為何續(xù) 本文已完結(jié),請看下文: > 求索:GSAP的動畫快于jQuery嗎?為何?/續(xù) 本文源自對問題《GSAP js動畫性能優(yōu)于jQuery的原理是什么?》的回答。GSAP是一個(gè)js動畫插件,它聲稱20x faster than jQuery,是什么讓...
摘要:將構(gòu)造函數(shù)的作用域賦值給新對象。也所以對象指向新對象執(zhí)行構(gòu)造函數(shù)內(nèi)部的代碼,將屬性添加給中的對象。通常的解決方案是判斷是否是構(gòu)造函數(shù)的實(shí)例,若是則繼續(xù)執(zhí)行,若不是則進(jìn)行的操作。代碼如下在構(gòu)造函數(shù)參數(shù)個(gè)數(shù)固定的情況下這種方案是可行的。 首先,一般的都是介紹自己,主要是項(xiàng)目經(jīng)歷 問題1:jQuery與Vue的區(qū)別是什么? JQuery和Vue的主要區(qū)別是JQuery主要是通過選擇器來選取D...
摘要:學(xué)習(xí)總結(jié)學(xué)習(xí)整理的一些筆記,很簡單。大部分認(rèn)為和只是不同的叫法而已。依賴注入的兩種方式和注解使用注釋驅(qū)動的功能源碼剖析 Spring IoC學(xué)習(xí)總結(jié) 學(xué)習(xí)spring Ioc整理的一些筆記,很簡單。分享給大家。 IoC 基本概念 在這之前,我們先記住一句話。好萊塢原則:Dont call us, we will call you.其實(shí)這句話很恰當(dāng)?shù)匦稳萘朔崔D(zhuǎn)的意味;Ioc, Inve...
閱讀 4678·2021-09-26 09:55
閱讀 1447·2019-12-27 12:16
閱讀 924·2019-08-30 15:56
閱讀 1931·2019-08-30 14:05
閱讀 1018·2019-08-30 13:05
閱讀 1295·2019-08-30 10:59
閱讀 1486·2019-08-26 16:19
閱讀 1909·2019-08-26 13:47