現在做項目基本是套用框架,不論是網上的前端還是后端框架,也會尋找一些封裝好的插件拿來即用,但還是希望拿來時最好自己過后再回過頭了解里面的原理,學習里面優秀的東西,不論代碼封裝性,還是小到命名。
好吧,扯遠了,在這里要講的是大家前端用得多的JS,可能接觸最多的是Jquery,但原生的JS最好還是要了解的,至少能看懂別人的代碼,然后學習。
平時用得多的無非是if for 邏輯處理字符串,截斷字符串,數組,然后是查找元素,對元素背景什么的屬性操作,這些都是些實用性上的東西,這里講一些更深入點的,如何理解Javascript對象。
C#,Java都是面象對象的語言,但JavaScript本身不是面向對象的語言,而是基於對象的語言。 JavaScript中所有事物都是對象, 包括字符串、數組、日期、數字,甚至是函數(驗證方法是你可以在實例上 . 出屬性)。
基於這點我們可以封裝自己的插件,這里就不講怎么制作插件了,想了解的可查詢我的如何制作插件的文章。
創建對象,平時用到的方法:
var emptyObject1 = {}; //創建空對象
var emptyObject2 = new Object(); //創建空對象
var person = {"name":"sdcyst",
"age":18, "sex":"male"}; //創建一個包含初始值的對象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) { //循環name對象中的屬性名字 namestring += name[props]; } alert(namestring); //NAME1NAME2NAME3NAME4 delete name.name1; //刪除name1屬性 delete name["name3"]; //刪除name3屬性 namestring = ""; for(var props in name) { //循環name對象中的屬性名字 namestring += name[props]; } alert(namestring); //NAME2NAME4 alert("name1" in name); //false alert("name4" in name); //true
接下來講講比較常見的數組,對象是無序數據的集合,而數組則是有序數據的集合,數組中的數據(元素)通過索引(從0開始)來訪問,數組中的數據可以是任何的數據類型,數組本身仍舊是對象,創建數組可以用"[]"操作符,或者是用Array()構造函數來new一個。
var array1 = []; //創建空數組 var array2 = new Array(); //創建空數組 array1 = [1,"s",[3,4],{"name1":"NAME1"}]; // alert(array1[2][1]); //4 訪問數組中的數組元素 alert(array1[3].name1); //NAME1 訪問數組中的對象 alert(array1[8]); //undefined array2 = [,,]; //沒有數值填入只有逗號,則對應索引處的元素為undefined alert(array2.length); //3 alert(array2[1]); //undefined
需要注意的是var
array =
new
Array(10);初始化的長度10實際上
對數組沒有任何的約束力,數組的長度是可以任意改變的。
delete操作符刪除數組的元素,注意這個刪除僅僅是將數組在該位置的元素設為undefined,數組的長度並沒有改變。
var array = new Array("n1","n2","n3","n4","n5"); //五個元素的數組 var astring = ""; for(var i=0; i<array.length; i++) { //循環數組元素 astring += array[i]; } alert(astring); //n1n2n3n4n5 delete array[3]; //刪除數組元素的值 alert(array.length + "_" + array[3]) //5_undefined array.length = 3; //縮減數組的長度 alert(array[3]); //undefined array.length = 8; //擴充數組的長度 alert(array[4]); //undefined
對象中也離不開函數,那如何創建函數:
function f(x) {........}
var f = function(x) {......}
上面這兩種形式都可以創建名為f()的函數,不過后一種形式可以創建匿名函數。
方法的調用需要對象的支持,那么在方法中如何獲取對象的屬性呢?this!this關鍵字我們已經很熟悉了,在javascript的方法中,我們可以用this來取得對方法調用者(對象)的引用,從而獲取方法調用者的各種屬性。
var obj = {"name":"NAME","sex":"female"}; obj.print = function() { //為對象添加方法 alert(this.name + "_" + this["sex"]); }; obj.print(); //NAME_female obj.sex = "male"; obj.print(); //NAME_male
來一個更加面向對象的例子。
var person = {name:"defaultname", setName:function(s){ this.name = s; }, "printName":function(){ alert(this.name); }} person.printName(); //defaultname person.setName("newName"); person.printName(); //newName
下面更深入點,每一個函數都包含了一個原型(prototype),我們可以簡單的把prototype看做是一個模版,新創建的自定義對象都是這個模版(prototype)的一個拷貝。
通過prototype創建自定義對象的一個例子:
// 構造函數 function Person(name, sex) { this.name = name; this.sex = sex; } // 定義Person的原型,原型中的屬性可以被自定義對象引用 Person.prototype = { getName: function() { return this.name; }, getSex: function() { return this.sex; } }
創建自定義對象(實例化類)
var zhang = new Person("ZhangSan", "man"); console.log(zhang.getName()); // "ZhangSan"
當代碼var zhang = new Person("ZhangSan", "man")執行時,其實內部做了如下幾件事情:
-
- 創建一個空白對象(new Object())。
- 拷貝Person.prototype中的屬性(鍵值對)到這個空對象中(我們前面提到,內部實現時不是拷貝而是一個隱藏的鏈接)。
- 將這個對象通過this關鍵字傳遞到構造函數中並執行構造函數。
- 將這個對象賦值給變量zhang。
上面我們提到了用new來創建一個對象的過程,事實上在這個過程中,當創建了空對象后,new會接着操作剛生成的這個對象的prototype屬性。
每個方法都有一個prototype屬性(因為方法本身也是對象),new操作符生成的新對象的prototype屬性值和構造方法的prototype屬性值是一致的。構造方
法的prototype屬性指向了一個prototype對象,這個prototype對象初始只有一個屬性constructor,而這個constructor屬性又指向了prototype屬性所在的方
法。有點暈,看下面的圖:
這樣,當用構造函數創建一個新的對象時,它會獲取構造函數的prototype屬性所指向的prototype對象的所有屬性。對構造函數對應的prototype對象所做的任何操作都會反應到它所生成的對象身上,所有的這些對象共享構造函數對應的prototype對象的屬性(包括方法)。
看個具體的例子吧:
function Person(name,sex) { //構造函數 this.name = name; this.sex = sex; } Person.prototype.age = 12; //為prototype屬性對應的prototype對象的屬性賦值 Person.prototype.print = function() { //添加方法 alert(this.name+"_"+this.sex+"_"+this.age); }; var p1 = new Person("name1","male"); var p2 = new Person("name2","male"); p1.print(); //name1_male_12 p2.print(); //name2_male_12 Person.prototype.age = 18; //改變prototype對象的屬性值,注意是操作構造函數的prototype屬性 p1.print(); //name1_male_18 p2.print(); //name2_male_18
在javascript中,所有的方法都有一個call方法和apply方法。這兩個方法可以模擬對象調用方法,它的第一個參數是對象,后面的參數表示對象調用這個方法時的參數。概念比較拗口,平時很少遇到,所以用得少,比較難得理解這里就不作過多的講解了,請自行查找說得更明了的文章來了解吧。
以上示例部分整理於園友文章,用得比較明了所以拿來講解,以上知識點可能只有在大家實際項目中運用的時候發現問題了,然后再來看,這時理解會更深入點,收藏起來作個備忘吧,有些源碼等知識可進入園友公眾號【一個碼農的日常】自行查看。
再來一次前后照應,連JS都有對象,你為什么沒有?!!!(說好的不要打臉……)