JavaScript學習筆記

本身看了以爲值得推薦的書:javascript

《JavaScript高級程序設計》css

《深刻理解JavaScript》html

《JavaScript面向對象精要》java

《JavaScript權威指南》相似API書,適合查漏補缺node

其餘參考書:jquery

《JavaScript語言精粹》git

《高性能JavaScript》es6

《JavaScript設計模式》web

《編寫可維護的JavaScript》正則表達式

《你不知道的JS(上卷)》

《你不知道的JS(中卷)》

《你不知道的JS(下卷)》

 

 (由於個人OneNote筆記粘貼到網頁圖片沒法顯示,因此後續將修整)

本筆記導航:

js基礎知識

特殊的數字值

string經常使用方法

Array經常使用方法

this

閉包

嚴格模式

JSON

跨源資源共享

JSONP

JavaScript 正則表達式

Object對象

單單js運行方式

《編寫可維護的JavaScript》學習筆記

JavaScript書籍閱讀筆記

Geolocation

Web Workers

 

ES5

開始支持:

嚴格模式

原生JSON對象

Features include Function.prototype.bind,

Array methods like indexOfforEachmap & filter,

Object methods like definePropertycreate & keys,

the trim method on Strings and many more.

 

js基礎知識

(基本數據類型)原始類型:boolean, number, string, null, undefined,symbol(ES6)

內置對象:Number, String, Boolean , Object,Array,Function,Argument,Date,  RegExp,  Math, Error。

 

JavaScript包括核心(ECMAScript)、文檔對象模型(DOM)、瀏覽器對象模型(BOM)

Javascript=ECMAScript+DOM+BOM

 

 

 

宿主環境有瀏覽器、Node和Adobe Flash 。

 

ECMA-262標準規定了語言的下列組成部分:語法、類型、語句、關鍵字、保留字、操做符、對象。

 

DOM

規定的是如何映射於XML的文檔結構,以便簡化對文檔中任意部分的訪問和操做。

針對HTML的對象和方法。

事件

樣式

遍歷和範圍

SVG(Scalable Vector Graphic, 可伸縮向量圖形)等

 

BOM

彈出新瀏覽器窗口的功能

移動、縮放和關閉瀏覽器窗口的功能

navigator對象

location

screen

cookies

XMLHTTPRequest和IE的ActiveXObject這樣的自定義對象

window

 

 

」 字 符 串 。 例 如 , 瀏 覽 器 在 加 載 下 面 所 示 的 代 碼 時 就 會 產 生 一 個 錨 誤 : function 010rt ( 「 / •cript , , ) C/scrip'* 因 爲 按 照 解 析 嵌 人 式 代 碼 的 規 則 , 當 瀏 覽 器 遇 到 字 符 串 「 < / 「 p [ 時 , 就 會 認 爲 那 是 結 束 的 e/script>-% 籤 。 而 通 過 把 這 個 字 符 串 分 隔 爲 兩 部 分 可 以 解 決 這 個 問 題 . 例 如 : " v:shapes="圖片_x0020_218">

 

 

 

在JavaScript中全部的值都有屬性。每個屬性都有一個key(或者是name)

和一個value。能夠認爲,屬性就像是一條記錄的字段。經過點(.)操做符能夠讀

取屬性、賦值。

 

var objl = {l; > var 0 習 2 = O; / / an empty object / / another empty object > 0b 〕 1 > 0b 」 1 0b 」 2 0b 〕 1 相 反 , 所 有 的 原 始 值 , 只 要 編 碼 值 相 同 , 則 被 認 爲 相 等 : 、 var pri , 1 = 123 ; > var prim2 = 123 ; 、 priml = = = 豇 2 " v:shapes="圖片_x0020_217">

 

console.log(typeof null);   //object, null是一個空的對象指針。 

判斷一個值是否爲空類型:value===null

使用===,是由於三等號在比較時不會將變量強制轉換爲另外一種類型。

(==會把字符串轉換成數字)

 

 

 

string 雖然是原始類型,但也有方法:

console.log(typeof null); // object,null是一個空的對象指針,也能夠認爲是一個bug

console.log("5" === 5); // true

console.log(undefined==null); // 注意三等號會強制類型轉換

var name = "Beth_Chan";

console.log(name.toLowerCase(),name.charAt(0),name.substring(2,5)); // 注意駝峯;索引從0開始;第二個索引不能算進去(左閉右開區間)

var count = 10;

console.log(count.toFixed(2),count.toString(8),count.toString(16)); // 10.00;10轉換成八進制是12,轉換成十六進制是a

var flag = true;

console.log(flag.toString()); // true

 

 

建立對象:

new Object() // new操做符和,=構造函數 指向內存中實際對象所在的指針(或者說引用)

內置(內建build-in)對象:Object,Function,Array,Date,Error,RegExp

 

對象字面形式建立對象,能夠在大括號中定義一個新對象及其屬性,屬性的組成包括一個標識符或字符串、一個冒號以及一個值,多個屬性之間用逗號隔開。

字面形式並無調用new Object(),但JavaScript引擎背後作的工做與new Object()同樣。

 

數組用中括號。

 

JavaScript有垃圾收集功能,使用引用類型時無需擔憂內存分配。解除引用是將對象變量置爲null。

 

對象可隨時添加和刪除屬性。

 

一般不會有人使用函數的構造函數。

 

容許用字面形式而不是使用RegExp構造函數定義正則表達式。

(相似Perl)

模式被包含在兩個「/「之間,第二個」/「後是由單字符表示的額外選項。

使用字面形式不須要擔憂字符串中的轉義字符。

除非須要經過一個或多個字符串動態構造正則表達式,不然建議字面形式。

 

 

function reflect(value) {

return value;

}

console.log(typeof reflect); // function;對於其餘非函數的引用類型,typeof都是返回「object」

var items = [];

var object = {};

function reflect(value) {

return value;

}

// instanceof以一個對象和一個構造函數爲參數

console.log(items instanceof Array);

console.log(items instanceof Object);

console.log(object instanceof Array); // false

console.log(object instanceof Object);

console.log(reflect instanceof Function);

console.log(reflect instanceof Object);

// 全部引用類型都繼承自Object,即全部對象都是Object的實例

Array.isArray(items); // true;鑑別數組(把一個數組從一個框架傳到另外一個框架時,全局上下文不一樣,因此instanceof沒法識別);IE8及更早的版本不支持。

 

 

屬性是對象中保存的名字和值的配對。

點號或中括號(要有引號)都可訪問屬性。例如array.push(123)能夠寫成array["push"](123)。

動態訪問哪一個屬性或者屬性名字有特殊字符時,特別有用。var method = "push"; array[method] (123)。

 

原始封裝類型

原始封裝類型有String,Number,Boolean

當讀取字符串、數字或布爾值時,原始封裝類型將被自動建立。

var name = "cxf";

var firstChar = name.charAt(0);

console.log(firstChar);

背後JavaScript引擎(engine):

var name = "cxf";

var temp = new  String(name); // 自動打包。

var firstChar = temp .charAt(0);

temp = null;

console.log(firstChar);

 

var name = "cxf";

name.last = "Beth";

console.log(name.last); // undefined

背後JavaScript引擎(engine):

var name = "cxf";

var temp = new String(name);

temp.last = "Beth";

temp = null;

var temp = new String(name);

console.log(temp.last);

temp = null;

 

臨時對象僅在值被讀取時建立。

var name = "cxf";

var count = 12;

var found = false;

console.log(name instanceof String); // false

console.log(count instanceof Number); // false

console.log(found instanceof Boolean); // false

instanceof操做符並無真的讀取任何東西。

 

手動建立原始封裝類型,會建立一個object,這意味着typeof沒法鑑別實際保存的數據的類型。

var name = new String("cxf");

var count = new Number(12);

var found = new Boolean(false);

console.log(typeof name); // object

console.log(typeof count); // object

console.log(typeof found); // object

 

 

var found = new Boolean(false);

if(found) {

console.log("Found");

} // 即便是false,也老是被執行。由於一個對象在條件判斷語句中總被認爲是true

 

var found = false;

if(found) {

console.log("Found");

} else {

console.log("Not found");

} // Not found

 

var temp = /[?&][^?&]+=[^?&]+/g;

console.log(typeof temp); // object,正則表達式返回object。

 

函數

函數其實就是對象,使函數不一樣於其餘對象的決定性特色是函數存在一個被稱爲[[Call]]的內部屬性(函數獨有的[[Call]]屬性代表該對象能夠被執行,[[Call]]該內部屬性包含了該函數的執行指令)。ECMAScript定義typeof操做符會在對象內查找這個內部屬性,對任何具備[[Call]]屬性的對象返回「function"

內部屬性沒法經過代碼訪問,而是定義了代碼執行時的行爲。

內部屬性都用雙重中括號來標註。

 

定義函數:(1)經過函數表達式(2)經過函數聲明(3)經過Function構造函數

函數表達式能夠是匿名函數或具名函數表達式(名字只能在內部被訪問,例如遞歸),取而代之一般會被一個變量或屬性引用,將一個函數做爲值賦值給變量,最後多了個分號。

在函數的真實形式直到運行時才能肯定時不得不用Function構造函數。

var add = new Function('x', 'y', 'return x+y'); // 把代碼放在字符串裏(對於工具是不可訪問的)

重要區別就是:函數聲明會被提高至上下文(要麼是 該函數被聲明時所在的函數的範圍,要麼是 全局範圍)的頂部。意味着能夠先使用函數後聲明它們。

(由於JavaScript引擎會將函數聲明放在其做用域最前面,提早知道了函數的名字)

函數聲明是作了徹底(總體)提高,變量聲明是部分提高(只對於聲明有效,賦值過程無效)。

 

 

 

 

function f10 { } 而 者 名 函 數 表 達 式 的 name 則 是 一 個 空 字 符 串 : > var f2 = function 0 { } ; 具 名 函 數 表 達 式 也 有 一 個 name : > var f3 = function myName() 0 ; 函 數 的 名 稱 對 於 debug 是 非 常 有 用 的 。 正 因 如 此 , 有 一 些 開 發 者 往 往 會 給 函 數 表 達 式 加 上 名 字 。 " v:shapes="圖片_x0020_213">

 

 

全部的函數都是對象、Function構造器的實例:

function id(x) {

return x;

}

console.log(id instanceof Function); // true

 

var numbers = [1,5,6,8,2,7,10];

numbers.sort();

console.log(numbers); // [ 1, 10, 2, 5, 6, 7, 8 ];

由於默認狀況下,sort()將數組中每一個對象轉換成字符串,而後進行比較。

numbers.sort(function(first,second) {

return first - second;

});

console.log(numbers); // [ 1, 2, 5, 6, 7, 8, 10 ];

數組的sort()方法接受一個比較函數做爲可選參數。傳遞給sort()的比較函數是一個函數表達式。第一個數小於第二個時返回負數。相等時返回0。

 

只要記住函數就是對象,不少行爲都變得容易理解。

 

JavaScript函數的另外一個獨特之處,在於能夠給函數傳遞任意數量的參數卻不形成錯誤。那是由於,函數參數實際上被保存在一個被稱爲arguments的相似數組的對象中。如同一個普通的JavaScript數組,arguments能夠自由增加,值可經過數字索引來引用。arguments的length屬性會告訴你目前有多少個值。

 

arguments對象自動存在於函數中。也就是說,函數的命名參數不過是爲了方便,並不真的限制該函數可接受函數的個數。

 

注意:arguments對象不是一個數組的實例,其擁有的方法與數組不一樣,Array.isArray(arguments)永遠返回false。

function reflect(value) {

console.log(Array.isArray(arguments)); // false

}

reflect();

 

 

length屬性代表了該函數的指望參數個數。

注意實際傳入的參數的數量不影響函數的指望參數個數。

function reflect(value) {

return value;

}

console.log(reflect("cxf",111)); // cxf

console.log(reflect.length); // 1 不變

 

reflect = function() {

return arguments[0];

}

console.log(reflect("cxf",111)); // cxf

console.log(reflect.length); // 0 不變

若是兩個放一塊兒運行,第一個也是0。

 

 

arguments

 

 

 

 

 

 

可選參數(設默認值):

 

 

例子:求和

function sum() {

var result = 0, i = 0, len = arguments.length; // 會變

while(i < len) {

result += arguments[i];

i++;

}

return result;

}

console.log(sum(1,1)); // 2

console.log(sum()); // 0

console.log(sum(8)); // 8

console.log(sum(4+6+9+1));

 

 

 

p-arseInt('2', 1 ) 總 之 , 當 你 不 明 確 函 數 或 者 方 法 的 調 用 方 式 時 , 你 需 要 格 外 注 意 。 一 旦 你 要 使 用 這 些 函 數 , 你 就 要 格 外 明 確 函 數 接 受 哪 些 參 數 , 同 時你會傳入哪些參數@ 這 是 我 們 通 過 回 調 來 實 現 的 方 式 · 歹 l.map(function ( { return parselnt(). 茈 ) } ) " v:shapes="圖片_x0020_207">

 

 

 

 

 

變量的做用域是指變量在何處能夠被訪問到。

之前只有函數級做用域,ES6後有塊級做用域了(塊就是指{}包圍的範圍)。

function { 、 不 e t 「 . C strictFunc() ReferenceError: X 飛 、 not 竺 123 〕 " v:shapes="圖片_x0020_205">

 

 

 

 

 

 

 

 

 

 

 

IIFE改造:

 

 

 

全局對象

getAllPropertyNames(window) . SO 「 t() .sltce(), 5 ) [ •AnalyserNode', •Array', •ArrayBuffer•, 'Attr', 'Audio' 〕 JavaScript 之 父 BrendanEich 認 爲 全 局 對 象 的 設 計 是 他 「 最 大 的 遺 憾 六 它 影 響 了 性 能 , 使 得 變 量 的 做 用 域 的 實 現 變 得 更 爲 復 雜 , 並 且 導 致 模 塊 化 代 碼 的 減 少 。 16 . 8 , 1 跨 平 臺 兼 容 瀏 覽 器 和 Node.js 都 有 一 些 全 局 的 變 量 可 以 引 用 全 局 的 對 象 。 不 幸 的 是 , 它 們 是 不 一 樣 的 : 。 瀏 覽 器 中 的 全 局 對 象 是 麗 nd 。 w , 它 是 文 檔 對 象 模 型 (DOM) 的 一 部 分 , 而 非 ECMAScnpt 5 的 一 部 分 。 在 每 一 個 幀 或 者 window 中 , 都 有 一 個 全 局 對 象 。 Node.js 中 的 全 局 對 象 是 global , 它 是 一 個 Node.js 專 屬 的 變 量 。 每 一 個 模 塊 都 有 它 自 己 的 做 用 域 , 在 這 些 做 用 域 中 this 指 向 了 這 個 做 用 域 的 對 象 。 因 此 , 乜 h 和 global 在 模 塊 中 是 不 同 的 。 在 兩 個 平 臺 上 , this 都 指 向 全 局 對 象 , 但 是 這 僅 僅 是 在 全 局 做 用 域 中 。 而 這 在 Node.js 中 是 不 可 能 的 。 如 果 你 想 用 一 種 跨 平 臺 的 方 式 來 訪 問 全 局 對 象 , 你 可 以 像 下 面 這 樣 作 : (function ( 醮 0b ) { / / glob PO 亡 5 to global 0b 丿 'undefined , ? window : global) ) ; )(typeof Hindow ! = = " v:shapes="圖片_x0020_198">

 

 

 

 

 

 

function sayMessage(message) {

console.log(message);

}

function sayMessage() {

console.log("Default message");

}

sayMessage("Hello"); // Default message

同名函數,只有最後定義的有效,以前的函數聲明被徹底刪除。

用對象來幫助理解:

var sayMessage = new Function("message","console.log(message);");

sayMessage = new Function("console.log(\"Default message\");")

sayMessage("Hello"); // sayMessage連續賦了兩次函數對象,第一個天然丟失了。

能夠用arguments對象獲取傳入的參數個數並決定怎麼處理。

即:

if (arguments.length === 0) {

message = "Default message";

}

console.log(message);

 

注意:在實際使用中,檢查命名參數是否爲未定義比依靠arguments.length更常見。

 

若是屬性的值是函數,則該屬性被稱爲方法。

能夠像添加屬性那樣給對象添加方法。

var person = {

name: "cxf",

sayName: function() {

console.log(this.name); // 不要用person,改變變量名就必須改變方法裏引用的名字,這種緊耦合很差,因此要用this。

}

};

person.sayName(); // cxf

全部函數做用域內都有一個this對象表明調用該函數的對象。

在全局做用域中,this表明全局對象(瀏覽器裏的window)。

當一個函數做爲對象的方法被調用時,默認this的值等於那個對象。

this可避免緊耦合,要是改person,就總是得改對應引用的話,會很麻煩。

function sayNameForAll() {

console.log(this.name);

}

var person1 = {

name: "cxf",

sayName: sayNameForAll

};

var person2 = {

name: "Beth",

sayName: sayNameForAll

};

var name = "Tone";

person1.sayName(); // cxf

person2.sayName(); // Beth

sayNameForAll(); // undefined; 爲何?

this在函數調用時才被設置。

 

改變this:

call()

apply()

bind()

 

 

 

 

 

改變屬性特徵,可以使用Object.defineProperty(擁有該屬性的對象,"屬性名", )

 

 

 

整數和浮點數(國際標準 IEEE 754)

JavaScript 內部,全部數字都是以64位浮點數形式儲存,即便整數也是如此。因此,1與1.0是相同的,是同一個數。

 

因爲浮點數不是精確的值,因此涉及小數的比較、運算要特別當心。

 

 

最佳實踐是不要直接比較非整數

取而代之,將邊界錯誤的上界(機器精度)考慮進來,對於雙精度一個標準的精度值是2的-53次方:

 

 

 

%是求餘,不是取模,由於它會返回與第一個操做數符號相同的值。

+number 保持參數不變;非數字會被轉換成數字

 

 

特殊的數字值:

  1. 1.    兩個錯誤值:NaN 和 Infinity
  2. 2.    兩個零值:+0 -0(一個數字的正負號和數值是分開存儲的)

 

NaN:

  1. 1.    NaN是惟一一個和自身不相等的值

 

Array.prototype.indexOf也使用了嚴格相等(===),所以不能經過該方法在數組中查找NaN

 

若是要檢查一個值是不是NaN,必須使用全局函數isNaN()

 

對非數字不起做用,由於它首先作的是把值轉換成數字,轉換可能生成NaN,而後函數會錯誤地返回true

 

所以,最好的檢驗NaN的方法是將isNaN和typeof類型檢查組合起來:

 

或者,利用NaN是惟一一個與自身不相等的特色,來檢驗NaN:

 

  1. 2.    NaN("Not a Number")是一個數字

 

  1. 3.    一個不能被解析的數字

Number( 'xyz') UaN > Number (undefined) UaN " v:shapes="圖片_x0020_184">

對比:

 

  1. 4.    失敗的操做

Math acos (2) UaN > Math. log(-l) UaN > Math. sqrt(-l) UaN " v:shapes="圖片_x0020_182">

  1. 5.    一個運算數是NaN(這樣能夠確保,若是在一個較長的運算中發生了錯誤,能夠在最後結果中看到)

25 / NEN " v:shapes="圖片_x0020_181">

 

Infinity

兩種錯誤:大到沒法表示的數字;或者除以0

 

1)Infinity比任何數(除了NaN)大,-Infinity比任何數(除了NaN)小,因此須要最大值或最小值時能夠當默認值

-Infinity>426332222222222222222 false > -Infinity<3 true " v:shapes="圖片_x0020_180">

 

都是false

Nan false -Infinity < NON false Infinity < Nau false -Infinity > Nan false " v:shapes="圖片_x0020_179">

 

 

2)巨大的數字

指數必須在-1023到1024之間(開區間)

Math. pow(2, 1Ø24) 1023) 8 .98846567431158±+307 " v:shapes="圖片_x0020_177">

不知道爲何沒有-Infinity:

Math. pow(2, -1023) 1.1125369292536ae7e-308 > Math. pow(2, -1024) s .562684646268003±- 309 > Math. pow(2, -1025) 2 .781342323134±-309 " v:shapes="圖片_x0020_176">

(3)被0除

-Ile -Infinity " v:shapes="圖片_x0020_175">

 

對比:

 

(4)Infinity的運算

若是嘗試用一個Infinity「抵消」另外一個Infinity的時候,會獲得錯誤的結果NaN:

Infinity - Infinity > Infinity / Infinity UaN " v:shapes="圖片_x0020_172">

若是試圖獲得大於Infinity的書,獲得的仍然是Infinity:

Infinity + Infinity Inf nity > Infinity * Infinity Infinity " v:shapes="圖片_x0020_171">

(5)檢查Infinity

嚴格相等和寬鬆相等都適用於Infinity:

 

附:全局函數isFinite()能夠檢查一個值是不是實際的值(既不是Infinity也不是NaN):

 

 

 

 

 

 

 

 

 

 

 

( -a) . toString() > (+0) . toString() > e. toString() O Uncaught SyntaxError: Invalid or unexpected token " v:shapes="圖片_x0020_163">

 

6..toString(2) 「110「" v:shapes="圖片_x0020_162">

聽從IEEE754雙精度浮點數標準,在js中咱們一般寫0,這意味着+0,可是它也意味着是-0

要記住和「.」點操做符區分開,要否則容易報錯。爲了區分有時要用兩個"."

+0和-0大部分時候是同樣的,都是0,可是也能夠區分兩個0:

除以兩個0

 

判斷兩個0不一樣的權威方法是除以0:

 

還有其餘能夠區別的:

Math.pow()

Math.atan2()

 

 

 

string經常使用方法

    //concat() – 將兩個或多個字符的文本組合起來,返回一個新的字符串。
    var str = "Hello";
    var out = str.concat(" World","!");
    console.log(str); //Hello
    console.log(out); //Hello World!

//charAt() – 返回指定位置的字符。
    var str = "HelloString";
    var out = str.charAt(1);
    console.log(out); //e

//charCodeAt() – 返回在指定的位置的字符的 Unicode 編碼。
    var str = "HelloString";
    var out = str.charCodeAt(5);
    console.log(out); //83

//indexOf(searchvalue,fromindex) – 返回字符串中一個子串第一處出現的索引,若是沒有匹配項,返回 -1 。
    //fromindex是可選的整數參數。規定在字符串中開始檢索的位置。它的合法取值是 0 到 stringObject.length - 1。
    //如省略該參數,則將從字符串的首字符開始檢索,此時indexOf()跟search()方法相似。
    var str = "HelloStringend";
    console.log(str.indexOf("e")); //1
    console.log(str.indexOf("e",2)); //11

//lastIndexOf(searchvalue,fromindex) – 返回字符串中一個子串最後一處出現的索引,若是沒有匹配項,返回 -1 。
    //若是在 stringObject 中的 fromindex 位置以前存在 searchvalue,則返回的是出現的最後一個 searchvalue 的位置。
    var str = "HelloString";
    console.log(str.lastIndexOf("l")); //3
    console.log(str.lastIndexOf("l", 1)); //-1
    console.log(str.lastIndexOf("l", 2)); //2
    console.log(str.lastIndexOf("l", 3)); //3

//substring(start,end) – 返回一個新的字符串,包括 start 處的字符,但不包括 end 處的字符,其長度爲 end 減 start
    //substring是以兩個參數中較小一個做爲起始位置,較大的參數做爲結束位置。
    //注意:若是參數是負數,substring則會將負參數都直接轉換爲0,若是僅有一個參數,則從start開始到末尾。
    var str = "HelloExample";
    console.log(str); //HelloExample
    console.log(str.substring(1, 3)); //el
    console.log(str.substring(3, 1)); //el
    console.log(str.substring(2)); //lloExample
    console.log(str.substring(-1)); //HelloExample
    console.log(str.substring(-1, -3)); //空字符串
    console.log(str.substring(-1, 5)); //Hello

//substr(start [,length]) – 返回一個新的字符串,從起始索引號提取字符串中指定數目的字符。
    //若是僅有一個參數,則從start開始到末尾。
    //當接收的參數是負數時,substr是將第一個參數與字符串長度相加後的結果做爲第一個參數
    var str = "HelloExample";
    console.log(str); //HelloExample
    console.log(str.substr(1, 3)); //ell
    console.log(str.substr(2, -1)); //空字符串
    console.log(str.substr(1)); //elloExample
    console.log(str.substr(-4, 2)); //mp
    console.log(str.substr(-3)); //ple

//stringObject.slice(start,end) 返回一個新的字符串,包括 start 處的字符,但不包括 end 處的字符,其長度爲 end 減 start
    //當接收的參數是負數時,slice會將它字符串的長度與對應的負數相加,結果做爲參數。若是僅有一個參數,則從start開始到末尾。
    var str = "HelloExample";
    console.log(str); //HelloExample
    console.log(str.slice(1, 3)); //el
    console.log(str.slice(2)); //lloExmaple
    console.log(str.slice(3, 1)); //空字符串
    console.log(str.slice(-4, -1)); //mpl
    console.log(str.slice(-4, 0)); //空字符串
    console.log(str.slice(-1, -4)); //空字符串
    console.log(str.slice(1, -4)); //elloExa

//toLowerCase() – 將整個字符串轉成小寫字母。
    //toLowerCase() – 將整個字符串轉成小寫字母。
    var str = "How Are you";
    console.log(str.toLowerCase()); //how are you
    console.log(str.toUpperCase()); //HOW ARE YOU

/***********************************************/
    /********支持正則表達式的 String 對象的方法*****/
    /***********split,match,replace,search**********/
    /***********************************************/
    //stringObject.split(separator,howmany),返回一個字符串數組。該數組是經過在 separator 指定的邊界處將字符串 stringObject 分割成子串建立的。返回的數組中的字串不包括 separator 自身。
    var str = "How are you doing today";
    console.log(str.split(" ")); //["How", "are", "you", "doing", "today"]
    console.log(str); //How are you doing today
    console.log(str.split("")); //["H", "o", "w", " ", "a", "r", "e", " ", "y", "o", "u", " ", "d", "o", "i", "n", "g", " ", "t", "o", "d", "a", "y"]
    console.log(str.split("", 3)); //["H", "o", "w"]
    console.log(str.split("a")); //["How ", "re you doing tod", "y"]
    console.log(str.split("good")); //["How are you doing today"]
    var str = "a_db-c(d+e";
    console.log(str.split(/[^a-z]/i)); //["a", "db", "c", "d", "e"]

/** match(searchvalue) 或 match(regexp)檢查一個字符串是否匹配一個正則表達式。返回存放匹配結果的數組。
    match() 方法將檢索字符串 stringObject,以找到一個或多個與 regexp 匹配的文本。這個方法的行爲在很大程度上有賴於 regexp 是否具備標誌 g。
    若是 regexp 沒有標誌 g,那麼 match() 方法就只能在 stringObject 中執行一次匹配。若是沒有找到任何匹配的文本, match() 將返回 null。不然,它將返回一個數組,其中存放了與它找到的匹配文本有關的信息。該數組的第 0 個元素存放的是匹配文本,而其他的元素存放的是與正則表達式的子表達式匹配的文本。除了這些常規的數組元素以外,返回的數組還含有兩個對象屬性。index 屬性聲明的是匹配文本的起始字符在 stringObject 中的位置,input 屬性聲明的是對 stringObject 的引用。
    若是 regexp 具備標誌 g,則 match() 方法將執行全局檢索,找到 stringObject 中的全部匹配子字符串。若沒有找到任何匹配的子串,則返回 null。若是找到了一個或多個匹配子串,則返回一個數組。不過全局匹配返回的數組的內容與前者大不相同,它的數組元素中存放的是 stringObject 中全部的匹配子串,並且也沒有 index 屬性或 input 屬性。
    **/
    var str = "Hello world! Hello";
    console.log(str.match("lo")); //["lo"] { index: 3, input: "Hello world! Hello" }
    console.log(str.match("world")); //["world"] { index: 6, input: "Hello world! Hello" }
    console.log(str.match("world").index); //6
    console.log(str.match(/Hello/g)); //["Hello", "Hello"]
    console.log(str.match("World")); //null
    var str = "1 plus 2 equal 3";
    console.log(str.match(/\d+/g)); //["1", "2", "3"]

//replace() 方法用於在字符串中用一些字符替換另外一些字符,或替換一個與正則表達式匹配的子串。
    //stringObject.replace(regexp/substr,replacement),返回一個新的字符串,是用 replacement 替換了 regexp 的第一次匹配或全部匹配以後獲得的。
    //replacement 能夠是字符串,也能夠是函數。若是它是字符串,那麼每一個匹配都將由字符串替換。可是 replacement 中的 $ 字符具備特定的含義,它說明從模式匹配獲得的字符串將用於替換。
    //  $一、$二、...、$99----與 regexp 中的第 1 到第 99 個子表達式相匹配的文本。
    //  $&------------------與 regexp 相匹配的子串。
    //  $`------------------位於匹配子串左側的文本。
    //  $'------------------位於匹配子串右側的文本。
    //  $$------------------直接量符號。
    var str = "Visit HangZhou";
    console.log(str); //Visit HangZhou
    console.log(str.replace(/Hang/g, "Su")); //Visit SuZhou
    var str = "1 plus 2 equal 3";
    console.log(str); //1 plus 2 equal 3
    console.log(str.replace(/(\d)/g, "*"));  //* plus * equal *

var str = "as An angle";
    console.log(str.replace(/a/, "b")); //bs An angle
    console.log(str.replace(/a/g, "b")); //bs An bngle
    console.log(str.replace(/a/gi, "b")); //bs bn angle

var str = "Karl,John";
    console.log(str.replace(/(\w+)\s*,\s*(\w+)/, "$2,$1")); //John,Karl

var str = '"ab", "b"';
    console.log(str.replace(/"([^"]*)"/g, "'$1'")); //'ab', 'b'

var str = "aaa bbb ccc";
    console.log(str.replace(/\b\w+\b/g, function (w) {
        return w.substring(0, 1).toUpperCase() + w.substring(1);
    })); //Aaa Bbb Ccc

//search() – 執行一個正則表達式匹配查找。若是查找成功,返回字符串中匹配的索引值。不然返回 -1 。
    //stringObject.search(regexp) 返回stringObject 中第一個與 regexp 相匹配的子串的起始位置。
    //此方法跟indexOf相似。此方法會忽略g標識
    var str = "Visit HangZhou";
    console.log(str) //Visit HangZhou
    console.log(str.search(/Hang/)); //6
    console.log(str.search(/hang/)); //-1
    console.log(str.search(/hang/i)); //6
    var str = "1 plus 2 equal 3";
    console.log(str) //1 plus 2 equal 3
    console.log(str.search(/\d/g)); //0

 

 

 

 

Array

數組字面量

數組最後的逗號(trailing comma)會被忽略

索引訪問和length屬性

arr[arr.length] = 'cxf'; // append an element 添加一個元素

arr.push('cxf'); // 另外一種添加元素的方法

 

 

 

 

 

 

 

經常使用方法

Array對象經常使用方法中:

 

不改變原數組:

一、 concat()

鏈接兩個或多個數組

不改變原數組

返回被鏈接數組的一個副本

 

二、join()

把數組中全部元素放入一個字符串

不改變原數組

返回字符串

 

三、 slice()

從已有的數組中返回選定的元素

不改變原數組

返回一個新數組

 

四、 toString()

把數組轉爲字符串

不改變原數組

返回數組的字符串形式

 

改變原數組(破壞性):

五、 pop()

刪除數組最後一個元素,若是數組爲空,則不改變數組,返回undefined

改變原數組

返回被刪除的元素

六、 push()

向數組末尾添加一個或多個元素

改變原數組

返回新數組的長度

 

七、 reverse()

顛倒數組中元素的順序

改變原數組

返回該數組

 

八、 shift()

把數組的第一個元素刪除,若空數組,不進行任何操做,返回undefined

改變原數組

返回第一個元素的值

 

九、 sort()

對數組元素進行排序(ascii)

改變原數組

返回該數組

 

十、 splice()

從數組中添加/刪除項目

改變原數組

返回被刪除的元素

 

十一、 unshift()

向數組的開頭添加一個或多個元素

改變原數組

返回新數組的長度

 

indexOf

sort

 

forEach

every

some

 

 

映射函數map和歸約函數reduce

map轉化方法接收一個輸入數組,輸出一個數組。所謂映射,是指它能夠遍歷數組,而且將函數應用於每一個元素(好比forEach)。可是他不是丟棄函數返回值,而是利用這些返回值從新創建一個新的數組。

reduce()即歸約函數(reduce or fold摺疊)經過重複調用一個函數//(該函數將數組的每一個元素都加到一個基值上),將數組轉化爲單一值。

 

forEach在一些類庫的實現是.each

 

this

 

 

 

 

 

 

 

 

 

 

 

 

用div[i]得用閉包傳參。

 

 

 

 

 

 

 

 

 

alert出100

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

構造函數:

 

 

new test後,實例化了一個對象,this就是指向這個test對象,不是指向window了,

 

 

 

 

 

 

 

 

 

 

因此相似生活中的案例,直接指明(不推薦)

 

 

 

推薦:

 

 

 

閉包

什麼是閉包?

在個人理解裏,就是嵌套的函數,且外部函數返回內部函數,即可以讀取其餘函數內部變量的函數。在本質上,閉包就是將函數內部和函數外部鏈接起來的一座橋樑。

下面就是典型的例子:

function outerf() {

var a = 5;

function innerf() {

a++;

alert(a);

}

return innerf;

}

var f = outerf();

f(); // 6

f(); // 7

也能夠寫成下面這種形式(即內部函數是匿名函數):

function outerf() {

var a = 5;

return function() {

a++;

alert(a);

}

}

var f = outerf();

f(); // 6

f(); // 7

另外還能夠這樣:

 

而普通函數是:

function f() {

var a = 5;

a++;

alert(a);

}

f(); // 6

f(); // 6

 

每次執行f()後a變量都會被回收。

 

咱們都知道,內部函數能夠引用外部函數的參數和變量。相反則不能。

function f() {

var a = 1;

}

alert(a); // a is not defined

 

普通函數一旦被執行,它的參數和變量就會被JS中的垃圾回收機制回收;但使用閉包時,即便外部函數被執行了,內部函數的引用還在,因此參數和變量仍是在內存裏。

 

閉包有什麼好處/優勢?有哪些應用/用途?

(容許函數訪問局部做用域以外的數據)

好處:

  1. 變量長期儲存在內存裏。
  2. 避免全局變量的污染。
  3. 模擬私有成員/私有方法

var counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  };  
})();

console.log(counter.value()); // logs 0
counter.increment();
counter.increment();
console.log(counter.value()); // logs 2
counter.decrement();
console.log(counter.value()); // logs 1

或寫成下面這種形式:

 

用法:

  1. 模塊化代碼
  2. 能夠讀取函數內部的變量
  3. 讓這些變量的值始終保持在內存中

eg: 在循環中直接找到對應元素的索引

若是是下面這樣寫,都是同一個數,也就是ALi.length。(只有點擊纔會觸發,而後循環已經結束)

<ul>

  <li> index = 0 </li>

  <li> index = 1 </li>

  <li> index = 2 </li>

  <li> index = 3 </li>

</ul>

<script type="text/javascript">

  var nodes = document.getElementsByTagName('li');

  for(i = 0;i<nodes.length;i+=1) {

      nodes[i].onclick = function() {

          console.log(i+1); //不使用閉包的話,值每次都是4

      }(4);

   }

</script>

 

 

 

閉包的解決是:

 

 

會返回0,1 ,2……

也能夠寫成下面的形式:

 

 

一開始的典型例子能夠變形爲下面這樣,也叫模塊化代碼:

 var f = (function() {

         var a = 5;

         return function() {

                 a++;

                 alert(a);

         }

 })();

 f(); // 6

 f(); // 7

 

當即執行函數:加個括號變成表達式,而後加個括號執行。

(function() {

var a = 1;

alert(a);

})();

或者加個名字:

(function f() {

var a = 1;

alert(a);

})();

 

注意下面的波浪線區別:

 

 

閉包須要注意的地方有哪些?

  1. 閉包在IE中會引起內存泄露(因爲閉包會使得函數中的變量都被保存在內存中,內存消耗很大,因此不能濫用閉包,不然會形成網頁的性能問題,在IE中可能致使內存泄露。解決方法是,在退出函數以前,將不使用的局部變量所有刪除。)

解決方法相似這樣:

 

 

或者:

 

 

 

  1. 閉包會在父函數外部,改變父函數內部變量的值。因此,若是你把父函數看成對象(object)使用,把閉包看成它的公用方法(Public Method),把內部變量看成它的私有屬性(private value),這時必定要當心,不要隨便改變父函數內部變量的值。(這句話不理解)

 

理解鞏固:

例子1:

var name = "The Window";

 

  var object = {

  name : "My Object",

 

  getNameFunc : function(){

  var that = this;

  return function(){

  return that.name;

  };

 

  }

 

  };

 

  alert(object.getNameFunc()()); // My Object

 

 

例子2:

 

       var name = "The Window";

 

  var object = {

  name : "My Object",

 

  getNameFunc : function(){

  return function(){

  return this.name;

  };

 

  }

 

  };

 

  alert(object.getNameFunc()()); // The Window   函數中的this通常是指向window中的變量。即this的指向是由它所在函數調用的上下文決定的,而不是由它所在函數定義的上下文決定的。

若是非要指向object,還能夠把代碼的最後一句改成 alert(object.getName().call(object));

 

嚴格模式

"use strict"

針對腳本文件,將"use strict"放在腳本第一行,則整個腳本都將以「嚴格模式」運行,不在第一行則無效,以「普通模式」運行;(不利於文件合併)

針對單個函數,將"use strict"放在函數體第一行,則整個函數都將以「嚴格模式」運行。

將整個腳本文件放在一個當即執行的匿名函數中最好。

(

function() {

"use strict";

}

)();

 

 

 

區別:

嚴格模式:

變量必須經過var進行聲明,不然將會報錯。

 

示例:

"use strict";

x = 1;

console.log(x); // ReferenceError: x is not defined

 

"use strict";

for(var i=0;i<10;i++) {

console.log(i);

}

 

 

爲了讓代碼更安全,禁止this關鍵字指向全局對象。

this從普通模式的window變成嚴格模式的undefined

 

示例:

eval("var a = 200; console.log(a);"); // 200

console.log(a); // 200

 

"use strict";

var fn = function() {

console.log(this); // undefined

}

fn();

 

因此,構造函數只要不經過new實例化對象,那麼就會直接報錯,由於undefined沒法設置屬性。

"use strict";

var Cat = function(name) {

this.name = name;

this.say = function() {

console.log(this.name);

}

};

Cat("咪咪");

window.say(); // Uncaught TypeError: Cannot set property 'name' of undefined

 

 

爲了讓代碼更安全,禁止刪除變量。

示例:

var x = 111;

delete x;

console.log(x); // SyntaxError: Delete of an unqualified identifier in strict mode.

 

"use strict";

var obj = {};

obj.y = 10;

delete obj.y;

console.log(obj.y); // undefined

 

普通模式下,若是對象有多個重名屬性(重名函數能夠用arguments[i]讀取),最後賦值的那個屬性會覆蓋前面的值,嚴格模式下,這屬於語法錯誤。

"use strict";

var obj = {

x: 200,

x: 300

};

console.log(obj);

都是300,爲何?

 

 

普通模式下,JS語言有兩種變量做用域(scope):全局做用域和函數做用域;嚴格模式創設了第三種做用域:eval做用域。

嚴格模式下,eval語句自己就是一個做用域。它所生成的變量只能用於eval內部。

"use strict";

eval("var a = 200; console.log(a);");

console.log(a); // ReferenceError: a is not defined

 

var fn = function() {

eval("var x = 100");

console.log(x); // 100

}

fn();

 

"use strict";

var fn = function() {

eval("var x = 100");

console.log(x); // ReferenceError: x is not defined

}

fn();

 

arguments對象的限制

arguments是函數的參數對象,嚴格模式對它的使用作了限制

一、不運行對arguments賦值

二、arguments再也不追蹤參數的變化

三、禁止使用arguments.callee,這意味着,咱們沒法在匿名函數內部調用自身(遞歸)了

 

禁用with關鍵字

當代碼執行到with語句時,執行環境的做用域鏈臨時被改變。一個新的變量對象被建立,它包含了參數指定的對象的全部屬性。這個對象被推入做用域鏈的首位,這意味着函數的全部局部變量處於第二個做用域鏈對象中,所以訪問的代價變高了。

示例:

"use strict";

var obj = {};

obj.a = 1;

obj.b = 2;

with(obj) {

console.log(a + b); // SyntaxError: Strict mode code may not include a with statement

}

 

不容許使用關鍵字

爲了向未來JavaScript的新版本過渡,嚴格模式新增了一些保留字:implements, interface, let, package, private, protected, public, static, yield

 

示例:

var extends = "我是extends";

console.log(extends);

報錯:

SyntaxError: Unexpected token extends

 

// "use strict";

var interface = "我是interface";

console.log(interface); // 我是interface

 

"use strict";

var interface = "我是interface";

console.log(interface);

報錯:

SyntaxError: Unexpected strict mode reserved word

 

爲了讓代碼更安全,禁止在函數內部遍歷調用棧

示例:

// "use strict";

var fn = function() {

console.log(arguments.length);

}

fn("abc","123"); // 2 兩種模式都是2 爲何?

 

嚴格模式下,對禁止擴展的對象添加新屬性,會報錯。

示例:

"use strict";

var obj = {};

obj.x = 1;

Object.preventExtensions(obj);

obj.y = 2;

console.log(obj); // TypeError: Can't add property y, object is not extensible

普通模式下,不會報錯,只會默默失敗。

 

 

禁止八進制表示法

示例:

"use strict";

var obj = 0100; // 64

console.log(obj); // SyntaxError: Octal literals are not allowed in strict mode.

 

函數必須聲明在頂層(如今好像能夠了)

示例:

"use strict";

var a = 1;

if (a>0) {

(function() {

console.log("行");

})();

}

 

"use strict";

var a = 1;

if (a>0) {

function fn() {

console.log("不行");

}

fn();

}

 

 

setTimeout(函數,毫秒數)

 

編譯是將代碼轉換成適合計算機的表示方式,一般可改善運行階段性能。

 

一開始時是解釋型->即時編譯

 

標準語言定義

 

HTML(內容和結構)和css(樣式)是聲明型的,js是行爲(計算)

 

 

 

 

document.getElementById('pox').style.color = 'red';

 

onclick="***()"

 

用[]而不是.能夠使用有特殊符號的屬性

 

 

 

 

 

 

 

 

結果是大桃花。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

給Object加就都有了。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

javascript有對象,沒有類(但有構造函數)。

 

 

 

 

 

私有屬性和封裝:

 

 

 

 

 

JavaScript包括 ECMAScript, DOM, BOM

 

 

2 JavaScript 的 基 本 類 型 有 string, number, boolean,undefined,null

3 . JavaScript 的 復 合 類 型(對象類型) 有  Object,Array,Number, String, Boolean , Function,Argument,Date,  RegExp, Math,Error。

(JavaScript的對象是鍵值對的集合)

4 . JavaScript 還 有 兩 個 空 類 型 : undefined 和 null

5 . JavaScript 中 獲 得 類 型 的 運 算 符 是 typeof, 使 用 該 運 算 符 返 回 什 麼 數 據 類 型 ? string

6 . JavaScript 中 = = = 和 = = 有 什 麼 區 別 ? 全等是既比較值,又比較類型。

7 . JavaScript 中 in 運 算 符 有 什 麼 用 ?  判斷一個對象是否具備某一個屬性。還有for ( var i in object )用法。

 

& JavaScript 的 條 件 運 算 符 是

 

9 . JavaScript 中 創 建 對 象 使 用 運 算 符

 

 

 

 

例子:(副本與快捷方式的區別)

 

10 . JavaScript 什 麼 叫 邏 輯 中 斷 :

 

 

瀏覽器可直接設斷點,刷新,點擊箭頭或F11執行下一步,VM是內部提供的虛擬機,F10跳過,watch或鼠標放變量上或直接出來(新瀏覽器)等。

能夠直接if (num)也能夠直接三元運算符,更好更簡單的方法是邏輯(短路)||:

 

 

 

 

 

 

 

1 1 . JavaScript 中 delete 運 算 符 的 做 用 是

 

 

false true 1 m is not defined " v:shapes="圖片_x0020_78">

arr[2]的位置是undefined,arr.length仍是4

12 . JavaScript 中 循 環 語 旬 有 種 . 分 別 是 .

13 . JavaScript 中 分 支 語 句 有種 、 分 別 是 :

1 生 JavaScripv 中 跳 轉 語 句 break 與 continuega 何 使 用 ?

 

 

 

 

 

 

 

 

 

 

 

 

有等號是表達式。例如a = 100 例如

加分號不是表達式,是語句。

 

 

 

 

 

for while do-while for-in

if-else switch

break跳出循環 continue跳出本次循環

 

 

 

JSON

JSON,全稱是 JavaScript Object Notation,即 JavaScript 對象標記法。

 

JSON 是一種輕量級(Light-Weight)、基於文本的(Text-Based)、可讀的(Human-Readable)格式。

 

JSON 的名稱中雖然帶有 JavaScript,但這是指其語法規則是參考 JavaScript 對象的,而不是指只能用於 JavaScript 語言。

 

JSON 不管對於人,仍是對於機器來講,都是十分便於閱讀和書寫的,並且相比 XML (另外一種常見的數據交換格式),文件更小,所以迅速成爲網絡上十分流行的交換格式。

 

近年來 JavaScript 已經成爲瀏覽器上事實上的標準語言,JavaScript 的風靡,與 JSON 的流行也有密切的關係。

 

由於 JSON 自己就是參考 JavaScript 對象的規則定義的,其語法與 JavaScript 定義對象的語法幾乎徹底相同。

 

JSON 格式的創始人聲稱此格式永遠不升級,這就表示這種格式具備長時間的穩定性,10 年前寫的文件,10 年後也能用,沒有任何兼容性問題。

 

2. JSON 的語法規則是怎樣的

 

JSON 的語法規則十分簡單,可稱得上「優雅完美」,總結起來有:

 

- 數組(Array)用方括號(「[]」)表示。

- 對象(Object)用大括號(」{}」)表示。

- 名稱/值對(name/value)組合成數組和對象。

- 名稱(name)置於雙引號中,值(value)有字符串、數值、布爾值、null、對象和數組。

- 並列的數據之間用逗號(「,」)分隔

 

{

"name": "Geoff Lui",

"age": 26

}

3. JSON 和 XML

 

JSON 常被拿來與 XML 作比較,由於 JSON 的誕生原本就多多少少要有取代 XML 的意思。相比 XML,JSON 的優點以下:

 

- 沒有結束標籤,長度更短,讀寫更快

- 可以直接被 JavaScript 解釋器解析

- 能夠使用數組

 

JSON:

 

{

"name": "Geoff Lui",

"age": 26,

"friends": ["Lily", "Lucy", "Gwen"]

}

 

XML:

 

<root>

<name>Geoff Lui</name>

<age>26</age>

<friends>Lily</friends>

<friends>Lucy</friends>

<friends>Gwen</friends>

</root>

 

 

4. JSON 解析和生成

 

在 JavaScript 中,有兩個方法與此相關: JSON.parse 和 JSON.stringify 。

 

語法

上一課提到的 JSON 的五點語法:

 

- 數組(Array)用方括號(「[]」)表示。

- 對象(Object)用大括號(」{}」)表示。

- 名稱/值對(name/value)之間用冒號(」:」)隔開。

- 名稱(name)置於雙引號中,值(value)有字符串、數值、布爾值、null、對象和數組。

- 並列的數據之間用逗號(「,」)分隔

 

1. 對象(Object)

 

對象用大括號(「{}」)括起來,大括號裏是一系列的「名稱/值對」,請看概念圖。

 

兩個並列的數據之間用逗號(「,」)隔開,注意兩點:

 

- 使用英文的逗號(「,」),不要用中文的逗號(「,」)

- 最後一個「名稱/值對「以後不要加逗號

 

2. 數組(Array)

 

數組表示一系列有序的值,用方括號(「[]」)包圍起來,並列的值之間用逗號分隔,請看概念圖。

 

例如,如下的數組是合法的:

 

 

3. 名稱/值對(Name/Value)

 

名稱(Name)是一個字符串,要用雙引號括起來,不能用單引號,也不能沒有引號,這一點與 JavaScript 不一樣。

 

值的類型只有七種:字符串(string)、數值(number)、對象(object)、數組(array)、true、false、null。不能有這以外的類型,例如 undefined、函數等。請看概念圖。

 

字符串(string)的規則以下:

 

- 英文雙引號括起來,不能用單引號,也不能沒有。

- 字符串中不能單獨出現雙引號(」) 和右斜槓(「\」)。

- 若是要打雙引號或右斜槓,須要使用「右斜槓+字符」的形式,例如 \」 和 \\,其它的轉義字符也是如此

 

字符串的概念圖。

數值的概念圖。

 

字符串轉化爲對象parse()

解析,是指將符合 JSON 語法規則的字符串轉換成對象的過程。

 

不一樣的編程語言都提供瞭解析 JSON 字符串的方法,在這裏主要講解 JavaScript 中的解析方法。主要有三種:

 

- 使用 eval()

- 使用 JSON.parse()

- 使用第三方庫,例如 JQuery 等

 

 

 

1. eval()

 

eval() 函數的參數是一個字符串,其做用是直接執行其中的 JavaScript 代碼。

 

 

eval() 可以解析 JSON 字符串。從這裏也能夠看得出,JSON 和 JavaScript 是高度嵌合的。

 

 

可是,如今已經不多直接使用 eval() 來解析了,若是您的瀏覽器版本真的是很舊,可能才須要這個方法。此外,eval() 是一個相對危險的函數,由於字符串中可能含有未知因素。在這裏,做爲學習,仍是要知道這也是一種方法。

 

 

請注意 eval() 的參數,在字符串兩旁加了括號,這是必須的,不然會報錯。

 

 

由於 JSON 字符串是被大括號(「{}」)包圍的,直接放到 eval() 會被當成語句塊來執行,所以要在兩旁加上括號,使其變成表達式。

 

 

 

2. JSON.parse()

 

如今絕大多數瀏覽器都以支持 JSON.parse(),是推薦使用的方式。

 

 

若是輸入了不符合規範的字符串,會報錯。

 

 

JSON.parse() 能夠有第二個參數,是一個函數。此函數有兩個參數:name 和 value,分別表明名稱和值。當傳入一個 JSON 字符串後,JSON 的每一組名稱/值對都要調用此函數。該函數有返回值,返回值將賦值給當前的名稱(name)。

 

 

利用第二個參數,能夠在解析 JSON 字符串的同時對數據進行一些處理。

 

 

對象轉化爲字符串stringify()

序列化,指將 JavaScript 值轉化爲 JSON 字符串的過程。

 

JSON.stringify() 可以將 JavaScript 值轉換成 JSON 字符串。JSON.stringify() 生成的字符串能夠用 JSON.parse() 再還原成 JavaScript 值。

 

 

 

1. 參數的含義

 

JSON.stringify(value[, replacer[, space]])

 

value:必選參數。被變換的 JavaScript 值,通常是對象或數組。

 

replacer:能夠省略。有兩種選擇:函數或數組。

 

  - 若是是函數,則每一組名稱/值對都會調用此函數,該函數返回一個值,做爲名稱的值變換到結果字符串中,若是返回 undefined,則該成員被忽略。

 

  - 若是是數組,則只有數組中存在名稱纔可以被轉換,且轉換後順序與數組中的值保持一致。

 

space:能夠省略。這是爲了排版、方便閱讀而存在的。能夠在 JSON 字符串中添加空白或製表符等。

 

 

 

2. value 用法

 

 

 

3. replacer 的用法

 

 

 

4. space 的用法

 

 

 

JSONXML的轉換

1. 下載相關文件

 

- JQuery

- jquery.json2xml.js

- jquery.xml2json.js

 

2. XML 字符串轉換成 JSON 對象

 

$.xml2json(str);

 

3. JSON 對象轉換成 XML 字符串

 

$.json2xml(obj);

 

 

 

 

 

AjaxJSON

JSON 文件被放置在服務器端,客戶端請求該文件用得最多的是 Ajax,可以實現異步請求。

 

 

1. Ajax 是什麼

 

AJAX,全稱 Asynchronous JavaScript and XML,即「異步的 JavaScript 和 XML」,通常寫做 Ajax。

 

Ajax 可以與服務器交換少許數據,從而異步地更新部分網頁。

 

異步,指的是當 Ajax 執行交換數據的操做時,其餘的操做仍然能夠執行。

 

一個最多見的應用是:打開百度或谷歌首頁,當輸入文字後,搜索欄下方會顯示出幾個建議的搜索詞。這正是 Ajax 的應用。

 

 

 

 

2. 建立和使用 Ajax

 

建立 Ajax 對象要考慮瀏覽器的版本問題,主要分爲兩大類:IE7+/Chrome/Firefox/… 和 IE6/IE5.。

 

function CreateXHR(){

    if (window.XMLHttpRequest)

    {

        //對瀏覽器 IE7+, Firefox, Chrome, Opera, Safari

        return new XMLHttpRequest();

    }

    else

    {

        //對瀏覽器 IE6, IE5

        return new ActiveXObject("Microsoft.XMLHTTP");

    }

}

 

而後,只要用以下方式建立便可。

 

var xmlhttp;

 

xmlhttp = CreateXHR();

 

 

服務器端有一個文件 test.json,請求並輸出。

 

 

xmlhttp.open("GET","test.json",true);

xmlhttp.send();

 

xmlhttp.onreadystatechange = function(){

    if(xmlhttp.readyState == 4 && xmlhttp.status == 200){

        var jsonstr = xmlhttp.responseText;

        console.log(jsonstr);

    }

}

 

其中,xmlhttp.readyState 存有 XMLHttpRequest 的狀態,有五個值:

 

0: 請求未初始化

1: 服務器鏈接已創建

2: 請求已接收

3: 請求處理中

4: 請求已完成,且響應已就緒

 

xmlhttp.status 的值爲請求結果,200 表示「OK」,404 表示未找到頁面。

 

獲取來自服務器的響應,可以使用 XMLHttpRequest 對象的 responseText 或 responseXML 屬性,前者是以字符串形式,後者是以 XML 形式。

 

 

 

 

跨源資源共享

 

 

 

 

 

 

 

 

 

 

 

標 籤 。 我 們 知 道 , 一 個 網 頁 可 以 從 任 何 網 頁 中 加 載 圖 像 , 不 用 擔 心 跨 域 不 跨 域 。 這 也 是 在 線 廣 告 齦 蹤 瀏 覽 量 的 主 要 方 式 。 正 如 第 13 章 討 論 過 的 , 也 可 以 動 態 地 創 建 圖 像 . 使 用 它 們 的 onioad 和 oncrrcr 事 件 處 理 程 序 來 確 定 是 否 接 收 到 了 響 應 到 動 態 創 建 圖 像 經 常 用 於 圖 像 Pingo 圖 像 Ping 是 與 服 務 器 進 行 簡 單 、 單 向 的 跨 域 通 信 的 一 種 方 式 到 請 求 的 數 據 是 通 過 查 詢 字 符 串 形 式 發 送 的 . 而 響 應 可 以 是 任 意 內 容 . 但 通 常 是 像 素 或 2 偶 響 應 。 通 過 圖 像 ping. 瀏 覽 器 得 不 到 任 何 具 體 的 數 據 , 但 通 過 偵 聽 1 d 和 error 事 件 , 它 能 知 道 晌 應 是 什 麼 時 候 接 收 到 的 。 凍 看 下 面 的 例 子 。 imq . 0010 d i , 0 , 0 《 alert 儼 ] ! 。 0 " v:shapes="圖片_x0020_67">

 

 

 

 

Comet

 

 

SSE

 

 

 

 

 

 

 

JSONP

JSON with padding

 

 

 

 

 

 

元 素 ( 要 了 解 詳 細 信 息 , 請 參 考 第 13 章 ) 來 使 用 的 , 使 用 時 可 以 爲 src 屬 跬 指 定 一 個 跨 域 URL 這 裏 的 < 艹 p 元 素 與 元 素 類 似 , 都 有 能 力 不 受 限 制 地 從 其 他 域 加 載 資 源 。 因 爲 JSONP 是 有 效 的 JavaScript 代 碼 , 所 以 在 請 求 完 成 後 , 即 在 JSONP 響 應 加 載 到 頁 而 中 以 後 , 就 會 立 即 執 行 。 來 看 一 個 例 了 。 function handleResponge (response) { 《 , You , re at 4 response . ip ' •. Which is in + response .region_name) ; 「 鬥 var script , document .createE1ement( 咩 過 cr p 門 ; "http : / / freegeoip j 90n / ?caiIbackrhandLeRespOnse• script . StC document . body. insertBefore (script , d0010Pn 上 .body . firstchilä) : J 、 0 PE a 化 / 湯 這 個 例 子 通 過 查 詢 地 理 定 位 服 務 來 顯 示 你 的 IP 地 址 和 位 置 信 息 「 JSONP 之 所 以 在 開 發 人 員 中 極 爲 流 行 , 主 要 原 因 是 它 非 常 簡 單 易 用 。 與 圖 像 Ping 相 比 , 它 的 優 點 在 於 能 夠 直 接 訪 問 響 應 文 本 , 支 持 在 瀏 覽 器 與 服 務 器 之 間 雙 向 通 信 。 不 過 , JSONP 也 有 兩 點 不 足 。 首 先 , JSONP 是 從 其 他 域 中 加 載 代 碼 執 行 如 果 其 他 域 不 安 全 , 很 可 能 會 在 響 應 中 夾 帶 一 些 惡 意 代 碼 , 而 此 時 除 了 完 全 放 棄 JSONP 調 用 之 外 , 沒 有 辦 法 追 究 。 因 此 在 使 用 不 是 你 自 己 運 維 的 web 服 務 時 , 一 定 得 保 證 它 安 全 可 靠 。 其 次 , 要 確 定 JSONP 請 求 是 否 失 敗 並 不 容 易 。 雖 然 HTML5 給 < scrip 。 元 素 新 增 了 一 個 onerror 事 件 處 理 程 序 , 但 目 還 沒 有 得 到 任 何 瀏 覽 器 支 持 。 爲 此 , 開 發 人 員 不 得 不 使 用 計 時 器 檢 測 指 定 時 間 內 " v:shapes="圖片_x0020_59">

 

 

提供了一種方式從另外一個站點獲取信息

用JSON來傳數據,靠JSONP來跨域。

Ajax直接請求普通文件存在跨域無權限訪問的問題,甭管你是靜態頁面、動態網頁、web服務、WCF,只要是跨域請求,一概不許;

 

Web頁面上調用js文件時則不受是否跨域的影響。不只如此,咱們還發現凡是擁有"src"這個屬性的標籤都擁有跨域的能力,好比<script>、<img>、<iframe>);

 

 

JavaScript 正則表達式(Regular Expression,在代碼中常簡寫爲regex、regexp或RE)

正則表達式是用於匹配字符串中字符組合的模式。在 JavaScript中,正則表達式也是對象。

這些模式被用於 RegExp exec test 方法, 以及 String matchreplacesearch split 方法。

使用單個字符串來描述、匹配一系列符合某個句法規則的字符串搜索模式。

搜索模式可用於文本搜索和文本替換。

兩種形式的語法:

/pattern/flags(flags標誌可選)

new RegExp(pattern [, flags])

 

正則表達式中的特殊字符

字符

含義

\

匹配將依照下列規則:

在非特殊字符以前的反斜槓表示下一個字符是特殊的,不能從字面上解釋。例如,沒有前面'\'的'b'一般匹配小寫'b',不管它們出如今哪裏。若是加了'\',這個字符變成了一個特殊意義的字符,意思是匹配一個字符邊界

反斜槓也能夠將其後的特殊字符,轉義爲字面量。例如,模式 /a*/ 表明會匹配 0 個或者多個 a。相反,模式 /a\*/ 將 '*' 的特殊性移除,從而能夠匹配像 "a*" 這樣的字符串。

使用 new RegExp("pattern") 的時候不要忘記將 \ 進行轉義,由於 \ 在字符串裏面也是一個轉義字符。

^

匹配輸入的開始。若是多行標誌被設置爲true,那麼也匹配換行符後緊跟的位置。

例如,/^A/ 並不會匹配 "an A" 中的 'A',可是會匹配 "An E" 中的 'A'。

當 '^' 做爲第一個字符出如今一個字符集合模式時,它將會有不一樣的含義。補充字符集合 一節有詳細介紹和示例。

$

匹配輸入的結束。若是多行標示被設置爲true,那麼也匹配換行符前的位置。

例如,/t$/ 並不會匹配 "eater" 中的 't',可是會匹配 "eat" 中的 't'。

*

匹配前一個表達式0次或屢次。等價於 {0,}。

例如,/bo*/會匹配 "A ghost boooooed" 中的 'booooo' 和 "A bird warbled" 中的 'b',可是在 "A goat grunted" 中將不會匹配任何東西。

+

匹配前面一個表達式1次或者屢次。等價於 {1,}。

例如,/a+/匹配了在 "candy" 中的 'a',和在 "caaaaaaandy" 中全部的 'a'。

?

匹配前面一個表達式0次或者1次。等價於 {0,1}。

例如,/e?le?/ 匹配 "angel" 中的 'el',和 "angle" 中的 'le' 以及"oslo' 中的'l'。

若是緊跟在任何量詞 * + {} 的後面,將會使量詞變爲非貪婪的(匹配儘可能少的字符),和缺省使用的貪婪模式(匹配儘量多的字符)正好相反。

例如,對 "123abc" 應用 /\d+/ 將會返回 "123",若是使用 /\d+?/,那麼就只會匹配到 "1"。

還能夠運用於先行斷言,如本表的 x(?=y) 和 x(?!y) 條目中所述。

.

(小數點)匹配除換行符以外的任何單個字符。

例如,/.n/將會匹配 "nay, an apple is on the tree" 中的 'an' 和 'on',可是不會匹配 'nay'。

(x)

匹配 'x' 而且記住匹配項,就像下面的例子展現的那樣。括號被稱爲 捕獲括號。

模式/(foo) (bar) \1 \2/中的 '(foo)' 和 '(bar)' 匹配並記住字符串 "foo bar foo bar" 中前兩個單詞。模式中的 \1 \2 匹配字符串的後兩個單詞。注意 \1\2\n 是用在正則表達式的匹配環節。在正則表達式的替換環節,則要使用像 $1$2$n 這樣的語法,例如,'bar foo'.replace( /(...) (...)/, '$2 $1' )

(?:x)

匹配 'x' 可是不記住匹配項。這種叫做非捕獲括號,使得你可以定義爲與正則表達式運算符一塊兒使用的子表達式。來看示例表達式 /(?:foo){1,2}/。若是表達式是 /foo{1,2}/,{1,2}將只對 ‘foo’ 的最後一個字符 ’o‘ 生效。若是使用非捕獲括號,則{1,2}會匹配整個 ‘foo’ 單詞。

x(?=y)

匹配'x'僅僅當'x'後面跟着'y'.這種叫作正向確定查找。

例如,/Jack(?=Sprat)/會匹配到'Jack'僅僅當它後面跟着'Sprat'。/Jack(?=Sprat|Frost)/匹配‘Jack’僅僅當它後面跟着'Sprat'或者是‘Frost’。可是‘Sprat’和‘Frost’都不是匹配結果的一部分。

x(?!y)

匹配'x'僅僅當'x'後面不跟着'y',這個叫作正向否認查找。

例如,/\d+(?!\.)/匹配一個數字僅僅當這個數字後面沒有跟小數點的時候。正則表達式/\d+(?!\.)/.exec("3.141")匹配‘141’可是不是‘3.141’

x|y

匹配‘x’或者‘y’。

例如,/green|red/匹配「green apple」中的‘green’和「red apple」中的‘red’

{n}

n是一個正整數,匹配了前面一個字符恰好發生了n次。

好比,/a{2}/不會匹配「candy」中的'a',可是會匹配「caandy」中全部的a,以及「caaandy」中的前兩個'a'。

{n,m}

n 和 m 都是整數。匹配前面的字符至少n次,最多m次。若是 n 或者 m 的值是0, 這個值被忽略。

例如,/a{1, 3}/ 並不匹配「cndy」中的任意字符,匹配「candy」中得a,匹配「caandy」中的前兩個a,也匹配「caaaaaaandy」中的前三個a。注意,當匹配」caaaaaaandy「時,匹配的值是「aaa」,即便原始的字符串中有更多的a。

[xyz]

一個字符集合。匹配方括號的中任意字符,包括轉義序列。你能夠使用破折號(-)來指定一個字符範圍。對於點(.)和星號(*)這樣的特殊符號在一個字符集中沒有特殊的意義。他們沒必要進行轉義,不過轉義也是起做用的。

例如[abcd] [a-d]是同樣的。他們都匹配"brisket"中得‘b’,也都匹配「city」中的‘c’。/[a-z.]+/ 和/[\w.]+/都匹配「test.i.ng」中得全部字符。

[^xyz]

一個反向字符集。也就是說, 它匹配任何沒有包含在方括號中的字符。你能夠使用破折號(-)來指定一個字符範圍。任何普通字符在這裏都是起做用的。

例如,[^abc] 和 [^a-c] 是同樣的。他們匹配"brisket"中得‘r’,也匹配「chop」中的‘h’。

[\b]

匹配一個退格(U+0008)。(不要和\b混淆了。)

\b

匹配一個詞的邊界。一個詞的邊界就是一個詞不被另一個詞跟隨的位置或者不是另外一個詞彙字符前邊的位置。注意,一個匹配的詞的邊界並不包含在匹配的內容中。換句話說,一個匹配的詞的邊界的內容的長度是0。(不要和[\b]混淆了)

例子:

/\bm/匹配「moon」中得‘m’;

/oo\b/並不匹配"moon"中得'oo',由於'oo'被一個詞彙字符'n'緊跟着。

/oon\b/匹配"moon"中得'oon',由於'oon'是這個字符串的結束部分。這樣他沒有被一個詞彙字符緊跟着。

/\w\b\w/將不能匹配任何字符串,由於一個單詞中的字符永遠也不可能被一個非詞彙字符和一個詞彙字符同時緊跟着。

注意: JavaScript的正則表達式引擎將特定的字符集定義爲「字」字符。不在該集合中的任何字符都被認爲是一個斷詞。這組字符至關有限:它只包括大寫和小寫的羅馬字母,小數位數和下劃線字符。不幸的是,重要的字符,例如「é」或「ü」,被視爲斷詞。

\B

匹配一個非單詞邊界。他匹配一個先後字符都是相同類型的位置:都是單詞或者都不是單詞。一個字符串的開始和結尾都被認爲是非單詞。

例如,/\B../匹配"noonday"中得'oo', 而/y\B./匹配"possibly yesterday"中得’ye‘

\cX

當X是處於A到Z之間的字符的時候,匹配字符串中的一個控制符。

例如,/\cM/ 匹配字符串中的 control-M (U+000D)。

\d

匹配一個數字。

等價於[0-9]。

例如, /\d/ 或者 /[0-9]/ 匹配"B2 is the suite number."中的'2'。

\D

匹配一個非數字字符。

等價於[^0-9]。

例如, /\D/ 或者 /[^0-9]/ 匹配"B2 is the suite number."中的'B' 。

\f

匹配一個換頁符 (U+000C)。

\n

匹配一個換行符 (U+000A)。

\r

匹配一個回車符 (U+000D)。

\s

匹配一個空白字符,包括空格、製表符、換頁符和換行符。

等價於[ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]。

例如, /\s\w*/ 匹配"foo bar."中的' bar'。

\S

匹配一個非空白字符。

等價於[^ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]。

例如, /\S\w*/ 匹配"foo bar."中的'foo'。

\t

匹配一個水平製表符 (U+0009)。

\v

匹配一個垂直製表符 (U+000B)。

\w

匹配一個單字字符(字母、數字或者下劃線)

等價於[A-Za-z0-9_]。

例如, /\w/ 匹配 "apple," 中的 'a',"$5.28,"中的 '5' 和 "3D." 中的 '3'。

\W

匹配一個非單字字符。

等價於[^A-Za-z0-9_]。

例如, /\W/ 或者 /[^A-Za-z0-9_]/ 匹配 "50%." 中的 '%'。

\n

當 n 是一個正整數,一個返回引用到最後一個與有n插入的正則表達式(counting left parentheses)匹配的副字符串。

好比 /apple(,)\sorange\1/ 匹配"apple, orange, cherry, peach."中的'apple, orange,' 。

\0

匹配 NULL (U+0000) 字符, 不要在這後面跟其它小數,由於 \0<digits> 是一個八進制轉義序列。

\xhh

與代碼 hh 匹配字符(兩個十六進制數字)

\uhhhh

與代碼 hhhh 匹配字符(四個十六進制數字)。

\u{hhhh}

(僅當設置了u標誌時) 使用Unicode值hhhh匹配字符 (十六進制數字).

 

正則表達式標誌

標誌

描述

g

全局搜索。

i

不區分大小寫搜索。

m

多行搜索。

y

執行「粘性」搜索,匹配從目標字符串的當前位置開始,能夠使用y標誌。

 

使用正則表達式的方法

方法

描述

exec

一個在字符串中執行查找匹配的RegExp方法,它返回一個數組(未匹配到則返回null)。

test

一個在字符串中測試是否匹配RegExp方法,它返回truefalse

match

一個在字符串中執行查找匹配的String方法,它返回一個數組或者在未匹配到時返回null。

search

一個在字符串中測試匹配的String方法,它返回匹配到的位置索引,或者在失敗時返回-1。

replace

一個在字符串中執行查找匹配的String方法,而且使用替換字符串替換掉匹配到的子字符串。

split

一個使用正則表達式或者一個固定字符串分隔一個字符串,並將分隔後的子字符串存儲到數組中的String方法。

 

一個正則表達式模式使用括號,將致使相應的子匹配被記住。例如,/a(b)c /能夠匹配字符串「abc」,而且記得「b」。回調這些括號中匹配的子串,使用數組元素[1],……[n]。

使用括號匹配的子字符串的數量是無限的。返回的數組中保存全部被發現的子匹配。下面的例子說明了如何使用括號的子字符串匹配。

下面的腳本使用replace()方法來轉換字符串中的單詞。在匹配到的替換文本中,腳本使用替代的$ 1,$ 2表示第一個和第二個括號的子字符串匹配。

var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
console.log(newstr);

這個表達式輸出 "Smith, John"。

使用正則表達式且不區分大小寫將字符串中的 Microsoft 替換爲 ibm:

var str = document.getElementById("demo").innerHTML;

var txt = str.replace(/microsoft/i, "ibm");

結果輸出爲:

Visit ibm!

 

使用正則表達式搜索 "Home" 字符串,且不區分大小寫:

var str = "Visit Home!";

var n = str.search(/Home/i);

輸出結果爲:

6

 

var patt = /e/;

patt.test("The best things in life are free!");

字符串中含有 "e",因此該實例輸出爲:

true

 

/e/.exec("The best things in life are free!");

字符串中含有 "e",因此該實例輸出爲:

e

 

方括號用於查找某個範圍內的字符:

表達式

描述

[abc]

查找方括號之間的任何字符。

[0-9]

查找任何從 0 至 9 的數字。

(x|y)

查找任何以 | 分隔的選項。

元字符是擁有特殊含義的字符:

元字符

描述

\d

查找數字。

\s

查找空白字符。

\b

匹配單詞邊界。

\uxxxx

查找以十六進制數 xxxx 規定的 Unicode 字符。

量詞:

量詞

描述

n+

匹配任何包含至少一個 n 的字符串。

n*

匹配任何包含零個或多個 n 的字符串。

n?

匹配任何包含零個或一個 n 的字符串。

 

 

 

 

Object對象

構造函數(Object()、Object(value))

實例屬性(__proto__、prototype、constructor)

實例方法(hasOwnProperty、isPropertyOf、propertyIsEnumerable、

toLocaleString、toString、valueOf)

靜態方法(Object.assign()、Object.create()、Object.defineProperties(

Object.defineProperty()、Object.freeze()、

Object.getOwnPropertyDescriptor()、

Object.getOwnPropertyNames()、Object.getPrototypeOf()、Object.setPropertyOf()、

Object.isExtensible()、Object.isFrozen()、

Object.isSealed()、Object.keys()、Object.preventExtensions()、

Object.seal())

屬性描述符(數據屬性如value,writable,enumerable,configurable;訪問器屬性get,set)

 

建立對象(實例),建立方法以下:

     1. 用new操做符後面跟Object的構造函數                        

 var cat= new Object();//推薦

// var o=new Object;//這種方法有效,但不推薦用。

cat.name="sunny";

cat.legs=4;

 

  2.  對象字面量字面量表示法(推薦)

var cat={
       name:"sunny",
       legs:4

}

 

Object類型中所具備的任何屬性和方法,一樣存在於具體的對象(實例)中。

Object類型的屬性和方法以下:

  1. 構造函數:Object()
  2. hasOwnProperty(PropertyName):檢查給定的屬性是否在當前的對象實例中,注:PropertyName必須以字符串給定
  3. isPrototypeOf(object):檢查傳遞的對象,是不是另外一個對象的原型。注:這裏牽扯到原型和原型鏈,因此之後具體在講,目前你們先知道有這麼個方法
  4. propertyIsEnumerable(PropertyName):檢查給定的屬性是否能用for-in 語句來枚舉。注:PropertyName必須以字符串給定
  5. toLocaleString():返回的字符串與執行環境的地區對應
  6. toString():返回字符串
  7. valueOf():返回對象的字符串、數值或布爾值表示

 

對象屬性的訪問方法

     1. 點表示法  cat.name

     2. 方括號表示法:cat["name"]

      注1:方括號訪問的優勢是:

 A. 能夠經過變量來訪問屬性    

var  pName="name";

alert(cat[pName]);

B. 若是屬性名中包含會致使語法錯誤的字符,或者屬性名使用的是關鍵字或保留字,也能夠用方括號表示法。

  cat["lovely brother"]="Tom"; 屬性名中包含空格因此不能使用點表示法訪問它

注2:訪問屬性推薦使用點表示法,除非沒辦法用點表示法的時候選擇用方括號訪問

 

Object對象,是全部JavaScript對象的超類(基類)。Object.prototype(Object的原型)定義了Js對象的基本方法和屬性。

alert(Object.prototype);  // [object Object]

alert(Object); // function Object { [native code] }

alert(Object()); // [object Object]

console. log(Object . prototype); {constructor: f, _dEfineGetter construct" : f Object() arguments: ( • assign: f assign() caller: ( • • • create: f create() : f, _defineSetter ha sownProp erty : f, _ LookupGEtter f defineproperties() f defineproperty() y entries: f entries freeze: f freeze getOwnPropertyDescriptor: f getOwnPropertyDescriptor() getOunPro;ertyDescriptors: f getOwnPropertyDEscriptors() f getCWnPropertyNames() f getOwnPropertySymboLs( ) getOwnPro;ertySymboZs: getPrototypeCf: f getPrototypEOf() Sis: f is() > isixtersi±le: f isExtensibLe() f isFrozen() > isSesI±d: f isSeaLed() keys: f keys() length: I name: "Obiect" preventixtersicns: f preventExtensions() prctcty;e: {constructor: f, _defineCetter Y seal: f seaL() f setPrototypEOf() values: f vaLues() _;t-cto_: f ( ) C [Scopes)]: Scopesce] hasOwnPro;erty: f hasCWnProperty() f isPrototypeOf() propertyIsEnumetäbIe: f propertyrsEnumerabLe() : f, _defineSetter hasCqn Property : f, I ookupGetter_ toLozsI±String: f toLocaLeString() toStrirg: f toString() valueCF: f VGLueOf() _d : f _ defineGEtter o define Setter Setter " v:shapes="圖片_x0020_56">

 

2. 構造函數(Object()、Object(value))

2.1 new Object() :返回一個Object實例

2.2 new Object(value) :根據value的值,返回不一樣的對象(NumberBooleanString)

參數:

①value {number | bool | string} :一個數字、布爾值或者字符串

返回值:

{Number、Boolean、String} 返回一個轉換後的對象

示例 :

var o = new Object(123);

console.log(o); // => Number對象

o = new Object(true);

console.log(o); // => Boolean對象

o = new Object('abc');

console.log(o); // => String對象

 

而alert(o); // 彈出123

 

3. 實例屬性(__proto__、prototype、constructor)

3.1 __proto__ :設置或返回對象的原型對象(IE中不支持此屬性)

說明:

1) 賦值時,對象實例繼承新原型的全部方法和屬性,以及新原型的原型鏈中的全部方法和屬性。

2) 屬性名稱以兩個下劃線開始和結束。

3) 對象實例的__proto__ == 或===對象原型(類/構造函數)的prototype

示例:

function People(name) {

    this.name = name;

}

function Student(age) {

    this.age = age;

}

Student.prototype = new People(); // 設置Student的原型爲People對象

 

var s = new Student(22);

console.log(s.__proto__); // => People 對象

console.log(Student.prototype); // => People 對象

console.log(s.__proto__ == Student.prototype); // => true

console.log(s.__proto__ === Student.prototype); // => true

 

// 2.對象直接量

var p = {}; // 等於new Object()

console.log(p.__proto__ == Object.prototype); // => true

console.log(p.__proto__ === Object.prototype); // => true

 

3.2 prototype :設置或返回對象原型(類/構造函數)的原型對象

說明:

1) prototype爲對象原型(類/構造函數)的屬性。__proto__是對象實例的屬性。

2)  JS內置對象(Array、Date等對象)都有一個只讀的prototype屬性。 可將屬性和方法添加到原型中,但不能爲內置對象分配其餘原型。

3) 自定義對象的prototype屬性可進行讀寫操做。

示例:

var Student = function (name) {

    this.name = name;

};

// 給Student的原型添加一個sayHello方法

Student.prototype.sayHello = function () {

    alert('Hello,' + this.name);

}

var st = new Student('張三'); // 初始化對象st

console.log(st.name); // => 張三

st.sayHello(); // 彈出:Hello,張三

 

3.3 constructor :表示建立此對象的構造函數

說明:

1) 設置或返回建立此對象的構造函數。

2) 若一個對象有多層繼承,將返回最早調用的構造函數。

3) obj.constructor.prototype 可表示對象的原型

示例:

// 1.內置對象

var str = 'abc';

console.log(str.constructor); // => function String 構造函數

var o = {};

console.log(o.constructor); // => function Object 構造函數

Chrome控制檯顯示 ƒ Object() { [native code] },跟一開始的console.log(Object)同樣,

因此也就能理解obj.constructor.prototype 可表示對象的原型了

 

// 2.自定義對象多層繼承 :constructor返回最早調用的構造函數

function People(name) {

    this.name = name; // s對象初始化時,先調用People構造函數,再調用Student構造函數

    console.log('People調用');

}

function Student(age) {

    this.age = age;

    console.log('Student調用');

}

Student.prototype = new People(); // 設置Student的原型爲People對象

 

var s = new Student(22);

console.log(s.constructor); // => function People 構造函數

 

總結:__proto__prototypeconstructor 的關係

說明:

1) 對象實例的__proto__ 等於 對象原型(類/構造函數)的prototype

2) 對象實例的constructor 等於 對象原型(類/構造函數),因此obj.constructor.prototype 可表示對象的原型。

示例:

 

 

 

 

var o = {};

console.log(o.__proto__ === Object.prototype); // true :對象的__proto__等於類的prototype

console.log(o.constructor === Object); // true :對象的constructor 等於 類

console.log(o.constructor.prototype === Object.prototype); // true :o.constructor.prototype 可表示對象的原型。

 

4. 實例方法(hasOwnProperty、isPropertyOf、propertyIsEnumerable、

toLocaleString、toString、valueOf)

4.1 hasOwnProperty(propertyName) :判斷對象是否擁有一個指定名稱的實例屬性(非繼承)

參數:

①propertyName {string} :屬性名稱。

返回值:

{bool} 判斷對象是否擁有一個指定名稱的本地定義(非繼承)的屬性;此方法不會檢查對象原型鏈中的屬性。

true :屬性爲對象的實例屬性,非繼承。

false :屬性不爲對象的實例屬性。

示例 :

// 1.Object對象

var o = new Object();

o.name = '自定義屬性'; // 定義一個實例屬性

console.log(o.hasOwnProperty('name')); // => true:name屬性爲實例o本身定義的,而非繼承

console.log(o.hasOwnProperty('toString')); // => false:toString爲繼承屬性

 

// 2.自定義對象

var Student = function (name) {

    this.name = name;

};

// 給Student的原型添加一個sayHello方法

Student.prototype.sayHello = function () {

    alert('Hello,' + this.name);

}

// 給Student的原型添加一個age屬性

Student.prototype.age = '';

 

var st = new Student('張三'); // 初始化對象st

console.log(st.hasOwnProperty('name')); // => true :調用構造函數時,經過this.name附加到實例對象上

console.log(st.hasOwnProperty('sayHello')); // => false :sayHello方法爲原型上的成員

console.log(st.hasOwnProperty('age')); // => false :age屬性爲原型上的成員

 

4.2 isPrototypeOf(obejct) :判斷某個原型是否出如今對象的原型鏈中

語法:

prototype.isPrototypeOf(object)

參數:

①obejct {object} :被檢測的對象。

返回值:

{bool} 返回某個原型是否出如今對象的原型鏈中

true :是

false :不是

示例 :

// 1.Obejct對象

var o = new Object();

console.log(Object.prototype.isPrototypeOf(o)); // => true :o爲Obejct一個對象

 

// 2.Array

var array = [1, 2, 3];

console.log(Array.prototype.isPrototypeOf(array)); // => true :數組原型

console.log(Object.prototype.isPrototypeOf(array)); // => true :Object是全部對象的基原型

 

// 3.自定義對象

var People = function () {

}

var Student = function () {

}

// 設置Student類的原型爲People

Student.prototype = new People();

var st = new Student();

console.log(Student.prototype.isPrototypeOf(st)); // => true :st爲Student一個對象

console.log(People.prototype.isPrototypeOf(st)); // => true :Student的原型爲People

console.log(Object.prototype.isPrototypeOf(st)); // =>true :Object是全部對象的基原型

 

4.3 propertyIsEnumerable(propertyName)

判斷指定名稱的屬性是否爲實例屬性而且是可枚舉的(可用for/in循環枚舉)

參數:

①propertyName {string} :屬性名稱

返回值:

{bool} 判斷屬性是否爲實例屬性而且是可枚舉的(可用for/in循環枚舉),不考慮原型鏈中的成員。

true :是

false :不是

示例 :

// 1.Array對象

var array = [1, 2, 3];

array.name = 'Array';

console.log(array.propertyIsEnumerable('name')); // => true :name屬性爲實例屬性

console.log(array.propertyIsEnumerable('join')); // => false :join方法繼承自Array

console.log(array.propertyIsEnumerable('length')); // => false :length屬性繼承自Array

console.log(array.propertyIsEnumerable('toString')); // => false :toString方法繼承自Object

 

// 2.自定義對象

var Student = function (name) {

    this.name = name;

}

// 定義一個原型方法

Student.prototype.sayHello = function () {

    alert('Hello' + this.name);

};

var a = new Student('tom');

console.log(a.propertyIsEnumerable('name')); // => true :name爲自身定義的實例屬性

console.log(a.propertyIsEnumerable('age')); // => false :age屬性不存在,也返回false

console.log(a.propertyIsEnumerable('sayHello')); // => false :sayHello屬於原型方法

 

4.4 toLocaleString() :返回當前對象的一個本地化的字符串表示

4.5 toString() :返回當前對象的一個字符串表示形式

4.6 valueOf() :返回當前對象的原始值

參數:

返回值:

{object} 返回當前對象關聯的原始值,若沒有相關聯的值,則返回對象自己

示例 :

var a = [1, 2, 3];

console.log(a.valueOf()); // => [1, 2, 3]

 

var b = true;

console.log(b.valueOf()); // => true

 

var c = {};

console.log(c.valueOf()); // => Object {}

 

var s = 'abc';

console.log(s.valueOf()); // => abc

 

// 自定義個對象,重寫valueOf

var customObject = {};

customObject.valueOf = function () {

    return '自定義對象';

}

console.log(customObject.valueOf()); // => 自定義對象

 

5. 靜態方法(Object.assign()、Object.create()、Object.defineProperties()、

Object.defineProperty()、Object.freeze()、

Object.getOwnPropertyDescriptor()

Object.getOwnPropertyNames()、Object.getPrototypeOf()、Object.setPropertyOf()、

Object.isExtensible()、Object.isFrozen()、

Object.isSealed()、Object.keys()、Object.preventExtensions()、

Object.seal()

 

Object.assign(target, ...sources)

將全部可枚舉屬性的值從一個或多個源對象複製到目標對象。它將返回目標對象。合成對象,共同屬性會合並

 

Object.setPropertyOf()

 

5.1 Object.create(prototype, propertyDescriptor)

建立並返回一個指定原型和指定屬性的對象

參數:

①prototype {prototype} :返回對象的原型,能夠爲null。若爲null,對象的原型爲undefined。

②propertyDescriptor {propertyDescriptor} 可選:屬性描述符。

屬性描述符:設置屬性的一系列特性

語法格式:

propertyName: {

    value: '', // 設置此屬性的值

    writable: true, // 設置此屬性是否可寫入;默認爲false:只讀

    enumerable: true, // 設置此屬性是否可枚舉(經過for/in預付);默認爲false:不可枚舉

    configurable: true // 設置此屬性是否可配置;如:是否能夠修改屬性的特性及刪除屬性。默認爲false

}

返回值:

{object} 返回一個指定原型和指定屬性的對象

示例 :

// 創建個自定義對象,設置name和age屬性

var obj = Object.create(null, {

    name: {

        value: 'tom',

        writable: true,

        enumerable: true,

        configurable: true

    },

    age: {

        value: 22

    }

});

console.log(obj.name); // => tom

console.log(obj.age); // => 22

 

obj.age = 28;

console.log(obj.age); // => 22 :age屬性的writable默認爲false,此屬性爲只讀

 

5.2  Object.defineProperties(object, propertyDescriptor) :添加/修改對象一個或多個屬性的特性

參數:

①object {object} :對象

②propertyDescriptor {propertyDescriptor} 屬性描述符

說明:

若對象包含此屬性,則是修改此屬性的特性;不然爲爲對象添加此屬性。

示例 :

var obj = {};

 

// 爲對象添加name和age屬性

Object.defineProperties(obj, {

    name: {

        value: 'tom',

        enumerable: true

    },

    age: {

        value: 22,

        enumerable: true

    }

});

for (p in obj) {

    console.log(p); // => name、age :輸出name和age屬性

}

 

5.3 Object.defineProperty(obj, propertyName, propertyDescriptor) :添加/修改對象指定屬性的特性

參數:

①object {object} :對象

②propertyName {string} :屬性的名稱

③propertyDescriptor {propertyDescriptor} 屬性描述符。

說明 :

若對象包含此屬性,則是修改此屬性的特性;不然爲添加此屬性。

示例:

var obj = {};

// 添加一個name屬性

Object.defineProperty(obj, 'name', {

        value: 'tom',

        writable: true,

        enumerable: true,

        configurable:true

    }

);

console.log(obj.name); // => tom :輸出name屬性的value的值

 

5.4 Object.freeze(object)

凍結對象,使其不能添加屬性以及沒法對現有的實例屬性進行特性更改、值修改、屬性刪除等操做

參數:

①object {object} :對象

說明 :

1) 此操做不可逆,凍結後沒法進行解封。

2) 隻影響實例屬性,不影響原型屬性。

示例:

var obj = {

    name: 'tom',

    age: 22

};

Object.freeze(obj); // 凍結對象

 

obj.email = '123@qq.com';

console.log(obj.email); // undefined :沒法添加屬性

obj.age = 25;

console.log(obj.age); // 22 :沒法設置屬性的值

 

5.5 Object.getOwnPropertyDescriptor(object, propertyName)

返回對象屬性的描述符

參數:

①object {object} :對象

②propertyName {propertyName} 屬性名稱

返回值:

{propertyDescriptor} 屬性描述符對象

示例 :

var obj = {

    name: 'tom',

    age: 22

};

 

var propertyDes = Object.getOwnPropertyDescriptor(obj, 'name');

console.log(propertyDes); // => Object {value: "tom", writable: true, enumerable: true, configurable: true} :輸出描述符對象

 

5.6 Object.getOwnPropertyNames(object)

返回一個數組,包含對象的全部實例屬性和方法,不包含原型繼承的屬性和方法

參數:

①object {object} :對象

返回值:

{Array} 一個數組,包含對象的全部實例屬性和方法,不包含原型繼承的屬性和方法

示例 :

1

2

3

4

5

6

7

8

var obj = {

    name: 'tom',

    age: 22,

    sayHello: function () {

        alert('Hello' + this.name);

    }

};

console.log(Object.getOwnPropertyNames(obj)); // => ["name", "age", "sayHello"] :返回對象的實例成員

 

5.7 Object.getPrototypeOf(object) :返回對象的上一級原型

參數:

①object {object} :對象

返回值:

{object} 返回原型對象

示例 :

//   1.對象直接量

var obj = {

    name: 'tom',

    age: 22,

    sayHello: function () {

        alert('Hello' + this.name);

    }

};

console.log(Object.getPrototypeOf(obj)); // => Object 對象:對象直接量的原型爲Object

 

// 2.自定義對象

var People = function (name) {

    this.name = name;

};

 

var p = new People('tom');

var people = Object.getPrototypeOf(p);

console.log(people); // => People 對象:new 建立的對象使用構造函數的prototype屬性做爲他們的原型

console.log(Object.getPrototypeOf(people)); // => Object 對象:原型People的原型爲Object

 

5.8 Object.isExtensible(object) :判斷是否可向對象添加新的屬性

5.9 Object.isFrozen(object) :判斷對象是否凍結;true:不能修改對象的現有屬性特性和值而且不能添加新的屬性

5.10 Object.isSealed(object) :判斷對象是否封閉;true:不能修改對象的現有屬性特性而且不能添加新的屬性

 

5.11 Object.keys(object) 返回一個數組,包含對象的可枚舉的實例屬性名稱

參數:

①object {object} :對象

返回值:

{Array} 返回一個數組,包含對象可枚舉的實例屬性名稱

說明:

此方法與getOwnPropertyNames()相似,但getOwnPropertyNames()包含了可枚舉和不可枚舉的成員

示例 :

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

var obj = {

    name: 'tom',

    age: 22,

    sayHello: function () {

        alert('Hello' + this.name);

    }

};

 

// 1)getOwnPropertyNames與keys方法返回的內容都相同

console.log(Object.getOwnPropertyNames(obj)); // => ["name", "age", "sayHello"] :返回對象的全部實例成員

console.log(Object.keys(obj)); // => ["name", "age", "sayHello"] :返回對象的全部可枚舉成員

 

// 設置對象的name屬性不可枚舉

Object.defineProperty(obj, 'name', {

        enumerable: false

    }

);

 

// 2)keys方法,只包含可枚舉成員

console.log(Object.getOwnPropertyNames(obj)); // => ["name", "age", "sayHello"] :返回對象的全部實例成員

console.log(Object.keys(obj)); // => ["age", "sayHello"] :返回對象的全部可枚舉成員

  

5.12 Object.preventExtensions(object) :設置對象不能添加新的屬性

參數:

①object {object} :對象

返回值:

{object} 返回此對象

示例 :

1

2

3

4

5

6

7

var obj = {

    name: 'tom',

    age: 22

};

Object.preventExtensions(obj); // 設置對象不能添加新的屬性

obj.email = '123@qq.com';

console.log(obj.email); // => undefined :沒法向對象添加新的屬性

 

5.13 Object.seal(object) :密封對象,使其沒法修改現有屬性的特性以及不能添加新的屬性

參數:

①object {object} :對象

返回值:

{object} 返回此對象

示例 :

1

2

3

4

5

6

7

8

9

10

11

12

13

var obj = {

    name: 'tom',

    age: 22

};

Object.seal(obj); // 密封對象

obj.email = '123@qq.com';

console.log(obj.email); // => undefined :沒法向對象添加新的屬性

 

// 報異常:沒法修改對象屬性的特性

Object.defineProperty(obj, 'name', {

        enumerable: false

    }

);

 

6.屬性描述符(數據屬性如value,writable,enumerable,configurable;訪問器屬性get,set)

分爲數據屬性和訪問器屬性;

二者可相互轉換,若轉換後未設置enumerable和configurable特性(兩類屬性描述符都包含這2個特性),將默認採用轉換前的值。

6.1 數據屬性

說明:包含屬性的操做特性;如:設置值、是否可枚舉等等

特性名稱

描述

默認值

value

設置屬性的值

undefined

writable

是否可修改屬性的值;true:可修改屬性的值;false:不可修改屬性的值

false

enumerable

是否可枚舉屬性;true:可枚舉,可經過for/in語句枚舉屬性;false:不可枚舉

false

configurable

是否可修改屬性的特性;true:可修改屬性的特性(如把writable從false改成true);false:不可修改屬性的特性

false

 

默認值:

1)在使用Object.definePropertyObject.defineProperties Object.create 函數的狀況下添加數據屬性,writableenumerableconfigurable默認值爲false

2)使用對象直接量建立的屬性,writableenumerableconfigurable特性默認爲true

示例:

1

2

3

4

5

6

7

8

9

10

11

// 1)對象直接量;屬性特性默認爲true

var o1 = {

    name: 'tom'

};

console.log(Object.getOwnPropertyDescriptor(o1, 'name')); // => Object {value: "tom", writable: true, enumerable: true, configurable: true}

 

// 2)經過Object.create建立,屬性特性默認爲false

var o2 = Object.create(null, {

    name: {value:'tom'}

});

console.log(Object.getOwnPropertyDescriptor(o2, 'name')); // => Object {value: "tom", writable: false, enumerable: false, configurable: false}

 

6.2 訪問器屬性

說明:設置屬性的訪問方式;set、get特性等

特性名稱

描述

默認值

get

屬性的返回值函數

undefined

set

屬性的設置值函數;含有一個賦值參數

undefined

enumerable

是否可枚舉屬性;true:可枚舉,可經過for/in語句枚舉屬性;false:不可枚舉

false

configurable

是否可修改屬性的特性;true:可修改屬性的特性(如把writablefalse改成true);false:不可修改屬性的特性

false

 

示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

var obj = {};

 

// 添加一個屬性,並設置爲訪問器屬性

Object.defineProperty(obj, "name", {

    get: function () {

        return this._name; // get和set裏的變量不要使用屬性,如:屬性爲name,get和set用的是_name

    },

    set: function (x) {

        if (isNaN(x)) {

            this._name = x;

        } else {

            this._name = 'name不能爲純數字';

        }

    },

    enumerable: true,

    configurable: true

});

 

console.log(Object.getOwnPropertyDescriptor(obj, 'name')); // => Object {get: function, set: function, enumerable: true, configurable: true}

obj.name = '12';

console.log(obj.name); // => name不能爲純數字

 

 

 

 

單單js運行方式

(1) 控制檯

 

(2)在線js編輯器RunJS、JSBin等(推薦)

(3)命令行:node 文件名(加不加js均可以) 這種太麻煩了

(4)   VScode把program 換成"program": "${file}"

一開始 配置錯了,改爲${file} 就解決了,就是運行當前文件

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

《編寫可維護的JavaScript》學習筆記

統一編程風格:

編程風格(style guideline)、編碼規範(code convention),編程風格是編碼規範的一種。

編碼規範還包括編程最佳實踐、文件和目錄的規劃、註釋等。

JSHint是JSLint的一個分支項目。JSHint較寬鬆,當出現語法錯誤時,能夠關掉編程風格檢查(可配置的選項不少,JSLint較少)。

1、格式化:

(1)縮進:建議在編輯器中配置敲入Tab鍵時插入4個空格。

(2)語句結尾:建議不要省略分號,雖然分析器有自動分號插入(Automatic Semicolon Insertion, ASI)機制。

(3)行的長度:最長不該當超過80個字符。

(4)換行:一般在運算符(例如逗號)後換行,下一行會增長兩個層級(例如8個字符)的縮進。

(5)空行:語義不相關用空行分隔,有關聯的代碼展示在一塊兒。

下面場景添加空行挺好:

在方法之間。

在方法中的局部變量(localvariable)和第一條語句之間。

在多行或單行註釋以前·

在方法內的邏輯片斷之間插入空行,提升可讀性。

(6)命名:駝峯式命名法 大駝峯命名法(Pascal case) 小駝峯命名法(Camel case)

6.1    變量和函數:變量名前綴是名詞,函數名前綴是動詞。foo、bar、tmp之類沒有意義的命名儘可能避免。

約定:

動詞

含義

can

函數返回一個布爾值

has

函數返回一個布爾值

is

函數返回一個布爾值

get

函數返回一個非布爾值

set

函數用來保存一個值

 

jQuery顯然並無遵循這種函數命名約定,一部分緣由在於jQuery中方法的使用方式,不少方法同時用做getter和setter.

好比,$("body").attr("class")能夠取到class屬性的值,而$("body").attr("class","selected")能夠給class屬性賦值。

儘管如此,仍是推薦使用動詞做爲函數名前綴。

6.2     常量:都大寫,用下劃線分隔。

6.3     構造函數:大駝峯命名法。

(7)直接量

7.1    字符串

// 合法的JavaScript代碼

Var name = "Nicholas says, \"Hi.\"";

// 也是合法的JavaScript代碼

Var name= 'Nicholas says, "Hi"';

在使用雙引號括起來的字符串裏須要對雙引號進行轉義,

而在使用單引號括起來的字符串裏則沒必要如此。

 

關於字符串還有另一個問題須要注意,即建立多行字符串。這個特性並不是來自JavaScript語言自己,

卻在幾乎全部的(JavaScript)引擎中正常工做。

// 很差的寫法

var longstring = "Here's the story, Of a man \

named Brady . " ;

// Good

var longstring = "Here ' S the story, Of a man

     "named Brady .

7.2     數字

// 不推薦的小數寫法:沒有整數部分

var price = .1;

7.3     null

/ / 很差的寫法:檢測是否傳入了參數

function dosomething(argl, arg2, arg3, arg4) {

if (arg4 != null) {

doSomethingE1se () ;

}

}

理解null最好的方式是將它當作對象的佔位符(placeholder)。

7.4     undefined

未聲明的變量和未初始化的變量,typeof運算結果都是undefined

// foo未被聲明

var person;

console.log(typeof person); // "undefined"

console. log(typeof foo); // "undefined"

 

var person = null;

console.log(typeof person); // "object"

將變量初始值賦值爲null代表了這個變量的意圖,它最終極可能賦值爲對象。

typeof運算符運算null的類型時返回"object",這樣就能夠和undefined區分開了。

7.5     建議用對象直接量

7.6     建議用數組直接量

2、註釋

空格:雙斜槓後、星號後

空行:多行註釋前

縮進

 

// 好的寫法

// if (condition) {

//         doSomething();

//        thenDoSomethingEIse();

// }

 

// 很差的寫法:這裏應當用多行註釋

// 接下來的這段代碼很是難,那麼,讓我詳細解釋一下

// 這段代碼的做用是首先判斷條件是否爲真

// 只有爲真時纔會執行,這裏的條件是經過

 

單行註釋

多行註釋(Java的多行註釋每一行都有星號)

文檔註釋(JavaDoc風格)

 

初始化某變量這種顯而易見的註釋就不用寫了,但變量改變有什麼特殊意義能夠寫。

 

要添加註釋:

難以理解的代碼

可能被認爲錯誤的代碼

瀏覽器特效hack

 

3、語句和表達式

一、if的花括號要加,並且不要寫成一行:if (condition) { doSomething(); }

全部塊語句都不要省略花括號。

if

for

while

do… while…

try...catch...finally …

推薦花括號的對齊方式爲第一行末尾,不要另起一行。

塊語句間隔建議:在括左圓括號以前和右圓括號以後各添加一個空格。好比:

if  (condition)  {

dosomething();

}

 

二、switch:

(1)縮進和第二個case開始,每一個case語句前加空行

(2)case可連續執行,即

case "first":

case "second":

// …

break;

(3)default中若是沒有邏輯能夠省略

三、with

 

推薦避免使用with語句

with語句能夠更改包含的上下文解析變量的方式。經過with能夠用局部變量和函數的形式來訪問特定對象的屬性和方法,

這樣就能夠將對象前綴通通省略掉。若是一段代碼中書寫了不少對象成員,則能夠使用with語句來縮短這段代碼。

var book = {title: "Maintainable JavaScript" ,author: "Nicholas C. "The book is {msg Zees"); var msg = *author;} "The book is Maintainable JavaScript by Nicholas C. title; msg Zakas " " by " " v:shapes="圖片_x0020_52">

在這個例子中,with語句花括號內的代碼中的book的屬性都是經過局部變量來讀取的,以加強標識符的解析。

問題是咱們很難分辨出title和author出如今哪一個位置,也難分辨出message究竟是局部變量仍是book的一個屬性。

實際上這種困惑對開發者的影響更甚,JavaScript引擎和壓縮工具沒法對這段代碼進行優化,由於它們沒法猜出代碼的正確含義。

 

在嚴格模式中,with語句是被明確禁止的,若是使用則報語法錯誤。

 

四、for

遍歷數組成員

儘可能避免用continue,能夠修改條件語句便可達到一樣效果。

五、for-in

遍歷對象屬性(還會遍歷從原型繼承來的屬性)

最好用hasOwnProperty()方法來爲for-in循環過濾出實例屬性。

var prop;

for (prop in object) {

if (object.hasOwnProperty(prop)) {

console.log("Property name is " + prop);

console.log("Property value is " + object[prop]);

}

}

4、變量、函數和運算符

JavaScript編程的本質是編寫一個個函數來完成任務。

10+undefined 返回NaN

4.1  變量聲明

推薦單var語句

4.2  函數聲明

和變量聲明同樣,函數聲明也會被JavaScript引擎提早。所以,在代碼中函數的調用能夠出如今函數聲明以前。

// 不推薦

doSomething ();

function doSomething() {

alert("cxf");

}

這段代碼是能夠正常運行的,由於JavaScnpt引擎將這段代碼解析爲:

function doSomething() {

alert("cxf");

doSomething ();

因爲JavaScript的這種行爲,咱們推薦老是先聲明JavaScript函數而後使用函數。

 

函數聲明不該當出如今語句塊以內。

 

4.3  當即調用的函數

當即執行的函數要加圓括號

var value = (function()

// 函數體

return {

message : "cxf"

}

}());

 

4.4  嚴格模式

最好不要在全局做用域中使用「use strict」

// 很差的寫法-全局的嚴格模式

"use strict";

function doSomething() {

//…

}

// 好的寫法

function doSomething0

"usestrict";

//…

 

若是你但願在多個文件中應用嚴格模式而沒必要寫不少行「use strict」的話,能夠使

用當即執行的函數。

         / / 好 的 寫 法

(function () {

"use strict";

function doSomething () {

/ / …

}

function doSomethingElse () {

/ / …

}

})();

 

4.5  相等

推薦老是用===和 !==

當發生強制類型轉換時,字符串會被轉換爲數字,相似使用Number()轉換函數。

若是一個布爾值和數字比較,布爾值會首先轉換爲數字,而後進行比較。

若是其中一個值是對象而另外一個不是,則會首先調用對象的valueOf()方法,獲得原始類型值再進行比較。

若是沒有定義valueOf(),則調用toString()。

 

4.6  eval()

 

 

 

 

 

4.7

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

對於已存在的JavaScript對象的方法:不覆蓋;不新增;不刪除。

 

修改對象(對象擴充)最受歡迎的形式是繼承。若是一種類型的對象已經作到了你想要的大多數工做,那麼繼承自它,而後再新增一些功能便可。

繼承包括基於對象的繼承(也常被叫作原型繼承)和基於類型的繼承。

 

基於對象的繼承(也常被叫作原型繼承):一個對象繼承另一個對象不須要調用構造函數,依賴於原型。

ES5的Object.create()方法是實現這種繼承的最簡單的方式。

var person = {

name: "cxf",

sayName: function() {

console.log(this.name);

}

};

var myPerson = Object.create(person); // 等價於myPerson.prototype = person; 這兩種方法均可以讓myPerson可以訪問person的屬性和方法。

myPerson.sayName();  // cxf

這個例子建立了一個新對象myPerson,它繼承自person。

 

基於類型的繼承是經過構造函數而非對象。基於類型的繼承通常須要兩步:首先,原型繼承,而後,構造器繼承。

(構造器繼承是調用超類的構造函數時傳入新建的對象做爲其this的值)

function MyError (message) {

this.message = message;

}

MyError.prototype = new Error();

 

function Person (name) {

this.name;

}

function Author (name) {

Person.call(this, name);

}

Author.prototype = new Person();

 

 

 

包裝器模式(也叫門面模式)

 

 

 

 

 

 

 

 

 

 

 

 

阻止修改

程度從淺到深依次爲:

(1)防止擴展

禁止「添加」

(2)密封

禁止「添加」+「刪除」

(3)凍結

禁止「添加」+「刪除」+「修改」

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

lambda表達式是匿名函數,可是匿名函數不全是使用lambda表達式來寫的。

 

 

 

 

 

JavaScript書籍閱讀筆記

在函數開始執行時建立全部的局部變量,稱爲提高。

規範代碼,爲擴展作好準備。eg:全局變量放開頭、函數放在一塊兒,局部變量放在函數體開頭。

 

修改數組元素:flavor[3] = "chocolate";

屬性length

索引能夠是一個變量:

eg:var rand = Math.floor(Math.random() * words.length);

alert(words[rand]);

數組元素能夠是任何JavaScript值(數字、字符串、布爾值、其餘數組、對象等)。

訪問索引太大或過小(小於0)的數組元素時,結果都是undefined。

稀疏數組沒賦值處都是undefined,長度是最大索引+1。

未初始化的變量的值是undefined,沒有值的變量也會佔用計算機內存。

myArray[myArray.length-1]獲取最後一個數組元素。

while(answer != "forty") 等價於 for(;answer != "forty";)

if(myarr[i] == undefined) undefined是一個值,不是一個字符串,不能加引號

i = i + 1 等價於 i++

能夠省略初始值,建立一個空數組 var arr = [];

給數組添加新元素能夠給指定索引處的元素賦值(可「稀疏」)或push方法。

數組是特殊的對象,對象能夠有關聯的函數(eg:push()),用於操做對象。

[]屬於字面量,還能夠new Array(3)

對象變量又叫引用變量

重構(refactor)指的是不改變代碼功能的狀況下,對齊進行從新組織,一般是函數返回值。

對象有屬性和行爲,每一個屬性都有名稱和值。

屬性名能夠是任何字符串,包含空格的字符串用引號括起來。

在同一個對象中,不能包含兩個同名的屬性。

最後一個屬性名和屬性值對後,不能添加逗號,現代瀏覽器大多數不會致使錯誤,舊版本會致使JS中止執行。

 

 

Geolocation

 

 

 

 

 

 

 

Web Workers

 

 

 

 

 

元 累 , 那 是 不 是 就 不 能 向 worker 中 添 加 其 他 腳 本 了 " v:shapes="圖片_x0020_2">

相關文章
相關標籤/搜索