跳到主要內容
黯羽輕揚每天積累一點點

JS 學習筆記 1_基礎與常識

免費2015-03-23#JS#js基础

JS 基礎知識,包括數據類型相關知識和其它常識

##1.六種數據類型##

5 種基礎的:Undefined,Null,Boolean,Number,String(其中 Undefined 派生自 Null)

1 種複雜的:Object(本質是一組無序鍵值對)

##2.字符串轉數字##

  • Number(str):先求值再轉換(先 valueOf 再 toString 都不行就是 NaN),一般與我們的預期結果不一樣,比如 Number('')=Number(false)=Number(null)=0 而 var x;Number(x)=NaN。。。所以一般都用下面兩種方式

  • parseInt(str):可以指定進制,建議使用 parseInt(x, 10);這樣的格式,即始終指明進制

  • parseFloat(str):不可以指定進制,解析整數時返回整數而不是浮點數

##3.獲取字符串長度##

String 類型的值都有 length 屬性。str.length 返回串長整數值,而不是通過其它函數來獲取串長

##4.值傳遞與地址傳遞##

函數傳參都是值傳遞

##5.作用域鏈##

本質是一個,存放了各層的變量對象(類似於編譯器的符號表指針棧),變量對象持有該層所有變量和函數的訪問權限,如果該層是函數,那麼變量對象是 arguments 對象,棧頂是正在執行的上下文環境對應的變量對象,棧底是全域執行環��對應的變量對象。

##6.作用域##

沒有塊級作用域,有函數作用域

##7.創建 Object 對象的 2 種方法##

  1. var obj = new Object();obj.attr = value;

傳統的方式,調用構造函數創建對象

  1. var obj = {attr1 : value1, attr2 : value2}或者 var obj = {"attr1" : value1, "attr2" : value2}

對象字面量表示法,屬性名可以是字符串

注意:

  1. 除非屬性名有歧義例如:null, var 等等,一般不要用字符串做屬性名,當然只是習慣約束

  2. 用對象字面量方式定義對象時,不會調用其構造函數

##8.訪問屬性值的兩種方法##

  1. obj.attr

  2. obj["attr"] 優點是可以通過變量來訪問屬性,如 var attrName = "attr";obj[attrName]更靈活

##9.數組的聲明與初始化##

  1. var arr = new Array(value1, value2...);

  2. var arr = Array(...);可以省略 new

  3. 數組字面量:var arr = [value1, value2...];

注意:用數組字面量定義數組時也不會調用其構造函數

##10.數組相關函數##

附錄

##11.函數聲明與函數表達式的區別##

  1. function fun(){...} js 引擎會在加載源代碼時生成該函數對象

  2. var fun = function(){...} js 引擎在執行時才會生成該函數對象

##12.函數重載##

不支持重載。後聲明的函數會覆蓋先聲明的,本質是對函數名進行了多次賦值操作(函數名只是一個指針變量)

##13.函數內部特殊屬性##

  1. arguments.callee 函數指針,指向擁有該 arguments 對象的函數,即當前函數

  2. this 當前執行環境的引用,頂層的 this 就是 window

  3. arguments.callee.caller 函數指針,指向調用當前函數的函數,沒有則返回 null

注意:this 可以是對象引用或者函數引用,但 callee 和 caller 只能是函數引用

##14.函數對象的屬性和方法##

  1. length 函數期望的命名參數的個數,js 中可以給函數傳遞任意多個參數,因為除了形參,還可以用 arguments 獲取任一參數

  2. prototype 指向函數的原型對象

  3. call(context, arg1, arg2...) 用來在特定的作用域中調用函數,解除對象與函數的緊耦合

  4. apply(context, arguments 或其它數組對象) 功能同上,支持數組參數

  5. bind/unbind(context, arg1, arg2...) 綁定/解綁執行環境或參數,可以從已有函數生成新函數,但用 bind 連續綁定是無效的(連續 != 多次),例如:

    function fun(){
        alert(this.data);
    }
    var obj = {
        data : 'obj_data'
    };
    var newObj = {
        data : 'new_obj_data'
    };
    fun1 = fun.bind(obj);
    fun1();
    fun2 = fun1.bind(newObj);//連續綁定
    fun2();
    fun3 = fun.bind(newObj);//多次綁定
    fun3();
    

以上代碼輸出'obj_data', 'obj_data', 'new_obj_data',第二次綁定失敗了,因為 bind 函數內部是用 call 來實現的,連續綁定的效果類似於:

    //第一次綁定得到的函數
    fun1 = fun.call(obj);
    //第二次綁定得到的函數
    fun2 = fun1.call(newObj);

第二次綁定得到的函數中 fun1 內部的 this 確實指向 newObj,但 fun1 中根本沒有用到 this,所以沒有任何影響

##15.一些常識##

  1. this 永遠指向自身所屬的對象(你是誰的屬性,你內部的 this 就是誰)

    var obj1 = {
        data : 1,
        fun : function(){
            alert(this.data);
        }
    };
    var obj2 = {
        data : 2
    };
    
    obj1.fun();
    obj2.fun = obj1.fun;
    obj2.fun();
    

    以上代碼輸出 1 和 2,因為執行過倒數第二句後,obj2 新增了一個 fun 屬性,值為 obj1.fun 的引用,但因為 obj2.fun 是 obj2 的屬性,所以 this 指向 obj2

  2. 盡量在構造函數原型上定義成員函數,因為直接在構造函數中定義的函數有運行時閉包的開銷

  3. 在 js 中應該用單引號,因為 JSON 和 XML 裡只有雙引號,用單引號可以避免轉義

  4. 盡量在變量聲明的同時初始化,以便區分 undefined 表示未聲明。因為對已聲明但未初始化的變量和未聲明的變量用 typeof 操作符都會返回"undefined"

  5. NaN(Not a Number)與任何值都不相等,包括 NaN 本身,所以需要用 isNaN() 函數來判斷

  6. 只能給引用類型的值動態地添加屬性。給基本類型的值添加屬性不會報錯但沒有任何意義

  7. 數組會根據索引自動增長。需要注意 length 屬性是可寫的,也就是說可以動態地設置數組長度,如截掉尾部元素

  8. 函數名只是一個指針變量。function fun{...} fun = null;只是斷開了引用關係,函數體並沒有被銷毀

##附錄##

###1.基礎數據類型###

  1. Undefined 已定義但未初始化的對象的預設值

  2. Null 表示一個空對象指針,所以用 typeof 檢測之返回 object

  3. Boolean 布林值,注意 Boolean() 轉換函數,規則如下:

  4. true/false ~ 不變

  5. 非空字符串/空字符串 ~ true/false

  6. 非 0 數字/0 和 NaN ~ true/false

  7. 任何對象/null ~ true/ false

  8. undefined ~ false

上面這些規則非常重要,因為 if 條件會自動應用 Boolean() 轉換,而且 if(obj) 是在 js 代碼中是很常見的,很多時候流程控制錯誤都是 if 條件自動轉換造成的

  1. Number 數值,js 中 +0 和 -0 相等,注意 NaN,它與任何東西都不相等,包括自身,而且它既不大於 n 也不小於等於 n。Number 變量支持 toString() 函數,可以用來對數值串進行進制轉換,例如 var num = 17;num.toString(16) 返回"11"

  2. String 字符串,注意字符串的不可變性,進行巨量拼接操作時應該用數組 + join 而不是循環+

###2.Object 類型變量的屬性和方法###

  1. Constructor 保存這構造函數的引用

  2. hasOwnProperty(porpertyName) 用來檢查當前對象是否擁有指定屬性(此處"屬性「包括屬性和方法)

  3. isPrototypeOf(obj) 用來當前對象是不是指定對象的原型

  4. propertyIsEnumerable(propertyName) 用來檢測指定屬性是否可枚舉

  5. toLocaleString() 相當於 toString() 函數,但附加了地區特徵

  6. toString() 返回對象的字符串表示

  7. valueOf() 返回對象的字符串、數值或布林值表示

###3.常見引用類型###

  1. Function js 中函數也是對象,非常靈活,例如:

    var load = window.onload;
    window.onload = function(){
        //do something
        load();//就是這麼簡單,添一對括號馬上執行
    }
    
  2. Array 數組類型的操作函數是最多的

  3. 棧方函數:push() 在數組末尾插一項,pop() 尾元出棧

  4. 隊列函數:push() 同上,shift() 首元出隊並返回首元;反向隊列(隊頭進,隊尾出)unshift()/pop()

  5. 排序函數:sort(fun) 無參比較字符串升序排列,有璨傳入自定義比較函數返回正值/負值/0;reverse() 反轉順序

    注意:sort()/reverse() 都會直接改變原數組,而且 sort() 預設實現方式不太科學,對 [1, 3, 10, 5] 排序的結果是 [1, 10, 3, 5],想要心裡想的結果,必須傳入自定義比較函數

4.  操作函數:
  1.  arr.concat(arr1, arr2\.\.\.) 連接形成新數組

  2.  arr.slice() 相當於 substring 對字符串的截取效果,用法也一樣

  3.  arr.splice() 向數組中部插入項,splice(startIndex, num, item1, item2\.\.\.) 表示把從 startIndex 開始的 num 項替換為各個 item,只有前兩個參數表示把從 startIndex 開始的 num 項換為空(也就是刪除),用 splice 可以實現刪除/替換/插入操作。

      *注意*:splice 函數也會直接改變原數組。

5.  位置函數:indexOf(value) 和 lastIndexOf(value),查找 value 的索引位置,沒找到返回 -1,內部用的是全等操作符(===)

6.  迭代函數:every(), filter(), forEach(), map(), some() 都是對數組中的每一項運行指定方法,IE9+ 支持且並不常用,在此不展開敘述

7.  歸約函數:reduce(), reduceRight() 不做介紹,原因同上

3. Date 類型:相關內容略多,參見W3School

  1. RegExp 類型:var regex = /^cat$/i;創建正則表達式(RegExp 類型),支持的模式有 g, i, m 分別表示全域模式,忽略大小寫模式,多行模式。當然,也可以用 new RegExp(strRegex, strMode),不過,有什麼理由非要去用這種方式呢?

js 支持正則捕獲,var matches = regex.exec(text); 通過 matches[0], matches[1]...來獲取捕獲到的內容

普通的正則匹配:regex.test(text) 返回 true/false

  1. 基本包裝類型:Boolean,String 和 Number,一直都在見面,只是沒有注意到,例如:

    var str = 'smilestome';
    var str_ = str.substring(1);
    

以上代碼等價於:

    var s1 = new String('smilestome');//創建包裝類型實例
    var s2 = s1.substring(1);//在實例上調用相應方法
    s1 = null;//銷毀實例

自動裝箱拆箱,為了讓基礎數據類型用起來更方便,但需要注意:new String() 與 String() 轉換方法不同,前者返回 object 類型,而後者返回 string 類型,鑑於這樣的區別,混用會引起不必要的麻煩,所以我們沒有理由顯式創建包裝類型。Boolean,Number 與之類似。

評論

暫無評論,快來發表你的看法吧

提交評論