JS疑難點筆記

1、數據類型
JavaScript不區分整數和浮點數,統一用Number表示
2、比較運算符
JavaScript在設計時,有兩種比較運算符:
第一種是==比較,它會自動轉換數據類型再比較,很多時候,會得到非常詭異的結果;
第二種是===比較,它不會自動轉換數據類型,如果數據類型不一致,返回false,如果一致,再比較。
由於JavaScript這個設計缺陷,不要使用==比較,始終堅持使用===比較。
另一個例外是NaN這個特殊的Number與所有其他值都不相等,包括它自己:

NaN === NaN; // false

唯一能判斷NaN的方法是通過isNaN()函數:

isNaN(NaN); // true
最後要注意浮點數的相等比較:

1 / 3 === (1 - 2 / 3); // false

這不是JavaScript的設計缺陷。浮點數在運算過程中會產生誤差,因爲計算機無法精確表示無限循環小數。要比較兩個浮點數是否相等,只能計算它們之差的絕對值,看是否小於某個閾值:

Math.abs(1 / 3 - (1 - 2 / 3)) < 0.0000001; // true

null和undefined
null表示一個“空”的值,它和0以及空字符串’‘不同,0是一個數值,’'表示長度爲0的字符串,而null表示“空”。
在其他語言中,也有類似JavaScript的null的表示,例如Java也用null,Swift用nil,Python用None表示。但是,在JavaScript中,還有一個和null類似的undefined,它表示“未定義”。
JavaScript的設計者希望用null表示一個空的值,而undefined表示值未定義。事實證明,這並沒有什麼卵用,區分兩者的意義不大。大多數情況下,我們都應該用null。undefined僅僅在判斷函數參數是否傳遞的情況下有用。
數組
數組是一組按順序排列的集合,集合的每個值稱爲元素。JavaScript的數組可以包括任意數據類型。例如:

[1, 2, 3.14, 'Hello', null, true];

上述數組包含6個元素。數組用[]表示,元素之間用,分隔。
對象
JavaScript的對象是一組由鍵-值組成的無序集合,例如:

var person = {
    name: 'Bob',
    age: 20,
    tags: ['js', 'web', 'mobile'],
    city: 'Beijing',
    hasCar: true,
    zipcode: null
};

javaScript對象的鍵都是字符串類型,值可以是任意數據類型。上述person對象一共定義了6個鍵值對,其中每個鍵又稱爲對象的屬性,例如,person的name屬性爲’Bob’,zipcode屬性爲null。
要獲取一個對象的屬性,我們用對象變量.屬性名的方式:

person.name; // 'Bob'
person.zipcode; // null

由於JavaScript的對象是動態類型,你可以自由地給一個對象添加或刪除屬性:

var xiaoming = {
    name: '小明'
};
xiaoming.age; // undefined
xiaoming.age = 18; // 新增一個age屬性
xiaoming.age; // 18
delete xiaoming.age; // 刪除age屬性
xiaoming.age; // undefined
delete xiaoming['name']; // 刪除name屬性
xiaoming.name; // undefined
delete xiaoming.school; // 刪除一個不存在的school屬性也不會報錯

javaScript的對象是一種無序的集合數據類型
如果訪問一個不存在的屬性會返回什麼呢?JavaScript規定,訪問不存在的屬性不報錯,而是返回undefined:
不過要小心,如果in判斷一個屬性存在,這個屬性不一定是xiaoming的,它可能是xiaoming繼承得到的:

'toString' in xiaoming; // true

因爲toString定義在object對象中,而所有對象最終都會在原型鏈上指向object,所以xiaoming也擁有toString屬性。

要判斷一個屬性是否是xiaoming自身擁有的,而不是繼承得到的,可以用hasOwnProperty()方法:

var xiaoming = {
    name: '小明'
};
xiaoming.hasOwnProperty('name'); // true
xiaoming.hasOwnProperty('toString'); // false

變量
在JavaScript中,使用等號=對變量進行賦值。可以把任意數據類型賦值給變量,同一個變量可以反覆賦值,而且可以是不同類型的變量,但是要注意只能用var申明一次
這種變量本身類型不固定的語言稱之爲動態語言,與之對應的是靜態語言。靜態語言在定義變量時必須指定變量類型,如果賦值的時候類型不匹配,就會報錯

操作字符串
1、計算長度

var s = 'Hello, world!';
s.length; // 13

2、要獲取字符串某個指定位置的字符,使用類似Array的下標操作,索引號從0開始:

var s = 'Hello, world!';
s[0]; // 'H'
s[6]; // ' '
s[7]; // 'w'
s[12]; // '!'
s[13]; // undefined 超出範圍的索引不會報錯,但一律返回undefined

JavaScript爲字符串提供了一些常用方法,注意,調用這些方法本身不會改變原有字符串的內容,而是返回一個新字符串:
toUpperCase()把一個字符串全部變爲大寫:
toLowerCase()把一個字符串全部變爲小寫:
indexOf()會搜索指定字符串出現的位置:

var s = 'hello, world';
s.indexOf('world'); // 返回7
s.indexOf('World'); // 沒有找到指定的子串,返回-1

substring()返回指定索引區間的子串:

var s = ‘hello, world’
s.substring(0, 5); // 從索引0開始到5(不包括5),返回’hello’
s.substring(7); // 從索引7開始到結束,返回’world’

數組
要取得Array的長度,可以直接訪問length屬性:

var arr = [1, 2, 3.14, 'Hello', null, true];
arr.length; // 6

**請注意:**直接給Array的length賦一個新的值會導致Array大小的變化

var arr = [1, 2, 3];
arr.length; // 3
arr.length = 6;
arr; // arr變爲[1, 2, 3, undefined, undefined, undefined]
arr.length = 2;
arr; // arr變爲[1, 2]

Array可以通過索引把對應的元素修改爲新的值,因此,對Array的索引進行賦值會直接修改這個Array:

var arr = [‘A’, ‘B’, ‘C’];
arr[1] = 99;
arr; // arr現在變爲[‘A’, 99, ‘C’]
請注意,如果通過索引賦值時,索引超過了範圍,同樣會引起Array大小的變化:

var arr = [1, 2, 3];
arr[5] = 'x';
arr; // arr變爲[1, 2, 3, undefined, undefined, 'x']

大多數其他編程語言不允許直接改變數組的大小,越界訪問索引會報錯。然而,JavaScript的Array卻不會有任何錯誤。在編寫代碼時,不建議直接修改Array的大小,訪問索引時要確保索引不會越界。

indexOf
與String類似,Array也可以通過indexOf()來搜索一個指定的元素的位置:

var arr = [10, 20, '30', 'xyz'];
arr.indexOf(10); // 元素10的索引爲0
arr.indexOf(20); // 元素20的索引爲1
arr.indexOf(30); // 元素30沒有找到,返回-1
arr.indexOf('30'); // 元素'30'的索引爲2

注意了,數字30和字符串’30’是不同的元素。
slice
slice()就是對應String的substring()版本,它截取Array的部分元素,然後返回一個新的Array:

var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
arr.slice(0, 3); // 從索引0開始,到索引3結束,但不包括索引3: ['A', 'B', 'C']
arr.slice(3); // 從索引3開始到結束: ['D', 'E', 'F', 'G']

注意到slice()的起止參數包括開始索引,不包括結束索引。

如果不給slice()傳遞任何參數,它就會從頭到尾截取所有元素。利用這一點,我們可以很容易地複製一個Array:

var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
var aCopy = arr.slice();
aCopy; // ['A', 'B', 'C', 'D', 'E', 'F', 'G']
aCopy === arr; // false

push和pop
push()向Array的末尾添加若干元素,pop()則把Array的最後一個元素刪除掉:

var arr = [1, 2];
arr.push('A', 'B'); // 返回Array新的長度: 4
arr; // [1, 2, 'A', 'B']
arr.pop(); // pop()返回'B'
arr; // [1, 2, 'A']
arr.pop(); arr.pop(); arr.pop(); // 連續pop 3次
arr; // []
arr.pop(); // 空數組繼續pop不會報錯,而是返回undefined
arr; // []

unshift和shift
如果要往Array的頭部添加若干元素,使用unshift()方法,shift()方法則把Array的第一個元素刪掉:

var arr = [1, 2];
arr.unshift('A', 'B'); // 返回Array新的長度: 4
arr; // ['A', 'B', 1, 2]
arr.shift(); // 'A'
arr; // ['B', 1, 2]
arr.shift(); arr.shift(); arr.shift(); // 連續shift 3次
arr; // []
arr.shift(); // 空數組繼續shift不會報錯,而是返回undefined
arr; // []

sort
sort()可以對當前Array進行排序,它會直接修改當前Array的元素位置,直接調用時,按照默認順序排序:

var arr = ['B', 'C', 'A'];
arr.sort();
arr; // ['A', 'B', 'C']

能否按照我們自己指定的順序排序呢?完全可以,我們將在後面的函數中講到。

reverse
reverse()把整個Array的元素給掉個個,也就是反轉:

var arr = ['one', 'two', 'three'];
arr.reverse(); 
arr; // ['three', 'two', 'one']

splice
splice()方法是修改Array的“萬能方法”,它可以從指定的索引開始刪除若干元素,然後再從該位置添加若干元素:

var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 從索引2開始刪除3個元素,然後再添加兩個元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回刪除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只刪除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不刪除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因爲沒有刪除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']

concat
concat()方法把當前的Array和另一個Array連接起來,並返回一個新的Array:

var arr = ['A', 'B', 'C'];
var added = arr.concat([1, 2, 3]);
added; // ['A', 'B', 'C', 1, 2, 3]
arr; // ['A', 'B', 'C']

請注意,concat()方法並沒有修改當前Array,而是返回了一個新的Array。

實際上,concat()方法可以接收任意個元素和Array,並且自動把Array拆開,然後全部添加到新的Array裏:

var arr = ['A', 'B', 'C'];
arr.concat(1, 2, [3, 4]); // ['A', 'B', 'C', 1, 2, 3, 4]

join
join()方法是一個非常實用的方法,它把當前Array的每個元素都用指定的字符串連接起來,然後返回連接後的字符串:

var arr = ['A', 'B', 'C', 1, 2, 3];
arr.join('-'); // 'A-B-C-1-2-3'

如果Array的元素不是字符串,將自動轉換爲字符串後再連接。
關於typeof
我們用typeof操作符獲取對象的類型,它總是返回一個字符串

typeof 123; // 'number'
typeof NaN; // 'number'
typeof 'str'; // 'string'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof Math.abs; // 'function'
typeof null; // 'object'
typeof []; // 'object'
typeof {}; // 'object'

總結一下,有這麼幾條規則需要遵守:

不要使用new Number()、new Boolean()、new String()創建包裝對象;

用parseInt()或parseFloat()來轉換任意類型到number;

用String()來轉換任意類型到string,或者直接調用某個對象的toString()方法;

通常不必把任意類型轉換爲boolean再判斷,因爲可以直接寫if (myVar) {…};

typeof操作符可以判斷出number、boolean、string、function和undefined;

判斷Array要使用Array.isArray(arr);

判斷null請使用myVar === null;

判斷某個全局變量是否存在用typeof window.myVar === ‘undefined’;

函數內部判斷某個變量是否存在用typeof myVar === ‘undefined’。

最後有細心的同學指出,任何對象都有toString()方法嗎?null和undefined就沒有!確實如此,這兩個特殊值要除外,雖然null還僞裝成了object類型。

更細心的同學指出,number對象調用toString()報SyntaxError:

123.toString(); // SyntaxError

遇到這種情況,要特殊處理一下:

123..toString(); // '123', 注意是兩個點!
(123).toString(); // '123'

不要問爲什麼,這就是JavaScript代碼的樂趣!

一個非常非常坑爹的地方,就是JavaScript的月份範圍用整數表示是0~11,0表示一月,1表示二月……,所以要表示6月,我們傳入的是5!這絕對是JavaScript的設計者當時腦抽了一下,但是現在要修復已經不可能了。

JavaScript的Date對象月份值從0開始,牢記0=1月,1=2月,2=3月,……,11=12月。
關於Form
沒有name屬性的的數據不會被提交
獲取值
如果我們獲得了一個節點的引用,就可以直接調用value獲得對應的用戶輸入值:

// <input type="text" id="email">
var input = document.getElementById('email');
input.value; // '用戶輸入的值'

這種方式可以應用於text、password、hidden以及select。但是,對於單選框和複選框,value屬性返回的永遠是HTML預設的值,而我們需要獲得的實際是用戶是否“勾上了”選項,所以應該用checked判斷:

// <label><input type="radio" name="weekday" id="monday" value="1"> Monday</label>
// <label><input type="radio" name="weekday" id="tuesday" value="2"> Tuesday</label>
var mon = document.getElementById('monday');
var tue = document.getElementById('tuesday');
mon.value; // '1'
tue.value; // '2'
mon.checked; // true或者false
tue.checked; // true或者false

設置值
設置值和獲取值類似,對於text、password、hidden以及select,直接設置value就可以:

// <input type="text" id="email">
var input = document.getElementById('email');
input.value = '[email protected]'; // 文本框的內容已更新

對於單選框和複選框,設置checked爲true或false即可。

AJAX請求是異步執行的,也就是說,要通過回調函數獲得響應

Jquery
什麼是jQuery對象?jQuery對象類似數組,它的每個元素都是一個引用了DOM節點的對象。
如果id爲abc的

不存在,返回的jQuery對象如下:

[]

總之jQuery的選擇器不會返回undefined或者null,這樣的好處是你不必在下一行判斷if (div === undefined)
通常很多節點有多個class,我們可以查找同時包含red和green的節點:

var a = $('.red.green'); **// 注意沒有空格!**
// 符合條件的節點:
// <div class="red green">...</div>
// <div class="blue green red">...</div>

Jqury表單提交 .submit()
當用戶試圖提交表單時,就會在這個表單元素上觸發submit事件。。它只能綁定在元素上。
以下幾種情況會導致表單被提交。
用戶點擊了, , 或者 ,或者當某些表單元素獲取焦點時,敲擊Enter(回車鍵),都可以提交。

jQuery 入口函數:

$(document).ready(function(){
// 執行代碼});或者
$(function(){
// 執行代碼});
JavaScript 入口函數:

window.onload = function () {
// 執行代碼}
jQuery 入口函數與 JavaScript 入口函數的區別:

jQuery 的入口函數是在 html 所有標籤(DOM)都加載之後,就會去執行。
JavaScript 的 window.onload 事件是等到所有內容,包括外部圖片之類的文件加載完後,纔會執行。

獲得內容 - text()、html() 以及 val() 三個簡單實用的用於 DOM 操作的 jQuery 方法:

text() - 設置或返回所選元素的文本內容
html() - 設置或返回所選元素的內容(包括 HTML 標記)
val() - 設置或返回表單字段的值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章