JavaScript 字面量 和 變量html
var a; //只是聲明變量而沒有賦值,則該變量的值是undefined var b = 666;
c = 222; // 變量賦值的時候,忘了寫命令,這條語句也是有效的。
// 不寫的作法,不利於表達意圖,並且容易不知不覺地建立全局變量
// 因此建議老是使用命令聲明變量。
console.log(ddd); // 變量沒有聲明就直接使用,會報錯,告訴你變量未定義varvarvar
JavaScript 標識符面試
指 js 中能夠由咱們命名的名字。。。如變量名,函數名... ...編程
var 臨時變量 = 1;
學習 js 三部分數組
JavaScript 有六種數據類型 (ES6 又新增了第七種 Symbol 類型的值)瀏覽器
\uxxxx
的形式,其中xxxx
表明該字符的 Unicode 碼點。好比,\u00A9
表明版權符號。
var s = '\u00A9'; // s = "©" var f\u006F\u006F = 'abc'; // foo = "abc";
btoa():任意值轉爲 Base64 編碼 atob():Base64 編碼轉爲原來的值 var string = 'Hello World!'; btoa(string) // "SGVsbG8gV29ybGQh" atob('SGVsbG8gV29ybGQh') // "Hello World!" btoa('你好') // 不適合非 ASCII 碼的字符,會報錯 function b64Encode(str) { return btoa(encodeURIComponent(str)); } function b64Decode(str) { return decodeURIComponent(atob(str)); } b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE" b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"
isFinite()
方法返回一個布爾值,表示某個值是否爲正常的數值。
isFinite(Infinity) // false isFinite(-Infinity) // false isFinite(NaN) // false isFinite(undefined) // false // 其餘都返回 true isFinite(null) // true isFinite(-1) // true
// parseInt() 獲取字符串中整數部分 // 利用 parseInt("",num) 進行進制轉換 parseInt('1000', 10) // 1000 parseInt('1000', 2) // 8 parseInt('1000', 6) // 216 parseInt('1000', 8) // 512 // parseFloat() 獲取字符串中的浮點數部分 parseFloat('314e-2') // 3.14 parseFloat('0.0314E+2') // 3.14 若是字符串符合科學計數法,則會進行相應的轉換 parseFloat('\t\v\r12.34\n ') // 12.34 自動過濾字符串前導的空格
NaN
是 JavaScript 的特殊值,表示「非數字」(Not a Number),主要出如今將字符串解析成數字出錯的場合。isNaN
爲true
的值,有可能不是NaN
,而是一個字符串typeof NaN // 'number NaN === NaN // false NaN不等於任何值,包括它自己。 Boolean(NaN) // false [NaN].indexOf(NaN) // -1 5 - 'x' // NaN Math.acos(2) // NaN Math.log(-1) // NaN Math.sqrt(-1) // NaN 0 / 0 // NaN NaN + 32 // NaN NaN - 32 // NaN NaN * 32 // NaN NaN / 32 // NaN
isNaN('Hello') // true // 至關於 isNaN(Number('Hello')) // true
// 判斷更可靠的方法是,利用爲惟一不等於自身的值的這個特色,進行判斷。
NaNNaN
function myIsNaN(value) { return value !== value; }
// Infinity大於一切數值(除了NaN),-Infinity小於一切數值(除了NaN) 1 / -0 // -Infinity 負無窮 -1 / -0 // Infinity 正無窮 Infinity === -Infinity // false // 場景一 Math.pow(2, 1024) // Infinity 計算結果太大,超出了可以表示的範圍 // 場景二 0 / 0 // NaN 1 / 0 // Infinity
// 第1位: 符號位,0表示正數,1表示負數 // 第2位到第12位(共11位): 指數部分 // 第13位到第64位(共52位): 小數部分(即有效數字) // 第1位:符號位,0表示正數,1表示負數 // 第2位到第12位(共11位):指數部分 // 第13位到第64位(共52位):小數部分(即有效數字) // (-1)^符號位 * 1.xx...xx * 2^指數部分 // 上面公式(指數部分在0到2047之間),一個數在 JavaScript 內部實際的表示形式。 // 精度最多隻能到53個二進制位, // 這意味着,絕對值小於2的53次方的整數,即-253到253,均可以精確表示。 // 9007199254740992111 // 9007199254740992000 // 上面示例代表,大於2的53次方之後,多出來的有效數字(最後三位的111)都會沒法保存,變成0。
64 位浮點數的指數部分的長度是 11 個二進制位,意味着指數部分的最大值是2047(2的11次方減1)。服務器
也就是說,64 位浮點數的 指數部分 的值最大爲 2047,分出一半表示負數,則 JavaScript 可以表示的數值範圍爲2的1024到2-1023(開區間),超出這個範圍的數沒法表示。
若是一個數大於等於2的1024次方,那麼就會發生「正向溢出」,即 JavaScript 沒法表示這麼大的數,這時就會返回Infinity。模塊化
Math.pow(2, 1024) // Infinity
若是一個數小於等於2的-1075次方(指數部分最小值-1023,再加上小數部分的52位),那麼就會發生爲「負向溢出」,即 JavaScript 沒法表示這麼小的數,這時會直接返回0。函數式編程
Math.pow(2, -1075) // 0
0.1 + 0.2 === 0.3 // false 0.3 / 0.1 // 2.9999999999999996 (0.3 - 0.2) === (0.2 - 0.1) // false
+0
或-0
看成分母,返回的值是不相等的。
(1 / +0) === (1 / -0) // false // 上面的代碼之因此出現這樣結果, // 是由於除以正零獲得+Infinity,除以負零獲得-Infinity, // 這二者是不相等的
轉換規則是除了下面六個值被轉爲false, 其餘值都視爲true。 undefined null false 0 NaN "" 或 '' (空字符串)
變量 a
分別被賦值爲undefined
和null
,這兩種寫法的效果幾乎等價。函數
在if
語句中,它們都會被自動轉爲false
,相等運算符(==
)甚至直接報告二者相等。學習
if (!undefined) { console.log('undefined is false'); } // undefined is false if (!null) { console.log('null is false'); } // null is false undefined == null // true
null
表示"無"。根據 C 語言的傳統,null
能夠自動轉爲0
Number(null) // 0 5 + null // 5
null
就像在 Java 裏同樣,被當成一個對象,Brendan Eich 以爲表示「無」的值最好不是對象。
其次,那時的 JavaScript 不包括錯誤處理機制,Brendan Eich 以爲,若是null
自動轉爲0,很不容易發現錯誤。
所以,他又設計了一個undefined
。
區別是這樣的:
null
是一個表示「空」的對象,轉爲數值時爲0
;
undefined
是一個表示"此處無定義"的原始值,轉爲數值時爲NaN
。
Number(undefined) // NaN 5 + undefined // NaN
// 變量聲明瞭,但沒有賦值 var i; // i = undefined // 調用函數時,應該提供的參數沒有提供,該參數等於 undefined function f(x) { return x; } f() // x = undefined // 對象沒有賦值的屬性 var o = new Object(); o.p // o.p =undefined // 函數沒有返回值時,默認返回 undefined function f() {} ret = f() // ret = undefined
普通對象Object
數組對象Array
函數對象Function
宿主對象
自定義對象
var x = 'sex';
var obj = { foo: 'Hello', bar: 'World',
[x]: "男" };
// 屬性的值仍是一個對象,就造成了鏈式引用。
Object.keys
方法。
var obj = { key1: 1, key2: 2 }; Object.keys(obj); // ['key1', 'key2']
delete
命令用於刪除對象的屬性,刪除成功後返回 true
var obj = { p: 1 }; Object.keys(obj) // ["p"] delete obj.p // true obj.p // undefined Object.keys(obj) // []
// 注意: 刪除一個不存在的屬性,不報錯,並且返回
deletetrue
只有一種狀況,delete
命令會返回false
,那就是該屬性存在,且不得刪除。
// Object.defineProperty() 建立的對象obj的p屬性是不能刪除的, var obj = Object.defineProperty({}, 'p', { value: 123, configurable: false }); obj.p // 123 delete obj.p // false 因此delete命令返回false
即便delete
返回true
,該屬性依然可能讀取到值。
var obj = {}; delete obj.toString // true obj.toString // function toString() { [native code] } // 上面代碼中,toString是對象obj繼承的屬性, // 雖然delete命令返回true,但該屬性並無被刪除,依然存在
var obj = { p: 1 }; 'p' in obj // true 'toString' in obj // true // toString() 方法是繼承的 // 使用對象的hasOwnProperty方法判斷,是否爲對象自身的屬性 var obj = {}; if ('toString' in obj) { console.log(obj.hasOwnProperty('toString')) // false } // for...in循環用來遍歷一個對象的所有屬性。 // 遍歷的是對象全部可遍歷(enumerable)的屬性,會跳過不可遍歷的屬性 // 對象都繼承了toString屬性,可是for...in循環不會遍歷到這個屬性 // 關於對象屬性的可遍歷性,參見《標準庫》章節中 Object 一章的介紹。 var obj = {a: 1, b: 2, c: 3}; for (var i in obj) { console.log('鍵名:', i); console.log('鍵值:', obj[i]); } // 使用for...in的時候,應結合 hasOwnProperty(),在循環內判斷,某個屬性是否爲對象自身的屬性。 var person = { name: '老張' }; for (var key in person) { if (person.hasOwnProperty(key)) { console.log(key); } } // name
// 例一 , 設置已有屬性 var obj = { p1: 1, p2: 2, }; with (obj) { p1 = 4; p2 = 5; } // 必須是當前對象已經存在的屬性,不然創造一個當前做用域的全局變量
// 等同於 obj.p1 = 4; obj.p2 = 5;
// 例二 訪問已有屬性 with (document.links[0]){ console.log(href); console.log(title); console.log(style); }
// 等同於 console.log(document.links[0].href); console.log(document.links[0].title); console.log(document.links[0].style);
這是由於with
區塊沒有改變做用域,它的內部依然是當前做用域。這形成了with
語句的一個很大的弊病,就是綁定對象不明確。
x
究竟是全局變量,仍是對象obj
的一個屬性。這很是不利於代碼的除錯和模塊化,編譯器也沒法對這段代碼進行優化,只能留到運行時判斷,這就拖慢了運行速度。所以,建議不要使用with
語句,能夠考慮用一個臨時變量代替with
。面試題
1. a[變量] 其中 a 是一個對象,使用 [] 來讀寫對象,會調用 .toString() 將 變量 隱式轉換 爲 字符串
var a{}; var b = { n: 2 }; var c = { m: 3 }; a[b] = 4; // a[b.toString()] = 4 a["object Object"] = 4 a[c] = 5; // a[c.toString()] = 5 a["object Object"] = 5 console.log(a[b]); // 打印 5
== 會進行復雜的 隱式類型轉換
=== 會進行 數據類型 和 值 的比較
三種方法 肯定一個值是什麼數據類型
typeof 123 // "number" typeof '123' // "string" typeof false // "boolean" typeof typeof 123 // "string" 由於 typeof 返回值是 string
// 函數返回function function f(){} typeof f // "function" // 對象返回object typeof window // "object" typeof {} // "object"
/**** 一個數組 也返回 object ****/
typeof [] // "object" /**** null 返回 object 表示將要做爲對象使用 ****/ typeof null // "object" // undefined 返回 undefined typeof undefined // "undefined" // typeof能夠用來檢查一個沒有聲明的變量,而不報錯。 console.log(typeof a); // 返回一個字符串 "undefined" // 實際編程中,這個特色一般用在判斷語句 // 錯誤的寫法 if (v) { // ... } // ReferenceError: v is not defined // 正確的寫法 if (typeof v === "undefined") { // ... }
// 空數組([])的類型也是object,這表示在 JavaScript 內部,數組本質上只是一種特殊的對象。 // 這裏順便提一下,instanceof運算符能夠區分數組和對象。var o = {}; var a = []; o instanceof Array // false 對象不是數組類型的 a instanceof Array // true 數組是對象類型的
變量類型: 變量的類型其實是變量內存中數據的類型
數據對象:
數據
即存儲於內存中表明特定信息的東東,本質就是 01 二進制。
具備 可讀 、可傳遞 的基本特性,一切皆數據
數據運行於內存中,讀寫速度快。
垃圾回收機制: 當堆中的一個對象,再也沒有任何一個變量指向它,則將在一段時間後被銷燬
因此,咱們再也不須要某個對象時,只須要 obj = null; 便可
變量