由於是個前端小白,通過這一兩天的學習html,css,js和jquery等,基本上前端會用了,而且熟悉我博客的人來說,沒錯,我把自己的博客給優化了一下(一些大佬都是禁用模板的所有樣式,然后自己設計頁面布局),我的話就稍微添加了一些小插件;
比如動態雪花背景,雪花隨着鼠標彈開;背景圖片;鼠標點擊特效文字;右上角3D相冊,類似輪播圖一樣;統計訪問博客的人的來源;小老鼠組件;個性時鍾組件;背景音樂;右下角的推薦框;左下角萌萌的看板娘,還有就是將博客正文和代碼的字體進行一些微調。。。。突然發現前端賊有意思,最大的感觸就是定位和布局,這兩個非常重要,布局可以更好模塊化的開發,而定位就是將你開發出來的模塊更好的展示出來,那么對於特效呢?就我而言對前端初學者其實不是特別重要吧,因為這就要靠你的編碼能力和邏輯思維了!
我是前端小菜鳥,對於寫特效代碼不是特別會,我博客的特效就是百度隨便找的,開箱即用,哈哈哈!
但是經過自己修改整個博客也學會了不少東西,這次就簡單說說學習過程中學的js吧。。。
1.js構造函數基本概念
說實話我是對用函數去實例化對象用起來有點不對勁,其實這里的構造函數就相當於一個類(面向對象語言都有類,比如C++,java,C#,python等),這個類就是起到一個模板的作用;比如我們去生產零件,構造函數(或者說是類)就相當於零件的圖紙,而實際生產出來的零件就是實例!顯而易這種方式很好,利於擴展和減少無謂工作量,因為你只需要對圖紙進行一些改進,零件也會跟着改進;(對應到代碼中就是用到繼承,繼承中最重要的知識點就是原型,后面會說到的);
我們簡單看看js是怎么實例化對象的,隨便寫幾種方式:
<script> function Person(name,age){
this.name = name
this.age = function(){xxxxxx}
}; </script> //第一種,字面量的形式,也就是直接用 var obj = {name:“小王”,age:function(){xxxxxx}} //第二種,用new關鍵字,也就是要用到構造函數 var obj = new Person(xx,xx); //第三種,先用new關鍵字創建一個Object空對象,然后往對象中添加新的屬性 var obj = new object(); obj.name = "小王"; obj.age = function(){xxxxxx};
看上面的代碼我們應該關注第二行 function Person(name,age){xxxxxxx},這個函數是個什么鬼呢?和一般我們自己隨便寫的函數有沒有什么區別呢?
第一眼看過去就是我們自己寫的函數名字都是小寫啊,而這里的函數首字母大寫了;用法嘛,一樣用,我們這個函數可以直接像我們自己定義的函數那樣使用,例如var per = Person(xx,xx);而首字母大寫了的函數(下面統稱為構造函數)還能創建對象,所以我們可以大概知道構造函數和普通函數應該是處於同一地位但是用法更多更靈活,那么問題來了,構造函數和普通函數是誰創造的呢?
就好像你可以根據零件圖紙制造零件,但是零件圖紙又是怎么來的呢?肯定有一個機器生產出來的;這里就有一個很有意思的現象,如果只看機器和圖紙,那么機器應該是構造函數,圖紙是實例;如果只看圖紙和零件,那么圖紙是構造函數,零件是實例;站在不同角度看到的就不一樣,而這里的機器指的就是js中的Function,一切的函數(不管是普通的函數,構造函數還是一些內置函數)都是由這個Function生產出來的。。。。
看看一些基本的東西(就當記一下筆記,哈哈):
js中五大基本數據類型:number,string,boolean,undefined,null;一個混個數據類型:object;
引用類型:Array,Object,Function
js中內置函數有,Date,Math,Number,Boolean,String,,Array,RegExp,Object,Function
到這里大家看一個大概的輪廓,可以看到Function生產出所有的函數,其中怎么生產出來構造函數的?在js內部做了封裝,看不到,但是我們可以通過intstanceof這個方法驗證:
測試如下,可以知道無論是什么函數本質上都是Function的實例,就好像我們國家有56個民族,但是本質上都是中國人啊。。。
//測試內置函數和自定義函數、自定義構造函數是不是Function實例 var person=new Function("name","age","return name+':'+ age"); 控制台:person instanceof Function //true 控制台:Array instanceof Function //true,自己試試其他的內置函數 var man = function(){}; 控制台:man instanceof Function //true function Person(name,age){this.name=name;this.age=age}; 控制台:Person instanceof Function //true 控制台:Function instanceof Function //true,可見Function是自己本身的一個實例,因為Function是最高層了,沒有上一層了,只能是自己的實例了
這里我們重點看構造函數,普通函數就不討論了,對於一個自定義構造函數來說,有爸爸,也有兒子,爸爸是Function,兒子是實例(注意,爸爸只能由一個,兒子可以有多個呀@_@),而且每一個身上都會有一個屬性constructor,可以指向自己的構造函數,於是上面的圖可以進行一些改進:
2.原型
為什么要有原型呢?上面已經說的比較清楚了,是為了能夠重復的使用代碼而不用每次都寫一些重復的代碼,那么原型放在哪里呢?它的本質又是什么呢?
很簡單,原型是放在構造函數中,而且本質上就是當前構造函數的一個實例,換句話的意思就是Function和內置函數以及所有自定義構造函數都有原型!對應在代碼中就是prototype屬性;注意:構造函數實例沒有原型的哦~~
說起來很抽象,對上面的圖進行改進:
那么問題來了,沒有沒辦法使得下一層可以直接指向上一層的原型呢?答案是有的,不管是Function、構造函數還是實例,默認都有一個自帶的屬性_proto_,這個屬性就是可以指向上一層的原型,於是上圖又可以進行一些變化:
現在我們就要看看原型的內部是什么樣子了?其實上面已經說了,原型是當前構造函數的一個實例,上面圖中原型2中的結構,應該就和Person的實例結構一樣,里面有屬性constructor和_proto_,其中constructor屬性應該不多說了吧,就是指向自己的構造函數;_proto_屬性指向上一層的原型,注意:這里有點不同,原型的祖先是Object,例如上圖原型1和原型2都是指向Object的原型
說起來跟日了狗一樣,我們繼續畫一個圖,為了整潔,就不看原型外面的那些屬性了:
是不是看着很煩,瑪德,加了原型之后整個結構都不一樣了,還會涉及到Object(其實js中Object是一個構造函數,也是由Function生產的,但是Object中的原型卻又是最頂層的,emmm.....青出於藍而勝於藍么?),基本上涉及到了原型之后整個結構看起來就復雜了很多,但是也因為由此,用起來也就更靈活了,靈活的有的時候都不知道該怎么用,哈哈!
3.原型的簡單用法
弄清楚了上面這些的結構之后我們再來使用原型就很簡單了!舉個很簡單的例子;
一個普通的構造函數:
function Person(name, age) { this.name = name; this.age = age; this.sayName = function() { alert(this.name+this.age) } } var person = new Person("java小新人","12"); person.sayName();
假如在不修改源代碼的情況下,我要這個person對象添加一個helloWorld方法,你覺得怎么用比較好?有人說,很簡單啊,我直接把這個構造函數一復制,馬上粘貼,然后在里面添加一個helloWorld方法就可以了,emmmm....也不是說這種方式不行啊,這種方式很好啊,起碼能夠完成功能啊,還是很不錯的!那有沒有辦法優化一下呢?畢竟我們知道重復的代碼太多是我們不想看到的。
這個時候就是原型的出場時間了:
function Person(name, age) { this.name = name; this.age = age; this.sayName = function() { alert(this.name+this.age) } } //運用原型,在原型中添加一個helloWorld屬性 Person.prototype.helloWorld = function(){alert(this.name+":世界,我來了!")} var person = new Person("java小新人","12"); person.helloWorld();
上述代碼在不修改源代碼的前提下只添加了一行代碼就完成了目標,是不是比復制粘貼好了不少,嘿嘿!
4.總結
我是搞java的,js這種前端的語言不是很熟悉(都是最近修改博客,復制別人代碼的時候發現js代碼看不懂,於是才有心思靜下來學一下前端的東西(●´∀`●)),也就只能根絕我查的一些資料和自己的理解,以及多敲代碼測試一下寫出來的文章,可能還有很多方面沒說到的或者有錯誤的,請提示一下我去修改,哈哈哈!話說感覺學js要把整個的函數體系弄清楚學一下還是很輕松愉快的!
后面應該會說說原型鏈和閉包相關的東西吧!