Javascript查漏補缺

想複習一下javascript高級程序設計一書的內容,寫下了下面的筆記,都是比較細的點,想到什麼就寫什麼了,可能有點略雜。javascript

Array數組部分

1.Array的length不只是可讀的,並且是可寫的。這就意味着能夠經過修改length來直接裁剪數組。若是length直接改大,那麼沒有賦值的地方爲undefinedjava

var a = [1,2,3];
a.length=2;
a;//[1,2]
a.length=3;
a;//[1,2,undefined]

2.Array.concat()能夠接受不少個參數,而且也支持類型不同的。將會返回鏈接以後的副本,不會修改原來的數組數組

var a = [1,2,3];
var b = a.concat('a',[3,4,5],1);
a;//[1,2,3]
b;//[1,2,3,'a',3,4,5,1]

3.splice()函數app

參數數目 功能
兩個參數Array.splice(startPos,delNum) 進行刪除操做,第一個參數表示起始位置,第二個表示刪除的個數
多個參數Array.splice(startPos,delNum,*insetElems) 刪除並插入,前兩個參數同上,以後的參數爲在刪除的位置須要插入的元素。若是第二個參數爲0,僅進行插入操做。

函數Function和字符串String

1.要擅於利用arguments.callee進行解耦。咱們在寫遞歸函數的時候都會在函數內部調用自身函數,這時咱們若是使用自身的函數名,函數內部就和函數名有耦合。咱們直接使用arguments.callee就能夠訪問到函數名並進行調用函數

function addAll(n){
    if(n==1){return 1;}
    return n+addAll(n-1);
    return n+arguments.callee(n-1);//better!
}
var addAll_1 = addAll;
addAll_1(3);//error

2.引用類型和基本包裝類型最主要的就是對象的生存期。若是是使用new建立的引用類型實例,那麼執行流會一直生存到當前做用域結束。若是是自動建立的則其基本包裝類對象只存在一瞬間this

var s = "sad";
s.color = "red";
s.color;//null

3.使用new調用基本包裝類性的構造函數和直接調用同名函數的結果是不同的。編碼

var number = Number("123");
typeof number;//number

var number2 = new Number("123");
typeof number2;//Object

4.因爲字符串也是相似一個數組,咱們想要對string使用Array方法,可使用call或者applyprototype

var str = '123';
Array.prototype.map.call(str,function(ele){console.log(ele);}

經過這個方法可使用數組的不少方法,好比filter,forEach等。不過貌似不少地方均可以用相似這種模式。
5.數組的方法:trim(),concat()不少都不會修改原來數組的內容,只是建立副本並返回。
6.使用Global對象的encodeURIComponent()函數對全部非字母數字進行編碼。decodeURIComponent()進行解碼。這個以前寫爬蟲就爬到了不少相似於unicode的碼u5168,或者在網頁URI中的一些查詢字符%E5%93%88%E5%93%88之類的也能夠經過這個進行解碼,還算是比較好用的一個函數啦。
7.利用bind()函數進行過一次綁定以後就不再可以進行第二次綁定了。也就是說this已經被固定下來了。設計

var a = {name:"A"}
var b = {name:"B"}
function getName(){console.log(this.name);}
var getA = getName.bind(a);
getA();//A
var getB = getA.bind(b);
getB();//A

8.只要是繼承的,進行instanceof檢測的時候會返回truecode

a instanceof Object;//true
undefined instanceof Object;//false
null instanceof Object;//false

Object類的屬性的屬性

屬性的屬性就是指Object的屬性的一些特性。分爲數據屬性訪問器屬性。數據屬性是用來存儲數據數值的,而訪問器屬性通常進行get/set操做,而不能進行數據的存儲。
其中,數據屬性分爲四個:

1. [[Configurable]]表示可否經過delete刪除屬性從而從新定義屬性
2. [[Enumerable]]表示可否經過for-in循環返回屬性。
3. [[Writable]]表示可否修改屬性的值
4. [[Value]]表示值

訪問器屬性

1.[[Configurable]]:默認爲true。表示可否經過delete刪除屬性從而從新定義屬性,可否修改屬性特性,或者可否把屬性修改成訪問器屬性;
2.[[Enumerable]]:默認爲true。表示可否經過for-in循環返回屬性;
3.[[Get]]:讀取屬性時調用的函數,默認爲undefined;
4.[[Set]]:寫入屬性時調用的函數,默認爲undefined。

不能直接添加這些屬性。只能用Object.defineProperty()或者Object.defineProperties()進行設置。例子以下

var a = {_name:123}

Object.defineProperty(a, 'name', {
    get:function(){
        return "我是"+this._name;
    },
    set:function(newVal){
        if(newVal>20){
            this._name=newVal;
        }
    }
})

這裏a並無name這個屬性,可是經過get()創建了從name_name的映射。可使得數據屬性的操做更加靈活。
下面是同時進行多個屬性的設置的語法示例:(writable設置爲false表示不能進行值的修改。)

Object.defineProperties(
    a,{_name:{value:23,writable:false},{name:{get:function(){return this._name;},set:function(){}}
        }
    }
)

原型鏈

能夠經過對象實例來訪問保存在原型中的值,可是不能經過對象實例來重寫原型中的值,他會在實例的屬性中添加這個值而且遮蓋掉原型鏈中的值。可是經過__proto__.prop就能夠訪問到原型鏈中的prop屬性。
即使是在實例中設置屬性爲null也不會消除對原型屬性的遮蔽。除非使用delete

function Person(){
}
Person.prototype.name="aa";
var a = new Person();
var b = new Person();
a.name="bb";
b.name;//"aa"
a.name=null;
a.name;//null
a.__proto__.name;//"aa"
a.__proto__.name="bb";
b.name;//"bb"

能夠經過hasOwnProperty()來獲取到實例非原型鏈中是否有這個屬性。

若是要判斷實例有這個屬性(包括原型鏈中的屬性)用in這個操做符。
經過for-in循環返回的是對象可以訪問到的(包括原型鏈),並且enumerable設置爲true的屬性

var c={name:"123",age:23};
Object.defineProperty(c,'name',{enumerable:false})
for(ele in c){console.log(ele);}//only age

若是要返回全部實例非原型鏈屬性(不論是否能夠枚舉)

Object.keys(obj)//將返回全部可枚舉的,屬於實例對象的屬性的屬性名數組。
Object.getOwnPropertyNames(obj);//返回的是全部實例屬性(不包括原型鏈),不論是否可枚舉
相關文章
相關標籤/搜索