現(xiàn)在做項目基本是套用框架,不論是網(wǎng)上的前端還是后端框架,也會尋找一些封裝好的插件拿來即用,但還是希望拿來時最好自己過后再回過頭了解里面的原理,學習里面優(yōu)秀的東西,不論代碼封裝性,還是小到命名。
好吧,扯遠了,在這里要講的是大家前端用得多的JS,可能接觸最多的是Jquery,但原生的JS最好還是要了解的,至少能看懂別人的代碼,然后學習。
平時用得多的無非是if for 邏輯處理字符串,截斷字符串,數(shù)組,然后是查找元素,對元素背景什么的屬性操作,這些都是些實用性上的東西,這里講一些更深入點的,如何理解Javascript對象。
C#,Java都是面象對象的語言,但JavaScript本身不是面向對象的語言,而是基于對象的語言。JavaScript中所有事物都是對象, 包括字符串、數(shù)組、日期、數(shù)字,甚至是函數(shù)(驗證方法是你可以在實例上 . 出屬性)。
基于這點我們可以封裝自己的插件,這里就不講怎么制作插件了,想了解的可查詢我的如何制作插件的文章。
創(chuàng)建對象,平時用到的方法:
var emptyObject1 = {};?????????? //創(chuàng)建空對象var emptyObject2 = new Object(); //創(chuàng)建空對象var person = {"name":"sdcyst",??????????"age":18,
"sex":"male"};???? //創(chuàng)建一個包含初始值的對象person
alert(person.name);????????????? //sdcyst
alert(person["age"]);??????????? //18
注意上面如何訪問一個對象的屬性,通過"."操作符獲取對象的屬性,必須得知道屬性的名字.一般來說"[]"操作符獲取對象屬性的功能更強大一些,
可以在[]中放入一些表達式來取屬性的值,比較有靈活性,如name["name"+(i+1)];
delete操作符可以刪除對象中的某個屬性,判斷某個屬性是否存在可以使用"in"操作符,需要注意的是對象中的屬性是沒有順序的。
var name = {"name1":"NAME1","name2":"NAME2","name3":"NAME3","name4":"NAME4"};
var namestring = "";for(var props in name) {? //循環(huán)name對象中的屬性名字???
?namestring +=name[props];}alert(namestring);? //NAME1NAME2NAME3NAME4delete name.name1; ?
//刪除name1屬性delete name["name3"];? //刪除name3屬性
namestring = "";for(var props in name) {? //循環(huán)name對象中的屬性名字???
?namestring +=name[props];}
alert(namestring);? //NAME2NAME4
alert("name1" in name); //false
alert("name4" in name); //true
接下來講講比較常見的數(shù)組,對象是無序數(shù)據(jù)的集合,而數(shù)組則是有序數(shù)據(jù)的集合,數(shù)組中的數(shù)據(jù)(元素)通過索引(從0開始)來訪問,數(shù)組中的數(shù)據(jù)可以是任何的數(shù)據(jù)類型,數(shù)組本身仍舊是對象,創(chuàng)建數(shù)組可以用"[]"操作符,或者是用Array()構造函數(shù)來new一個。
var array1 = [];//創(chuàng)建空數(shù)組
var array2 =newArray();//創(chuàng)建空數(shù)組
array1 = [1,"s",[3,4],{"name1":"NAME1"}];
//alert(array1[2][1]);//4?? 訪問數(shù)組中的數(shù)組元素
alert(array1[3].name1);//NAME1 訪問數(shù)組中的對象
alert(array1[8]);//undefined
array2 = [,,];//沒有數(shù)值填入只有逗號,則對應索引處的元素為undefinedalert(array2.length);//3
alert(array2[1]);//undefined
需要注意的是var array =newArray(10);初始化的長度10實際上對數(shù)組沒有任何的約束力,數(shù)組的長度是可以任意改變的。
delete操作符刪除數(shù)組的元素,注意這個刪除僅僅是將數(shù)組在該位置的元素設為undefined,數(shù)組的長度并沒有改變。
var array =new Array("n1","n2","n3","n4","n5");//五個元素的數(shù)組
var astring = "";
alert(astring);//n1n2n3n4n5
delete array[3];//刪除數(shù)組元素的值
alert(array.length + "_" + array[3])//5_undefined
array.length= 3;//縮減數(shù)組的長度
alert(array[3]);//undefined
array.length = 8;//擴充數(shù)組的長度
alert(array[4]);//undefined
對象中也離不開函數(shù),那如何創(chuàng)建函數(shù):
function f(x) {........}
var f = function(x) {......}
上面這兩種形式都可以創(chuàng)建名為f()的函數(shù),不過后一種形式可以創(chuàng)建匿名函數(shù)。
方法的調用需要對象的支持,那么在方法中如何獲取對象的屬性呢?this!this關鍵字我們已經(jīng)很熟悉了,在javascript的方法中,我們可以用this來取得對方法調用者(對象)的引用,從而獲取方法調用者的各種屬性。
var obj = {"name":"NAME","sex":"female"};
obj.print=function() {//為對象添加方法alert(this.name + "_" +this["sex"]);
};
obj.print();//NAME_femaleobj.sex = "male";
obj.print();//NAME_male
來一個更加面向對象的例子。
var person = {name:"defaultname",
setName:function(s){this.name =s;
},"printName":function(){
alert(this.name);
}}
person.printName();//defaultnameperson.setName("newName");
person.printName();//newName
下面更深入點,每一個函數(shù)都包含了一個原型(prototype),我們可以簡單的把prototype看做是一個模版,新創(chuàng)建的自定義對象都是這個模版(prototype)的一個拷貝。
通過prototype創(chuàng)建自定義對象的一個例子:
// 構造函數(shù)
function Person(name, sex) {
this.name = name;
this.sex = sex;
}
// 定義Person的原型,原型中的屬性可以被自定義對象引用
Person.prototype = {
getName: function() {
return this.name;
},
getSex: function() {
return this.sex;
}
}
創(chuàng)建自定義對象(實例化類)
var zhang = new Person("ZhangSan", "man");
console.log(zhang.getName());? // "ZhangSan"
當代碼var zhang = new Person("ZhangSan", "man")執(zhí)行時,其實內部做了如下幾件事情:
創(chuàng)建一個空白對象(new Object())。
拷貝Person.prototype中的屬性(鍵值對)到這個空對象中(我們前面提到,內部實現(xiàn)時不是拷貝而是一個隱藏的鏈接)。
將這個對象通過this關鍵字傳遞到構造函數(shù)中并執(zhí)行構造函數(shù)。
將這個對象賦值給變量zhang。
上面我們提到了用new來創(chuàng)建一個對象的過程,事實上在這個過程中,當創(chuàng)建了空對象后,new會接著操作剛生成的這個對象的prototype屬性。
每個方法都有一個prototype屬性(因為方法本身也是對象),new操作符生成的新對象的prototype屬性值和構造方法的prototype屬性值是一致的。構造方
法的prototype屬性指向了一個prototype對象,這個prototype對象初始只有一個屬性constructor,而這個constructor屬性又指向了prototype屬性所在的方
法。有點暈,看下面的圖:

這樣,當用構造函數(shù)創(chuàng)建一個新的對象時,它會獲取構造函數(shù)的prototype屬性所指向的prototype對象的所有屬性。對構造函數(shù)對應的prototype對象所做的任何操作都會反應到它所生成的對象身上,所有的這些對象共享構造函數(shù)對應的prototype對象的屬性(包括方法)。
看個具體的例子吧:
functionPerson(name,sex) {//構造函數(shù)this.name =name;this.sex =sex;
}
Person.prototype.age= 12;//為prototype屬性對應的prototype對象的屬性賦值Person.prototype.print =function() {//添加方法alert(this.name+"_"+this.sex+"_"+this.age);
};varp1 =newPerson("name1","male");varp2 =newPerson("name2","male");
p1.print();//name1_male_12p2.print();//name2_male_12Person.prototype.age= 18;//改變prototype對象的屬性值,注意是操作構造函數(shù)的prototype屬性p1.print();//name1_male_18p2.print();//name2_male_18
在javascript中,所有的方法都有一個call方法和apply方法。這兩個方法可以模擬對象調用方法,它的第一個參數(shù)是對象,后面的參數(shù)表示對象調用這個方法時的參數(shù)。概念比較拗口,平時很少遇到,所以用得少,比較難得理解這里就不作過多的講解了,請自行查找說得更明了的文章來了解吧。
以上示例部分整理于園友文章,用得比較明了所以拿來講解,以上知識點可能只有在大家實際項目中運用的時候發(fā)現(xiàn)問題了,然后再來看,這時理解會更深入點,收藏起來作個備忘吧.
再來一次前后照應,連JS都有對象,你為什么沒有?!?。。ㄕf好的不要打臉……)