Js基礎知識1-對象、對象屬性全解
Object對象
Object對象包含如下屬性和方法,也就意味著一切對象(函數也是對象)都包含如下方法。
每種方法和屬性在不同的對象中有不同的作用,並不是每種對象都有使用每個方法的必要。
下面是Object對象的派生對象在使用這些方法和屬性時的意義。Object對象只是定義了他們,並沒有使用他們。 __proto__
屬性是保存當前對象的原型對象。對象通過這個屬性產生了原型鏈,可以參考http://blog.csdn.net/luanpeng825485697/article/details/78547421。
constructor屬性
constructor屬性是保存當前對象的構造函數,js通過構造函數來實現對象的實例化。
下面的例子中,constructor保存的就是Object構造函數。
var obj1 = new Object(); obj1.id = "obj1"; var obj2 = { "id": "obj2" }; console.log(obj1.constructor);//function Object(){} console.log(obj2.constructor);//function Object(){}
hasOwnProperty(propertyName)方法
hasOwnProperty方法接收一個字符串參數,該參數表示屬性名稱,用來判斷該屬性是否在當前對象實例中,而不是在對象的原型鏈中。我們來看看下面這個例子:
var arr = []; //實例化了一個Array對象 console.log(arr.hasOwnProperty("length"));//true console.log(arr.hasOwnProperty("hasOwnProperty"));//false
在這個例子中,首先通過定義了一個數組對象的實例arr,我們知道數組對象實際是通過原型鏈繼承了Object對象,然後擁有自己的一些屬性,我們通過hasOwnProperty方法判斷length是arr自己的屬性,而hasOwnProperty是在原型鏈上的屬性。
isPrototypeOf(Object)方法
isPrototype方法接收一個對象,用來判斷當前對象是否在傳入的參數對象的原型鏈上,說起來有點抽象,我們來看看代碼。
*
*
*
Array數組
參考http://blog.csdn.net/luanpeng825485697/article/details/77009182
JS函數對象
任何函數function都派生於Funciton對象,而Function對象派生於Object對象。函數的詳解可以參考:http://blog.csdn.net/luanpeng825485697/article/details/77010261
可以使用關鍵字function創建函數對象;無需指定返回值類型;參數列表聲明不需var關鍵字;無函數重載;函數內部可以直接調用arguments數組(隱式定義),該數組存儲了實參列表;函數名代表一種引用類型,可用(函數名 instanceof Function)測試;打印函數引用會輸出整個函數定義。
3.1動態函數和匿名函數
1)動態函數: 動態函數是通過js的內置對象Function定義。形式為:new Function(arg1 , arg2),由於arg1和arg2為變量,所以可以動態指定。如:
var run = new Function(“x,y”,”return x+y;”);
2)匿名函數:沒有函數名,形如:var run = function(x,y){return x+y;};
註:打印動態函數的引用可以發現動態函數也是匿名函數。
3.2 全局函數
String(object) 將一個對象值轉換為一個字符串
Number(object) 將一個對象的值轉換為一個數字
Eg:sum+=Number(cell.innerText);
eval(str)接收一個字符串形式的表達式,並試圖求出表達式的值。作為參數的表達式可以采用任何合法的操作符和常數。如果參數中包含JS命令,這些命令也可以被執行,就像這些命令是JS程序的一部分一樣。
函數可計算某個字符串,並執行其中的的 JavaScript 代碼。eval(“2+3”) // 返回 5
decodeURI(URIstring) 為加密的URI進行解碼
decodeURIComponent(URIstring) 為加密的URI組件解碼
encodeURI(URIstring) 將字符串加密為URI
encodeURIComponent(URIstring) 將字符串加密為URI組件
parseInt(str) 將一個字符串解析為一個整數,不是四舍五入操作,而是切尾
試圖從一個字符串中提取一個整數。可附加一個n整數實現返回n進制整數。如果在字符串中存在除了數字、符號、小數點和指數符號以外的字符,就停止轉換,返回已有的結果。如果第一個字符就不能轉換,函數就返回NaN值。
parseFloat(str)試圖從一個字符串中提取一個浮點值。如果在字符串中存在除了數字、符號、小數點和指數符號以外的字符,就停止轉換並返回已有的結果。如果第一個字符就不能轉換,函數就返回NaN值。
isNaN()用於判斷是否為NaN值類型,如果是函數返回true。
isFinite(number)可以判斷參數number是否是一個無窮。如果是則函數返回false,否則返回true。
escape(string)對一個字符串進行解碼
接受一個字符串,這個字符串中可能含有空格、分號等字符。函數把字符串轉換成Cookie的內部表示方式。函數返回值就是這種內部的表達方式。
函數可對字符串進行編碼,這樣就可以在所有的計算機上讀取該字符串
unescape(string)接受一個Cookie,把其內部表達方式轉化成普通的字符串形式。 JS函數一共可分為常規函數、數組函數、日期函數、數學函數、字符串函數等五類。
1 var student1 = new Object(); //定義對象引用,或者var student1 = {},new Object()。所有的包裝類都派生於Object。Object基類包含hasOwnProperty、isPrototypeOf、propertyIsEnumerable、toLocaleString、toString、valueOf方法 2 student1.name = "student1"; //直接設置同時添加對象屬性 3 student1["age"]=12; //直接設置同時添加對象屬性 4 student1.getname = function(){ //設置添加對象方法。函數表達式,只有在執行到本行才解析 5 return this.name; //this表示作用對象,這裏為student1 6 }; 7 //var {name:personname, age:personage} = student1; //解構賦值,對應項使用副本賦值,如[value1,value2]=[value2,value1];可實現兩個基本數據交換 8 printf(JSON.stringify(student1)); //JSON.stringify把對象轉化為JSON字符串表示 9 10 student1 = { 11 name:"student1", 12 _age:12, //前面有下滑線是一種常用的標記,用於表示只能通過對象方法訪問的屬性,只是對開發者的一種標記習慣,並不是真的私有變量 13 getname:function(){ 14 return this.name; 15 } 16 }; 17 Object.defineProperty(student1,"name1",{ //可以用於定義新數據屬性,也可以修改原有數據屬性。也可以不使用defineProperty可以直接定義數據屬性。也可以使用defineProperties同時定義多個數據或訪問器屬性 18 writable:true, //對象屬性的數據屬性,是否可修改 19 enumerable:true, //對象屬性的數據屬性,通過for-in遍歷到 20 configurable:true, //對象屬性的數據屬性,能否通過delete刪除屬性,configurable屬性在定義為false以後,就不能再被設置 21 value:"sst" //對象屬性的值屬性,默認為underfined 22 }); 23 Object.defineProperty(student1,"age",{ //訪問器屬性,不能直接定義,必須通過defineProperty定義,不包含數據值,設置時調用set函數,讀取時調用get函數。訪問器屬性名稱不要和數據屬性名稱相同 24 get:function(){return this._age}, 25 set:function(newvalue){this._age=newvalue;this.name="xxt";} 26 }); 27 student1.age=22; //age不是數據屬性,而是訪問屬性。這裏是調用了set函數, 28 Object.preventExtensions(student1);//設置對象不可被擴展,以後再添加屬性都是underfined,防止被篡改 29 Object.seal(student1); //密封對象,對象不能添加刪除屬性。 30 Object.freeze(student1); //凍結對象,屬性不可修改。只能通過set訪問器修改 31 printf(JSON.stringify(student1)); //將JSON格式轉化為字符串。JSON格式即KEY-VALUE格式 32 for(var myproperty in student1){ //for in遍歷對象屬性 33 console.log(myproperty,":",student1[myproperty]); 34 } 35 36 37 38 39 function Student(name,age){ //自定義函數,構造函數,等同於java中的自定義類。所有的類型派生於Object 40 var sex="男"; //函數內部為私有屬性 41 this.name=name; //通過this創建的是可以被實例對象訪問的 42 this.age=age; 43 this.getName=function(){ 44 return this.name; //函數內部this表示此函數引用的擁有者,不是傳入參數。當作為全局函數時,this表示window 45 }; 46 this.setName= function(name){ //函數不關心傳入或者定義的參數數量和類型,因此所有函數沒有重載 47 if(typeof name=="string") //基本數據類型,做類型檢驗,避免參數傳遞錯誤 48 this.name = name; //沒有指定返回值,實際返回的是undefined 49 }; 50 this.getAge =function (){ 51 if(this.age.toFixed(2)<<2) //轉化為false的值:"",0,NaN,null,underfined。其他轉化為true,類型首字母大寫,變量首字母小寫,<<按位移動,<<<無符號按位移動,toFixed(2)表示保留2位小數 52 return -~this.age; //~按位取非,&按位取與,|按位取或 ^按位取異或,一元減號,表示取負 53 return this.age; //保證所有路徑都有返回值,雖然不加也不會出錯,因為有默認返回值undefined 54 }; 55 this.setAge= function(age){ //函數參數總是按值傳遞,無論基本類型還是引用類型,引用類型傳遞引用的值,不傳遞指向對象的值 56 if(age instanceof Number){ //包裝類型,做類型檢驗,避免參數傳遞錯誤 57 this.age = parseInt(age.toString(16),16);//parseInt將字符串化為整數,支持識別多進制和轉化為多進制,toString()轉化為字符串,支持多進制轉化 58 } 59 //typeof判斷基本類型,underfined聲明未定義(underfined類型只有一個值),boolean布爾型,string字符串,number數值,object對象或null(null類也只有一個值),function函數 60 //instanceof判斷包裝類型,基本類型對象的包裝類型為Underfined,Boolean,String,Number,Object, 61 typestr = typeof("getAge"); //省略var的變量為全局變量 62 } 63 } 64 student1=new Student("小明",12); //new是創建了一個新對象,構造函數將屬性和方法綁定到這個新對象上 65 Student("小紅",13); //作為全局函數。通過構造函數將屬性綁定到window上 66 var student2 = new Object(); 67 Student.call(student2,"小剛",14); //call和apply通過構造函數,將屬性綁定到以存在對象student2上 68 if(student2 instanceof Student) //instanceof判斷變量是否是某個類型或其派生類型實例的,student1是Student類,同時也是Object 69 printf(student2.name); 70 71 72 //js的繼承有多重方式。每種方式的內存操作都是不同。下面展示其中一種。 73 // js的類型繼承原理和java、c#相同。派生類繼承基類時,會實例化(淺復制)一個基類對象和保留引用在派生類空間。派生類內的實例的基類和派生類自定義的函數分別操控各自的屬性。在函數和屬性操作中時,會自動先派生後基類的順序查找,不用手動查找 74 //關於實例化:只復制且全部復制在構造函數中開辟了內存的變量,包括引用變量。派生類實例化時基類對象進行淺復制。 75 function Monitor(){ //自定義函數,相當於自定義一個類,類名Monitor。在文件中多稱為構造函數,相當於c++和java中的自定義類。每個函數類,都有基類Object 76 this.task=["學習"]; 77 } 78 Monitor.prototype.data = "原型數據"; //prototype獲取派生類的基類對象引用,通過基類對象引用直接為基類添加屬性。系統會為派生類提供默認原型,也可以通過繼承自定義原型 79 person1 = new Monitor(); //通過函數類實例化對象 80 person2 = new Monitor(); //實例化對象 81 Object.getPrototypeOf(person1).data="原型數據1"; //通過實例修改原型。Object.getPrototypeOf()獲取對象原型。實例對象包含對原型的引用,但需要使用getPrototypeOf函數獲取 82 person1.data="派生數據"; //修改派生類屬性,這樣當查找data數據會先自動搜索派生類,再自動搜素基類。 83 84 printf(person1.hasOwnProperty("data")); //是否擁有指定屬性(不算基類屬性)。true因為自定義了該屬性 85 printf(person1.data); //讀取自定義屬性 86 87 var keys = Object.keys(Monitor.prototype); //獲取對象所擁有(不包括繼承的)的可枚舉實例,Monitor是類,Monitor.prototype是基類實例。如果換成person1,則只能獲取派生類的自定義屬性。getOwnPropertyNames可獲取對象擁有的所有屬性 88 printf(keys); 89 delete person1.data; //刪除派生類自定義的屬性 90 printf(person1.hasOwnProperty("data")); //是否擁有指定屬性。false,因為該屬性在派生類中被刪除了,只有基類中存在,雖然可以訪問,但是是繼承過來的,不是自己擁有的 91 printf("data" in person1); //是否包含指定屬性。true包含,只是不擁有 92 printf(person1.data); //基類屬性 93 Monitor.prototype.sex=["男"]; //通過派生類向基類添加數組引用變量 94 person1.sex.push("女"); //在實例對象中保留了基類的引用和淺復制了基類對象。這裏的sex是經過了一次從派生類到基類的向上查詢。 95 printf("基類中的引用:"+person2.sex); //實例對象連帶更新。所以構造函數用於指定專屬屬性,原型用於存放共享屬性 96 person1.task.push("工作"); //修改構造函數中引用指向的對象 97 printf("派生類中的引用:"+person2.task); //實例對象不連帶更新構造函數中的數據。因為實例化時會深復制構造函數中的所有數據,在實例化時為每個對象都創建 98 99 Monitor.prototype=new Student("組長",12); //繼承,派生類Person設置基類為Student。在繼承中會為淺復制一個基類實例放在派生類空間中,同時將引用存儲為prototype,放在派生類Person中
Js基礎知識1-對象、對象屬性全解