摘要:前言由于最近的項(xiàng)目用到了一些的代碼,所以我?guī)е闷嫘?,認(rèn)真閱讀了這本書,粗略地了解語言的基本結(jié)構(gòu)和特性,對(duì)于一些不熟悉的新概念,以記錄的形式加強(qiáng)印象,也是對(duì)學(xué)習(xí)的反思總結(jié)。
前言
由于最近的項(xiàng)目用到了一些js的代碼,所以我?guī)е闷嫘?,認(rèn)真閱讀了這本書,粗略地了解js語言的基本結(jié)構(gòu)和特性,對(duì)于一些不熟悉的新概念,以記錄的形式加強(qiáng)印象,也是對(duì)學(xué)習(xí)的反思總結(jié)。
一、字面量(literals)“字面量“這個(gè)詞在書中高頻出現(xiàn),先看看他的定義:
字面量表示如何表達(dá)這個(gè)值,一般除去表達(dá)式,給變量賦值時(shí),等號(hào)右邊都可以認(rèn)為是字面量。
舉個(gè)簡單的例子就明白了,例如
var a = 1; var b = "hello world"; var c = []; var d = {}; var e = function (a,b){return a + b;}
以上例子中,賦值號(hào)右邊都是字面量,分別是數(shù)字字面量,字符串字面量,數(shù)組字面量,對(duì)象字面量及函數(shù)字面量。
為什么要有字面量呢?我的理解,js和php一樣都是弱類型語言,需要根據(jù)賦值號(hào)右邊的內(nèi)容來判斷變量的類型,而字面量就是為了很方便地按照指定規(guī)格創(chuàng)建新的對(duì)象,數(shù)組或者定義函數(shù)值,讓我們更清楚地知道我到底定義了一個(gè)什么。
字面量與變量的區(qū)別?字面量都是一些不可改變的值,比如 :1 2 3 4 5
變量就像一個(gè)容器,可以用來保存字面量,而且變量的值是可以任意改變的
通常我們不會(huì)直接調(diào)用字面量,而是先將字面量存到變量中,再進(jìn)行調(diào)用
二、對(duì)象(object)真的應(yīng)了老師說的,”萬物皆對(duì)象“,在js中,沒有類,有的只有對(duì)象,數(shù)組是對(duì)象,函數(shù)是對(duì)象,正則表達(dá)式是對(duì)象,當(dāng)然,對(duì)象也是對(duì)象。
對(duì)象字面量(object literals)寫法很簡單,就是一對(duì)花括號(hào)括住“屬性:值”對(duì),這里就不再舉例子了,對(duì)象是可以嵌套的,用點(diǎn)運(yùn)算符來獲取對(duì)象的某個(gè)值
引用(reference)對(duì)象不會(huì)復(fù)制,通過引用來傳遞,例如
var stooge = { name : "Jack"; }; var x = stooge; x.name = "Tom"; var result = stooge.name;
由于x與stooge指向同一個(gè)對(duì)象,所以此時(shí)result為”Tom“.
原型(prototype)js里,每一個(gè)對(duì)象都會(huì)連接一個(gè)原型對(duì)象,并且可以繼承屬性,所有通過字面量對(duì)象創(chuàng)建的對(duì)象都會(huì)連接到Object.prototype,它是js中標(biāo)配對(duì)象
當(dāng)創(chuàng)建一個(gè)對(duì)象時(shí),可以選擇一個(gè)對(duì)象作為它的原型,,這有點(diǎn)像類的繼承,具體實(shí)現(xiàn)的方法書中已經(jīng)幫我們寫好了,直接拿來套用就行
var stooge = { name : "Tom" }; if (typeof Object.beget !== "function") { Object.create = function(o){ var F = function () {}; F.prototype = o; return new F(); }; } var another_stooge = Object.create(stooge);//another_stooge選擇stooge作為它的原型
關(guān)于原型,有幾點(diǎn)需要注意
對(duì)一個(gè)對(duì)象做出改變時(shí),不影響它的原型,但改變?cè)偷膶傩詴r(shí),繼承它的對(duì)象的屬性也會(huì)改變,但不會(huì)改變繼承以后新增的屬性
在原型之中添加屬性,繼承它的所有對(duì)象也會(huì)可見,改變?cè)偷囊粋€(gè)屬性,繼承它的對(duì)象的屬性也會(huì)改變,刪除原型的一個(gè)屬性,繼承它的對(duì)象也會(huì)刪除
如果b繼承a,c繼承b,那么就會(huì)形成原型鏈,如果獲取一個(gè)c中沒有的屬性,那么它會(huì)從b中找這個(gè)屬性,如果b中也沒有,它會(huì)從a中找,如果a中還沒有,則返回undefined,此過程稱為委托
關(guān)于第二條我有一個(gè)疑問,在原型中添加一個(gè)屬性,繼承它的對(duì)象是否也添加了這個(gè)屬性?
如果我直接檢索一個(gè)對(duì)象的屬性,由于委托的存在而使得我無法確認(rèn)該屬性是對(duì)象還是原型的
例如,我在上面的代碼繼續(xù)寫
stooge.lastname = "jack"; var name = another_stooge.lastname; document.writeln(name);
這時(shí),輸出結(jié)果是jack,但這個(gè)jack是another_stooge的還是stooge的,我并不知道。
這個(gè)其實(shí)在后面給出了解決方法,就是使用hasOwnProperty()這個(gè)方法
stooge.lastname = "jack"; var status = another_stooge.hasOwnProperty("lastname"); document.writeln(status);
運(yùn)行結(jié)果:false
這個(gè)方法會(huì)檢查對(duì)象是否擁有獨(dú)有屬性,而且不會(huì)檢查原型鏈,如果是,返回true,否則返回false
使用typeof可以檢查對(duì)象屬性的類型,用來過濾掉函數(shù),而hasOwnProperty則可以過濾掉不關(guān)心的值,那么結(jié)合forin語句就可以遍歷對(duì)象所有的值了
var name; for (name in another_stooge) { if (typeof another_stooge.name !== "function") { document.writeln(name + ":" another_stooge.name); } }三、函數(shù)(Functions)
函數(shù)這部分涉及的內(nèi)容較多,各種調(diào)用,回調(diào),級(jí)聯(lián),記憶等之前從沒見過的用法
函數(shù)對(duì)象(Function Objects)對(duì)象字面量創(chuàng)建對(duì)象,它連接到object.prototype
函數(shù)字面量創(chuàng)建函數(shù)對(duì)象,它連接到Function.prototype
有趣的是,函數(shù)在創(chuàng)建完之后,會(huì)天生自帶屬性和方法,函數(shù)不僅可以當(dāng)“函數(shù)”使用,也能當(dāng)“對(duì)象”使用,函數(shù)可以保存到變量,對(duì)象,數(shù)組中。函數(shù)可以當(dāng)成另一個(gè)函數(shù)的參數(shù),函數(shù)可以返回函數(shù),函數(shù)甚至可以擁有函數(shù)(注意,不是在一個(gè)函數(shù)中調(diào)用另一個(gè)函數(shù),而是函數(shù)可以作為另一個(gè)函數(shù)的屬性),當(dāng)一個(gè)函數(shù)是另一個(gè)對(duì)象的屬性時(shí),函數(shù)被稱為方法
四種函數(shù)的調(diào)用模式 1.方法調(diào)用模式這種調(diào)用方法在面向?qū)ο缶幊陶Z言中最為常見,當(dāng)一個(gè)函數(shù)保存為一個(gè)對(duì)象的屬性時(shí),可以通過object.function()進(jìn)行調(diào)用
另外,方法可以通過this指針找到自己的對(duì)象,在方法內(nèi),可以通過this.another_function(),this.property使用或修改對(duì)象其他的方法和屬性,在使用thinkphp過程中,this的使用非常高頻,所以這樣的用法并不陌生
2.函數(shù)調(diào)用模式當(dāng)函數(shù)定義在對(duì)象外部時(shí),,通過function(value1,value2,etc)調(diào)用成為函數(shù)調(diào)用模式
函數(shù)調(diào)用模式有一個(gè)麻煩的地方。
當(dāng)函數(shù)定義在對(duì)象內(nèi)部時(shí),this指調(diào)用函數(shù)的對(duì)象,當(dāng)函數(shù)沒有綁定在對(duì)象內(nèi)時(shí),默認(rèn)指向全局對(duì)象(window)
但是當(dāng)我在函數(shù)內(nèi)定義了一個(gè)方法時(shí),this應(yīng)該指向?qū)ο?,而?shí)際卻指向全局對(duì)象,這使得在定義函數(shù)內(nèi)部的方法時(shí)不能使用該對(duì)象的其他屬性輔助完成,例如以下
var ob = { value : 1, add : function () { var show = function () { return this; }; return show(); } }; var result = add(); document.writeln(result);
運(yùn)行結(jié)果:[object Window]
由結(jié)果可知,show方法中的this并沒有指向ob,而是指向了全局對(duì)象。
解決方法:在外部函數(shù)內(nèi)定義一個(gè)變量that并賦值為this,內(nèi)部函數(shù)使用that,即可訪問該對(duì)象
var ob = { value : 1, add : function () { var that = this; var show = function () { return that.value; }; return show(); } }; var result = ob.add(); document.writeln(result);
運(yùn)行結(jié)果:1
此時(shí),show就可以訪問ob.value了
先上實(shí)例
var Person = function(name){ this.name = name; }; var student = new Person("li");//構(gòu)造一個(gè)Person對(duì)象,并將name屬性賦值為li document.writeln(student.name);
很眼熟,像極了類的構(gòu)造函數(shù),用法也是,直接new Function(value,etc)
這種構(gòu)造對(duì)象的模式對(duì)于習(xí)慣了基于類的語言的我簡直是福音,我看到時(shí)滿滿的親切感
書上對(duì)于構(gòu)造器調(diào)用不是十分推薦,因?yàn)楫?dāng)使用此類函數(shù)時(shí)不加new修飾符會(huì)帶來意想不到的錯(cuò)誤,既沒有編譯器提醒也沒有運(yùn)行警告。在后面他提出了一個(gè)更好的解決辦法——偽類,會(huì)這在之后進(jìn)行具體的學(xué)習(xí)
4.Apply,Call調(diào)用模式(上下文調(diào)用模式)書中對(duì)這種調(diào)用的介紹很少,我結(jié)合書和菜鳥教程做了一些自己的總結(jié)
Apply和Call都是函數(shù)自帶的方法,功能一樣,用法不同
apply:
函數(shù)模式
var array = [1,2]; var add = function(number1,number2){ return number1 + number2; }; var result = add.apply(null,array);//以window作為上下文 document.writeln(result);
2.方法模式
var array = [1,2]; var add = function(number1,number2){ return number1 + number2; }; var o = { name : "jack"}; var result = add.apply(o,array);//以o作為上下文 document.writeln(result);
兩種調(diào)用,只是在參數(shù)上有所不同,第一個(gè)參數(shù)為null時(shí),以window作為上下文,如果是對(duì)象,則以該對(duì)象為上下文
這個(gè)上下文是什么?有什么用?
這使我非常困惑,這種調(diào)用看似很沒用??!
直到我看到一則實(shí)例,我才感受到它的魅力
題目:獲得 div 與 p 標(biāo)簽, 并添加邊框 border: 1px solid red
一般做法:
var p_list = document.getElementsByTagName("p");//獲取所有p標(biāo)簽,存到p_list var div_list = document.getElementsByTagName("div");//獲取所有div標(biāo)簽,存到div_list var i = 0; for( ; i < p_list.length; i++ ) { p_list[ i ].style.border = "1px solid red";//通過for循環(huán),挨個(gè)添加樣式 } for( i = 0; i < div_list.length; i++ ) { div_list[ i ].style.border = "1px solid red";//通過for循環(huán),挨個(gè)添加樣式 }
使用上下文模式:
var t = document.getElementsByTagName, arr = [];// 偽數(shù)組沒有 push 方法,所以這里要 聲明一個(gè) 數(shù)組 arr.push.apply( arr, t.apply( document, [ "p" ] ) );// 其實(shí)是把p標(biāo)簽,一個(gè)個(gè)當(dāng)成參數(shù)放了進(jìn)來 arr.push.apply( arr, t.apply( document, [ "div"] ) );//同上 arr.forEach( function( val, index, arr ) { val.style.border = "1px solid red";//使用foreach,只進(jìn)行一次遍歷,即可添加樣式 });
上述實(shí)例的核心就是將兩個(gè)數(shù)組合并在一起,進(jìn)行一次遍歷
對(duì)于call,只是參數(shù)不再以數(shù)組形式封裝,而是function.call(null,value1,value2,etc)這樣的形式,在此不多做贅述
小結(jié)通過js,我首次接觸到基于原型繼承設(shè)計(jì)的語言,剛開始學(xué)習(xí)對(duì)于這樣的設(shè)計(jì)不是很明白,也不明白原型設(shè)計(jì)的好處是什么。但是js的廣泛使用證明它必然有它的優(yōu)勢(shì),我無法理解說明我的技術(shù)還達(dá)不到去理解一個(gè)語言精髓的水平
js中處處體現(xiàn)著萬物姐皆對(duì)象,處處是對(duì)象,這讓我在一開始感到費(fèi)解,但隨著進(jìn)一步的學(xué)習(xí),我發(fā)現(xiàn),在js中,對(duì)象與其說是對(duì)象,不如說是屬性和方法的集合,一個(gè)對(duì)象在定義之初,系統(tǒng)就已經(jīng)“免費(fèi)”贈(zèng)送了這個(gè)集合一些屬性和方法,以這樣的思路去思考,就不難理解為什么函數(shù)會(huì)是對(duì)象了
函數(shù)的四種調(diào)用方法,方法模式和函數(shù)模式我都非常熟悉,只是函數(shù)調(diào)用模式需要注意this與that,構(gòu)造器模式作者并不推薦,只是作為了解,而上下文模式設(shè)計(jì)的巧妙我還不能完全領(lǐng)會(huì),基本處于一頭霧水。
javascript語言精粹這本書感覺很多地方過于簡略,需要我結(jié)合網(wǎng)上的一些資料輔助才能看懂,換言之,它并不適合新手入門,然而即便如此,我也抱著能看懂多少算多少的心態(tài),去一窺這個(gè)語言的魅力
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/97256.html
摘要:對(duì)之前看高級(jí)程序設(shè)計(jì)時(shí)沒有注意到的一些知識(shí)點(diǎn),結(jié)合本書做以補(bǔ)充語法注釋源于的型既可以出現(xiàn)在字符串字面量中,也可能出現(xiàn)在正則表達(dá)式字面量中,如故一般建議使用型注釋保留字語句變量參數(shù)屬性名運(yùn)算符和標(biāo)記等標(biāo)識(shí)符不允許使用保留字,此外在對(duì)象字面量中 對(duì)之前看《JavaScript高級(jí)程序設(shè)計(jì)》時(shí)沒有注意到的一些知識(shí)點(diǎn),結(jié)合本書做以補(bǔ)充 語法 注釋 源于PL/I的/* */型既可以出現(xiàn)在字符串字...
摘要:但采用構(gòu)造器調(diào)用模式,即是使用了前綴去調(diào)用一個(gè)函數(shù)時(shí),函數(shù)執(zhí)行的方式會(huì)改變。對(duì)象包含構(gòu)造器需要構(gòu)造一個(gè)新的實(shí)例的所有信息。構(gòu)造器的變量和內(nèi)部函數(shù)變成了該實(shí)例的私有成員。 JavaScript 是一門弱類型語言,從不需要類型轉(zhuǎn)換。對(duì)象繼承關(guān)系變得無關(guān)緊要。對(duì)于一個(gè)對(duì)象來說重要的時(shí)它能夠做什么,而不是它從哪里來。 閱讀《javascript語言精粹》筆記! 偽類 js的原型存...
摘要:對(duì)象適用于匯集和管理數(shù)據(jù)。一個(gè)對(duì)象字面量就是包圍在一對(duì)花括號(hào)的多個(gè)名值對(duì)。嘗試從對(duì)象里取值將會(huì)導(dǎo)致異常。亦不會(huì)觸及原型鏈中的任何對(duì)象。嚴(yán)格模式下,不能用刪除顯式聲明的標(biāo)識(shí)符,名稱或具名函數(shù)。 Javascirpt里的對(duì)象是無類型的。它對(duì)新屬性的名字和屬性的值沒有任何的限制。對(duì)象適用于匯集和管理數(shù)據(jù)。對(duì)象可以包括其他對(duì)象,所以它們可以容易地表示成樹狀或者圖形結(jié)構(gòu)。 對(duì)象字面量 ...
摘要:在中數(shù)組是經(jīng)常被使用到的,我們除了要學(xué)習(xí)數(shù)組的方法,還需要了解誒一下某一些方法是如何來實(shí)現(xiàn)的。然而我看了語言精粹中方法的一章,想記錄下書上的代碼,以便加深印象。方法移除數(shù)組中的第一個(gè)元素并且放回該元素。 在js中數(shù)組是經(jīng)常被使用到的,我們除了要學(xué)習(xí)數(shù)組的方法,還需要了解誒一下某一些方法是如何來實(shí)現(xiàn)的。然而我看了《javascript語言精粹》中方法的一章,想記錄下書上的代碼,以便加深印...
摘要:語言精粹讀書筆記第四章函數(shù)函數(shù)字面量函數(shù)字面量包含個(gè)部分第一部分,保留字第二部分,函數(shù)名,它可以被忽略。這個(gè)超級(jí)延遲綁定使得函數(shù)對(duì)高度復(fù)用。構(gòu)造器調(diào)用模式一個(gè)函數(shù),如果創(chuàng)建的目的就是希望結(jié)合的前綴來調(diào)用,那它就被稱為構(gòu)造器構(gòu)造。 《JavaScript 語言精粹》 讀書筆記 第四章 函數(shù) Functions 函數(shù)字面量 函數(shù)字面量包含4個(gè)部分: 第一部分, 保留字 function...
閱讀 3202·2021-10-12 10:11
閱讀 1921·2021-08-16 10:59
閱讀 2936·2019-08-30 15:55
閱讀 1298·2019-08-30 14:19
閱讀 2094·2019-08-29 17:03
閱讀 2530·2019-08-29 16:28
閱讀 3291·2019-08-26 13:47
閱讀 2947·2019-08-26 13:36