摘要:中的數據類型在中,包含種數據類型字符串數值布爾值以及對象。然而事實上,這個會彈出,究其原因,就是此處的,因為調用對象的存在,使得當閉包被調用時當這個的發生時,引用的是這個對象。關于函數可以保持自己內部的數據這一特性,成為閉包。
1.JavaScript中的數據類型
在Javascript中,包含6種數據類型:字符串(string)、數值(number)、布爾值(boolean)、undefined、null以及對象(object)。PS:第6種應該是object還是symbo(ES6)?2.JavaScript中的對象
此處的對象包括:對象(屬性的集合,即鍵值的散列表)、數組(有序的列表)、函數(包含可執行的代碼)3.相等與等同運算符
相等運算符:如果操作數具有相同的類型,則判斷其等同性,如果兩個操作數的值相等,則返回true,否則返回false。
如果操作數的類型不同,則按照這樣的情況來判斷:null和undefined相等;
其中一個是數字,另一個是字符串,則將字符串轉換為數字,再做比較;
其中一個是true,先轉換為1(false轉為0)再做比較;
如果一個值是對象,另一個是數字/字符串,則將對象轉換為原始值(通過toString()或者valueOf());
其他情況,直接返回false。
4.原型對象及原型鏈等同運算符(===):如果操作數的類型不同,則不進行值的判斷,直接返回false。
如果操作數的類型相同,分下列情況來判斷:都是數字的情況,如果值相同,則兩者等同(有一個例外,就是NaN,NaN與其本身也不相等),否則不等同;
都是字符串的情況,與其他程序設計語言一樣,如果串的值不相等,則不等同;
都是布爾值,且值均為true/false,則等同;
如果兩個操作數引用同一個對象(數組,函數),則兩者完全等同;
如果兩個操作數均為null/undefined,則等同。
javascript本身是基于原型的,每個對象都有一個prototype的屬性,這個prototype本身也是一個對象,因此它本身也可以有自己的原型,這樣就構成了一個鏈結構。5.數組對象的方法
訪問一個屬性的時候,解析器需要從下向上的遍歷這個鏈結構,直到遇到該屬性,則返回屬性對應的值,或者遇到原型為null的對象(javascript的基對象Object的構造器的默認prototype有一個null原型),如果此對象仍沒有該屬性,則返回undefined。
方法 | 描述 |
---|---|
concat() | 連接兩個或更多的數組,并返回結果數組 |
join() | 把數組的所有元素放入一個字符串。元素通過指定的分隔符進行分隔 |
pop() | 刪除并返回數組的最后一個元素 |
push() | 向數組的末尾添加一個或更多元素,并返回新的長度 |
reverse() | 顛倒數組中元素的順序 |
shift() | 刪除并返回數組的第一個元素 |
slice() | 從某個已有的數組返回選定的元素 |
sort() | 對數組的元素進行排序 |
splice() | 刪除元素,并向數組添加新元素 |
unshift() | 向數組的開頭添加一個或更多的元素,并返回新的長度 |
valueOf() | 返回數組對象的原始值 |
jQuery的設計者John Resig提供的方法
Array.prototype.remove = function (from, to) { var rest = this.slice((to || from) + 1 || this.length); this.length = from < 0 ? this.length + from : from; return this.push.apply(this.rest); }; array.remove(0);//刪除第一個元素 array.remove(-1);//刪除倒數第一個元素 array.remove(0,2);//刪除數組下標為0-2的元素(3個)7.正則表達式
元字符 | 含義 |
---|---|
^ | 串的開始 |
$ | 串的結束 |
* | 零到多次匹配 |
+ | 一到多次匹配 |
? | 零或一次匹配 |
b | 單詞邊界 |
字符 | 含義 |
---|---|
字符本身 | 匹配字符本身 |
r | 匹配回車 |
n | 匹配換行 |
t | 制表符 |
f | 換頁 |
x# | 匹配十六進制數 |
cX | 匹配控制字符 |
標志符 | 含義 |
---|---|
[...] | 在集合中的任一個字符 |
1 | 不在集合中的任一個字符 |
. | 除n之外的任一個字符 |
w | 所有的單字,包括字母數字及下劃線 |
W | 不包括所有的單字,w的補集 |
s | 所有的空白字符,包括空格,制表符 |
S | 所有的非空白字符 |
d | 所有的數字 |
D | 所有的非數字 |
b | 退格字符 |
標記 | 含義 |
---|---|
{n} | 重復n次 |
{n,} | 重復n或更多次 |
{n,m} | 重復至少n次,至多m次 |
var pid = /^(d{15}|d{18})&/;//身份證 var mphone = /d{11}/;//手機號碼 var phone = /d{3,4}-d{7,8};//電話號碼8.使用正則表達式
創建正則表達式:
使用字面量:var regex = /pattern/;
使用RegExp對象:var regex = new RegExp("pattern", switchs);
而正則表達式的一般形式描述為:var regex = /pattern/[switchs];
這里的開關(switchs)有以下三種:
修飾符 | 描述 |
---|---|
i | 忽略大小寫開關 |
g | 全局搜索開關 |
m | 多行搜索開關(重定義^與$的意義) |
正則表達式對象的方法:
方法名 | 描述 |
---|---|
test() | 測試串中是否有合乎模式的匹配 |
exec() | 對串進行匹配 |
compile() | 編譯正則表達式 |
除了正則表達式對象及字面量外,String對象中也有多個方法支持正則表達式操作。
方法 | 作用 |
---|---|
match | 匹配正則表達式,返回匹配數組 |
replace | 替換 |
split | 分割 |
search | 查找,返回首次發現的位置 |
var str = "life is very much like a mirror."; var result = str.match(/is|a/g);//返回["is", "a"] var str = "Welcome, John"; var result = str.replace(/span/g, "div");//10.正則表達式中括號的作用Welcome, John如果想把Welcome和John兩個單詞調換順序: var result = str.replace(/(w+),s(w+)/g, "$2, $1"); //John,Welcome
括號用來將子表達式標記起來,以區別于其他表達式,比如很多的命令行程序都提供幫助命令,鍵入h和鍵入help的意義是一樣的,那么就會有這樣的表達式:h(elp)?//字符h之后的elp可有可無
括號用來分組,當正則表達式執行完成之后,與之匹配的文本會按規則填入各個分組。
例如:
var pattern = /w{4}(d{4})(w{2})/; var result = pattern.exec("yunn0871cg"); console.log("city code = " + result[1] + ", county code = " + result[2]); //city code = 0871, county code = cg
正則表達式的exec方法會返回一個數組,數組的第一個元素(下標為0)表示整個串,第一個元素為第一個分組,第二個元素為第二個分組;
第三種情況,括號用來對引用起輔助作用,即在同一個表達式中,后邊的式子可以引用前邊匹配的文本。
11.匿名自執行函數有的函數只需要執行一次,其內部變量無需維護,比如UI的初始化,那么我們可以使用閉包。例如:
var datamodel = { table: [], tree: {} }; (function (dm) { for (var i = 0; i < dm.table.rows; i++) { var row = dm.table.rows[i]; for (var j = 0; j < row.cells; i++) { drawCell(i, j); } } })(datamodel);
我們創建了一個匿名的函數,并立即執行它,由于外部無法引用它內部的變量,因此在執行完后很快就會被釋放,最主要的是這種機制不會污染全局對象。
12.緩存設想我們有一個處理過程很耗時的函數對象,每次調用都會花費很長時間,那么我們就需要將計算出來的值存儲起來,當調用這個函數的時候,首先在緩存中查找,如果找不到,則進行計算,然后更新緩存并返回值,如果找到了,直接返回查找到的值即可。閉包可以做到這一點,因為它不會釋放外部的引用,函數內部的值可以得以保留。
var CachedSearchBox = (function () { var cache = {}, count = []; return { attachSearchBox: function (disd) { if (disd in cache) {//如果在緩存中 return cache[disd];//直接返回 } var fsb = new uikit.webctrl.SearchBox(disd);//創建 cache[disd] = fsb;//更新緩存 if (count.length > 100) {//保證緩存的大小小于100個 delete cache[count.shift()];//刪除最前面那個緩存 } return fsb; }, clearSearchBox: function (disd) { if (disd in cache) { cache[disd].clearSelection(); } } } })(); CachedSearchBox.attachSearchBox("input1");13.閉包實現封裝
var person = function () { //變量作用域為函數內部,外部無法訪問 var name = "default"; return { getName: function () { return name; }, setName: function (newName) { name = newName; } } }(); person.name;//undefined person.getName();//default person.setName("aaa"); person.getName();//aaa14.閉包中的this
關于this我們之前已經做過討論,它表示對調用對象的引用,而在閉包中,最容易出現錯誤的地方是誤用了this。在js的開發中,一個常見的錯誤就是將this類比為其他的外部局部變量。
$(function () { var con = $("#div#panel"); this.id = "content"; con.click(function () { alert(this.id);//panel }) });
此處的this.id到底引用著什么呢?很多開發者可能根據閉包的概念,做出錯誤的判斷:content,理由是,this.id顯示的被賦值為content。然而事實上,這個alert會彈出panel,究其原因,就是此處的this,因為調用對象的存在,使得當閉包被調用時(當這個panel的click發生時),this引用的是con這個jQuery對象。而匿名函數中的this.id="content"是對匿名函數本身做的操作。兩個this引用的不是同一個對象。如果想要在事件處理函數中訪問這個值,我們必須做一些改變:
$(function () { var con = $("#div#panel"); this.id = "content"; var self = this; con.click(function () { alert(self.id);//content }) });15.new操作符
在JavaScript中,通過new操作符來作用于一個函數,實質上會發生這樣的動作。
首先,創建一個空對象,然后用函數apply方法,將這個空對象傳入作為apply的第一個參數以及上下文參數。這樣函數內部的this將會被這個空的對象所替代。
var triangle = new Shape("triangle"); //上一句相當于下面的代碼 var triangle = {}; Shape.apply(triangle, ["triangle"]);16.用JavaScript函數實現封裝
function Person(name) { //私有變量 var address = "1"; //公共方法 this.getAddress = function () { return address; }; //公共變量 this.name = name; } //公共方法 Person.prototype.getName = function () { return this.name; }; //公共方法 Person.prototype.setName = function (name) { this.name = name; };
首先聲明一個函數,作為模板,用面向對象的術語來說,就是一個類。用var方式聲明的變量僅在類內部可見,所以address為一個私有成員,訪問address的唯一方法就是通過我們向外暴露的getAddress方法,而get/setName,均為原型鏈上的方法,因此為公開的。我們可以做個測試:
var jack = new Person("jack"); console.log(jack.name);//jack console.log(jack.getName());//jack console.log(jack.address);//undefined console.log(jack.getAddress());//1
添加靜態變量:
function Person(name) { //私有變量 var address = "1"; //公共方法 this.getAddress = function () { return address; }; //公共變量 this.name = name; } Person.TAG = "javascript-core";//在訪問該變量的時候,不需要實例化Person類17.函數式的JavaScript
函數可以保持自己內部的數據,函數的運算對外部無副作用(修改了外部的全局變量的狀態等)。關于函數可以保持自己內部的數據這一特性,成為閉包。示例:
var outter = function () { var x = 0; return function () { return x++; } }; var a = outter(); console.log(a());//0 console.log(a());//1 console.log(a());//2 var b = outter(); console.log(b());//0 console.log(b());//1
變量a通過閉包引用outter的一個內部變量,每次調用a()就會改變此內部變量,應該注意的是,當調用a時,函數outter已經返回了,但是內部變量x的值仍然被保持。而變量b也引用了outter,但是這是一個不同的閉包,所以b開始引用的x值不會隨著a()被調用而改變,兩者有不同的實例,這就相當于面向對象中的不同實例擁有不同的私有屬性,互不干涉。
18.柯里化的概念柯里化就是預先將函數的某些參數傳入,得到一個簡單的函數,但是預先傳入的參數被保存在閉包中,因此會有一些奇特的特性。比如:
var adder = function (num) { return function (y) { return num + y; } }; var inc = adder(1); var dec = adder(-1); console.log(inc(99));//100 console.log(dec(101));//10019.函數式編程風格
通常來講,函數式編程的謂詞(關系運算符,如大于、小于、等于的判斷等),以及運算(加減乘除等)都會以函數的形式出現,比如:
a > b
通常表示為:
gt(a, b)
因此,可以首先對這些常見的操作進行一些包裝,以便我們的代碼更具有“函數式”風格。
如果我們之前的編碼風格是這樣:
//階乘 function factorial(n) { if (n == 1) { return 1; } else { return n * factorial(n - 1); } }
在函數式風格下,就應該是這樣了:
function factorial(n) { if (equal(n, 1)) { return 1; } else { return mul(n, factorial(dec(n))); }` }20.活動對象
在JavaScript中,當一個函數被調用的時候,就會產生一個特殊的對象:活動對象。這個對象中包含了參數列表和arguments對象等屬性。由于活動對象是變量對象的特例,因此,它包含變量對象所有的屬性,如變量定義,函數定義等。
實例:
function func(handle, message) { var id = 0; function doNothing(x) { return x; } handle(message); } func(print, "hello");//執行到這里的時候,活動對象被創建21.作用域鏈
作用域鏈與原型鏈類似,也是一個對象組成的鏈,用以在上下文中查找標識符(變量、函數等)。查找時也與原型鏈類似,如果激活對象本身具有該變量,則直接使用該變量的值,否則向上層搜索,依次類推,直到查找到或者返回undefined。作用域鏈的主要作用是用以查找自由變量。所謂自由變量是指,在函數中使用的,非函數內部局部變量,也非函數內部定義的函數名,也非形式參數變量。這些變量通常來自于函數的“外層”或者全局作用域,比如,我們在函數內部使用的window對象及其屬性。
var topone = "top-level"; (function outter() { var middle = "mid-level"; (function inner() { var bottom = "bot-level"; console.log(topone + ">" + middle + ">" + bottom); })(); })(); //在函數Inner中,console.log語句出現的topone、middle變量就是自由變量22.詞法作用域
在javascript中,函數對象的創建和函數本身的執行是完全不同的兩個過程。
function func() { var x = 0; console.log("func"); }//這是函數的創建 func();//函數的執行
所謂詞法作用域(靜態作用域)是指,在函數對象的創建時,作用域就已經建立,而并非到執行時,因為函數創建后可能永遠不會被執行,但是作用域是始終存在的。比如在上例中,如果在程序中沒有調用func(),那么,func對象仍舊是存在的,在內存的結構可能是這樣的:23.this的上下文
func.["[[scope]]"] = global.["variable object"];
而當函數執行時,進入函數執行期上下文,函數的活動對象被創建,此時的作用域鏈是活動對象和"[[scope]]"屬性的合成。
this值是執行期上下文對象的一個屬性(執行期上下文對象包括變量對象、作用域鏈以及this)。執行期上下文對象有三類,當進入不同的上下文時,this的值會確定下來,并且this的值不能更改。在執行全局代碼時,控制流會進入全局執行期上下文,而在執行函數時,又會有函數執行期上下文。例如:
var global = this; var tom = { name: "Tom", home: "desine", getInfo: function () { console.log(this.name + ", from " + this.home); } }; tom.getInfo(); var jerry = { name: "Jerry", getInfo: tom.getInfo }; jerry.getInfo(); global.getInfo = tom.getInfo; global.getInfo(); 輸出結果: Tom, from desine Jerry, from undefined , from undefined
tom對象本身具有name和home屬性,因此在執行tom.getInfo時,會打印tom對象上的這兩個屬性值。當將global.getInfo屬性設置為tom.getInfo時,getInfo中的this值,getInfo中的this值,在運行時,事實上是global對象,所以name和home均未定義。
24.window對象window對象是對瀏覽器當前窗口的引用,因為瀏覽器會將window與自身繪制出來的窗口綁定起來,我們對window的操作事實上會映射到瀏覽器窗口上。正是瀏覽器本身提供了這種腳本化的能力,我們才有機會通過JavaScript代碼來完成很多操作。25.文檔對象模型(DOM)
DOM即文檔對象模型,它是一個平臺,提供語言無關的API,允許程序訪問并更改文檔的內容、結構以及樣式。HTML文檔是一個樹形的結構,與瀏覽器中的頁面中的結構一一對應。26.事件驅動模型
由于客戶端JavaScript的開發屬于用戶界面開發的范疇,因此使用事件驅動模型就顯得非常自然了。事件驅動的特點在于:代碼塊的運行與否與程序流程無關。而傳統的流式代碼的特點是,從函數的入口進入,依次調用各個子模塊的處理函數,最后退出。這種編程模式主要適用于與UI關系不大的場合,很少有異步的過程,這些特點可能要追溯到計算機程序的最初模型——批處理。27.與服務器端交互(Ajax)
而事件驅動模型主要是面向用戶的,你無法知道用戶會如何使用你的程序,因此就只能通過回調、事件監聽等方式,當用戶做出某個動作時才會觸發之前已經注冊好的監聽器,從而執行相關代碼,而不是順序地執行。甚至在一次運行中,部分代碼始終沒有被觸發,也就根本不會被執行到。
Ajax表示異步JavaScript與XML。事實上,Ajax與XML幾乎沒有任何關系,因為是異步交互,所以用戶的頁面不用刷新,在同一個頁面中,客戶端請求服務數據,當服務數據返回時,通過JavaScript將數據片段填充到頁面的某個部分,即實現了局部刷新。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79984.html
摘要:上一篇文章第二章實戰演練開發網站第九節防止跨站攻擊下一篇文章第三章概念及應用第二節服務端編程的異步特性使得其非常適合服務器的高并發處理,客戶端與服務器的持久連接應用框架就是高并發的典型應用。因為是的標準協議,所以不受企業防火墻的攔截。 上一篇文章:Python:Tornado 第二章:實戰演練:開發Tornado網站:第九節:防止跨站攻擊下一篇文章:Python:Tornado 第三章...
摘要:上一篇文章第三章概念及應用第二節服務端編程下一篇文章第四章網站部署第一節調試模式由于是的標準之一,所以主流瀏覽器的客戶端編程語音已經支持的客戶端編程。此事件發生在收到了來自服務器的消息時。此事件發生在通信過程中有任何錯誤時。 上一篇文章:Python:Tornado 第三章:HTML5 WebSocket概念及應用:第二節:服務端編程下一篇文章:Python:Tornado 第四章:T...
摘要:上一篇文章第三章概念及應用第一節概念下一篇文章第三章概念及應用第三節客戶端編程定義了類用于處理鏈接的請求,應用開發者應該繼承該類并實現其中的函數。通常,這是服務器端編程的核心函數,通過解析收到的消息做出相應的處理。 上一篇文章:Python:Tornado 第三章:HTML5 WebSocket概念及應用:第一節:WebSocket概念下一篇文章: Python:Tornado 第三章...
摘要:作用默認的,直接在當前線程運行總是開啟一個新線程用于密集型任務,如異步阻塞操作,這個調度器的線程池會根據需要增長對于普通的計算任務,請使用默認是一個,很像一個有線程緩存的新線程調度器計算所使用的。這個使用的固定的線程池,大小為核數。 轉載請注明出處:https://zhuanlan.zhihu.com/p/20687307 RxJava系列1(簡介) RxJava系列2(基本概念及使...
閱讀 1391·2023-04-26 03:04
閱讀 2325·2019-08-30 15:44
閱讀 3727·2019-08-30 14:15
閱讀 3507·2019-08-27 10:56
閱讀 2703·2019-08-26 13:53
閱讀 2616·2019-08-26 13:26
閱讀 3075·2019-08-26 12:11
閱讀 3609·2019-08-23 18:21