摘要:具有相同的所有構(gòu)造器的對(duì)象都具有相同的類型最后中的中有對(duì)于使用函數(shù)名這樣的方式創(chuàng)建對(duì)象有無是一樣的。對(duì)于使用函數(shù)名創(chuàng)建對(duì)象和無返回值一樣因?yàn)槟J(rèn)就會(huì)返回。
讀到j(luò)query源碼時(shí)我有以下疑惑
問題1 Jquery 中創(chuàng)建對(duì)象的奧秘
問題2 JavaScript中this的指向問題
問題3 return this 的作用
問題4 instanceof / 對(duì)象和類之間的關(guān)系
//代碼1(Jquery 創(chuàng)建對(duì)象)
var iQuery=function (){ name="iQuery"; //4 return new iQuery.prototype.init(); //1 }; iQuery.prototype={ init : function(){ name="iQueryPrototypeInit"; //5 return this; //2 }, name : "iQueryPrototype" //6 }; iQuery.prototype.init.prototype=iQuery.prototype; //3
這時(shí)我有問題了,//1 處有無new的區(qū)別。//2 處有無 return this 的區(qū)別。 //3處的作用
在這里我通過對(duì)//代碼1 進(jìn)行分解來回答 問題1 到 問題4
//代碼2 我將 //代碼1 中的 //3 處去掉 //2 處去掉 //1 處去掉
var iQuery=function (){ name="iQuery"; return iQuery.prototype.init(); }; iQuery.prototype={ init : function(){ name="iQueryPrototypeInit"; //5 }, name : "iQueryPrototype" }; iQuery().name; //結(jié)果為 VM105:1 Uncaught TypeError: Cannot read property name of undefined(…)
分析: iQuery.prototype.init() 是調(diào)用了init函數(shù),由于函數(shù)沒有返回值,所以只返回了控制 return iQuery.prototype.init() 也沒有返回值iQuery().name;會(huì)有以上錯(cuò)誤提示
//代碼3
var iQuery=function (){ name="iQuery"; //4 return new iQuery.prototype.init(); //1 }; iQuery.prototype={ init : function(){ name="iQueryPrototypeInit"; //5 }, name : "iQueryPrototype" //6 }; iQuery().name; //結(jié)果為 undefined 這里并不提示錯(cuò)誤,而是說name沒有定義;
分析: //4處 name為iQuery 的局部變量,//5 處name是init的局部變量。
執(zhí)行iQuery()時(shí)創(chuàng)建了一個(gè)init的對(duì)象,這時(shí)init是構(gòu)造函數(shù),執(zhí)行時(shí)流程
1 創(chuàng)建一個(gè)對(duì)象
2 返回新建的對(duì)象
這就是有無 new 的區(qū)別
//代碼4 多了個(gè)this
var iQuery=function (){ name="iQuery"; //4 return new iQuery.prototype.init(); //1 }; iQuery.prototype={ init : function(){ this.name="iQueryPrototypeInit"; //5 }, name : "iQueryPrototype" //6 }; iQuery().name; //結(jié)果為 `iQueryPrototypeInit`
分析: 執(zhí)行 iQuery().name;執(zhí)行流程
1 創(chuàng)建一個(gè)對(duì)象
2 讓 this 引用這個(gè)對(duì)象
3 為 this 所引用的對(duì)象添加屬性 name
4 返回 this 所引用的對(duì)象
iQuery() instanceof iQuery //false iQuery() instanceof iQuery.prototype //VM125:1 Uncaught TypeError: Right-hand side of "instanceof" is not callable(…)
說 iQuery.prototype 是一個(gè)對(duì)象 instanceof 右邊必須是類,即函數(shù)名
iQuery() instanceof iQuery.prototype.init; //true
這里調(diào)用 iQuery() 是創(chuàng)建了init的一個(gè)對(duì)象。
//代碼5 多了//2
var iQuery=function (){ name="iQuery"; //4 return new iQuery.prototype.init(); //1 }; iQuery.prototype={ init : function(){ this.name="iQueryPrototypeInit"; //5 return this; //2 }, name : "iQueryPrototype" //6 }; iQuery().name; //結(jié)果為 iQueryPrototypeInit
分析: 執(zhí)行 iQuery().name;執(zhí)行流程
1 創(chuàng)建一個(gè)對(duì)象
2 讓 this 引用這個(gè)對(duì)象
3 為 this 所引用的對(duì)象添加屬性 name
4 返回 this 所引用的對(duì)象
iQuery() instanceof iQuery //false iQuery() instanceof iQuery.prototype //VM125:1 Uncaught TypeError: Right-hand side of "instanceof" is not callable(…)
說 iQuery.prototype 是一個(gè)對(duì)象 instanceof 右邊必須是類,即函數(shù)名
iQuery() instanceof iQuery.prototype.init; //true
這里調(diào)用 iQuery() 是創(chuàng)建了init的一個(gè)對(duì)象。
總結(jié)1 如果使用new創(chuàng)建對(duì)象加不加 return this 是一樣的。
//代碼6 去掉//1 處的 new //2處有 return this
var iQuery=function (){ name="iQuery"; //4 return iQuery.prototype.init(); //1 }; iQuery.prototype={ init : function(){ this.name="iQueryPrototypeInit"; //5 return this; //2 }, name : "iQueryPrototype" //6 }; iQuery().name; // iQueryPrototypeInit
如果去掉 //5
iQuery().name; // iQueryPrototype
分析: 執(zhí)行 iQuery() 返回了 iQuery.prototype 這個(gè)由字面常量創(chuàng)建的對(duì)象
如果沒有去掉 //5 則給 iQuery.prototype 添加了 name 屬性覆蓋了原有的name
在這里 iQuery.prototype.init() 是 iQuery.prototype 這個(gè)對(duì)象調(diào)用了 init 函數(shù)
所以 init 的 this 指向了 iQuery.prototype
結(jié)論2: 函數(shù)中的 this 始終指向直接調(diào)用它的對(duì)象 ,注意是直接,為什么說是直接 請(qǐng)看 //代碼6
//代碼7
var iQuery=function (){ name="iQuery"; //4 return iQuery.prototype.init(); //1 }; iQuery.prototype={ init : function(){ return this; //2 }, name : "iQueryPrototype" //6 }; var temp ={}; temp.name="temp"; temp.sayName=iQuery().init; // 等價(jià)于 temp.sayName=iQuery.prototype.init; temp.name; // 結(jié)果 temp temp.sayName.name; // 結(jié)果 temp
分析: 執(zhí)行 temp.sayName=iQuery().init; 為對(duì)象 temp 添加了一個(gè) sayName 方法,sayName 引用了 iQuery().init/temp.sayName=iQuery.prototype.init這時(shí) init 中的 return this 這個(gè) this 指向 temp 因?yàn)槭?temp 直接調(diào)用 init
總結(jié):JavaScript中的 this 是上下文 這個(gè)上下文特指是函數(shù)的上下文,就是函數(shù)所屬的對(duì)象JavaScript中的 bind,call,apply 方法都能切換 函數(shù)的上下文,這和代碼 //6 的原理相同都是改變 this 的指向,所以叫做上下文切換
//代碼8 (本文最重要的點(diǎn)) 對(duì)象和類之間的關(guān)系(instanceof)
var iQuery=function (){ name="iQuery"; //4 return new iQuery.prototype.init(); //1 }; iQuery.prototype={ init : function(){ }, name : "iQueryPrototype" //6 }; iQuery.prototype.init.prototype=iQuery.prototype; //3
// 注意 增加了 //3
這時(shí)執(zhí)行:
a: iQuery() instanceof iQuery().init; //true
b: iQuery() instanceof iQuery; //true;
如果去掉 //3
c: iQuery() instanceof iQuery; //false;
分析: 我調(diào)用 iQuery() 創(chuàng)建的明明是 構(gòu)造器 init 的對(duì)象啊 a:的結(jié)果才是符合邏輯的結(jié)果,b: 是什么鬼啊,和他有毛關(guān)系啊
請(qǐng)看 //代碼9 //代碼10
//代碼9
var pro={}; var A=function(){}; A.prototype=pro; var B=function(){}; B.prototype=pro; var a=new A(); var b=new B(); 執(zhí)行: a instanceof A; //true a instanceof B; //true b instanceof A; //true b instanceof B; //true
//代碼10
var pro={}; var A=function(){}; A.prototype=pro; var B=function(){}; B.prototype=pro; var a=new A(); var b=new B(); var C=function(){}; C.prototype=a; var c=new C(); c instanceof A; //true c instanceof B; //true c instanceof C; //true
分析: 看到這里大家一定會(huì)明白Jquery的設(shè)計(jì)者為什么加 iQuery.prototype.init.prototype=iQuery.prototype;
雖然源碼中用了 fn 但是 fn 就是 Jquery.prototype我給出我的結(jié)論
結(jié)論3: JavaScript 中的對(duì)象和類(即 構(gòu)造器) 之間除了 對(duì)象的_proto_ 屬性指向了 類(構(gòu)造器)指定的 prototype之外,對(duì)象和類之間沒有更多的關(guān)系。類型完全由 prototype 決定。具有相同 prototype 的所有構(gòu)造器的對(duì)象都具有相同的類型
最后: Jquery中的init中有 return this 對(duì)于使用 new 函數(shù)名() 這樣的方式創(chuàng)建對(duì)象有無 return this 是一樣的。那Jquery為什么加啊,因?yàn)?b>Jquery中的很多其它方法可以進(jìn)行鏈?zhǔn)秸{(diào)用,這些方法中通過 return this 返回由init創(chuàng)建的對(duì)象,為了保持一致 所以init中的 return this 真的可以去掉。對(duì)于使用 new 函數(shù)名() 創(chuàng)建 對(duì)象 return this 和無返回值一樣因?yàn)槟J(rèn)就會(huì)返回 this。 return 基本類型,則 return 會(huì)被忽略依然 return this。 如果 return 引用類型 那么返回結(jié)果就是 引用類型的對(duì)象。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/80326.html
摘要:干想了半天,認(rèn)為可能還是本身的寫法問題。對(duì)象提供了一種通過定義函數(shù)來獲取或設(shè)置特定值的方法。簡(jiǎn)單來說,給我們暴露了一個(gè)鉤子,我們可以自己定義方法比如,來實(shí)現(xiàn)針對(duì)某個(gè)屬性的特定行為。 寫在最前 本次分享一下在一次jQuery賦值樣式失效的結(jié)果中來分析背后原因的過程。在翻jQuery源碼的過程中,感覺真是還不能說自己只是會(huì)用jQuery,我好像連會(huì)用都達(dá)不到(逃 歡迎關(guān)注我的博客,不定期更...
摘要:干想了半天,認(rèn)為可能還是本身的寫法問題。對(duì)象提供了一種通過定義函數(shù)來獲取或設(shè)置特定值的方法。簡(jiǎn)單來說,給我們暴露了一個(gè)鉤子,我們可以自己定義方法比如,來實(shí)現(xiàn)針對(duì)某個(gè)屬性的特定行為。 寫在最前 本次分享一下在一次jQuery賦值樣式失效的結(jié)果中來分析背后原因的過程。在翻jQuery源碼的過程中,感覺真是還不能說自己只是會(huì)用jQuery,我好像連會(huì)用都達(dá)不到(逃 歡迎關(guān)注我的博客,不定期更...
摘要:第一個(gè)大陡坡是應(yīng)用發(fā)布,老年代內(nèi)存占比下降,很正常。但此時(shí)老年代內(nèi)存使用占比。因?yàn)楹笃诓⒉粫?huì)引發(fā)。可以看出,由于到達(dá)時(shí)候,觸發(fā)了一次和一次。但觸發(fā)時(shí),占比并沒用明顯的規(guī)律。得出,擴(kuò)容導(dǎo)致這個(gè)說法,其實(shí)是不準(zhǔn)確的。 轉(zhuǎn)載請(qǐng)注明原文鏈接:https://www.jianshu.com/p/468... 某天早上,毛老師在群里問「cat 上怎么看 gc」。 showImg(https://...
摘要:首先,我先去上搜索了的定義運(yùn)算符創(chuàng)建一個(gè)用戶定義的對(duì)象類型的實(shí)例或具有構(gòu)造函數(shù)的內(nèi)置對(duì)象的實(shí)例。 今天看到一道面試題,如下,問: 實(shí)例化 Person 過程中,Person返回什么(或者 p 等于什么)? function Person(name) { this.name = name return name; } let p = new Person(Tom); 說實(shí)...
閱讀 3504·2021-10-18 13:30
閱讀 2957·2021-10-09 09:44
閱讀 1973·2019-08-30 11:26
閱讀 2306·2019-08-29 13:17
閱讀 769·2019-08-29 12:17
閱讀 2259·2019-08-26 18:42
閱讀 484·2019-08-26 13:24
閱讀 2964·2019-08-26 11:39