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