內建物件與原生物件
內建(Build-in
)物件與原生(Naitve
)物件的區別在於:前者總是在引擎初始化階段就被建立好的物件,是後者的一個子集;而後者包括了一些在執行過程中動態建立的物件。
原生物件(New後的物件)
ECMA-262
把原生物件(native object
)定義為“獨立於宿主環境的 ECMAScript
實現提供的物件”。包括如下:
1 |
Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError、ActiveXObject(伺服器方面)、Enumerator(集合遍歷類)、RegExp(正規表示式) |
由此可以看出,簡單來說,原生物件就是 ECMA-262
定義的類(引用型別)。
內建物件(不需要New)
定義:由ECMAScript實現提供的物件,獨立於宿主環境,在一個指令碼程式執行的開始處。
注:每個內建物件(built-in object
)都是原生物件(Native Object
),一個內建的建構函式是一個內建的物件,也是一個建構函式。
舉個例子:
1 2 3 |
Native objects: Object (constructor), Date, Math, parseInt, eval。 string 方法比如 indexOf 和 replace, array 方法, ... Host objects (假定是瀏覽器環境): window, document, location, history, XMLHttpRequest, setTimeout, getElementsByTagName, querySelectorAll, ... |
ECMA-262][2 只定義了兩個新的內建物件,即 Global
和 Math
(它們也是原生物件,根據定義,每個內建物件都是原生物件)。
以下是ECMA-262定義的內建物件(built-in):
1 |
global、Object、Function、Array、String、Boolean、Number、Math、Date、RegExp、JSON、Error物件(Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError 和URIError) |
我們也可以修改內建物件的原型
1 2 3 4 5 6 7 8 9 10 11 |
if (!Array.prototype.forEach) { Array.prototype.forEach = function(fn){ for ( var i = 0; i < this.length; i++ ) { fn( this[i], i, this ); } }; } ["a", "b", "c"].forEach(function(value, index, array){ assert( value, "Is in position " + index + " out of " + (array.length - 1) ); }); |
以上程式碼將輸出:
1 2 3 |
PASS Is in position 0 out of 2 PASS Is in position 1 out of 2 PASS Is in position 2 out of 2 |
注意:擴充套件原型是很危險的:
1 2 3 4 5 6 7 8 9 10 11 12 |
Object.prototype.keys = function(){ var keys = []; for ( var i in this ) keys.push( i ); return keys; }; var obj = { a: 1, b: 2, c: 3 }; assert( obj.keys().length == 3, "We should only have 3 properties." ); delete Object.prototype.keys; |
輸出: FAIL We should only have 3 properties.
如果不是有特殊需要而去擴充套件原生物件和原型(prototype
)的做法是不好的
1 2 3 4 |
//不要這樣做 Array.prototype.map = function() { // code }; |
除非這樣做是值得的,例如,向一些舊的瀏覽器中新增一些ECMAScript5
中的方法。
在這種情況下,我們一般這樣做:
1 2 3 4 5 6 7 |
<script type="text/javascript"> if (!Array.prototype.map) { Array.prototype.map = function() { //code }; } </script> |
用原型擴充套件物件
對js原生物件的擴充套件無非就是往prototype
裡註冊,例如,我們可以往String
物件裡擴充套件ltrim,rtrim
等方法。js每個物件都繼承自Object
,並且,物件和其他屬性都通過prototype
物件來繼承。通過prototype
物件,我們可以擴充套件任何物件,包括內建的物件,如String
和Date
:
String物件的擴充套件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<script type="text/javascript"> if(typeof String.prototype.ltrim=='undefined'){ String.prototype.ltrim = function(){ var s = this; s = s.replace(/^\s*/g, ''); return s; } } if(typeof String.prototype.rtrim=='undefined'){ String.prototype.rtrim = function(){ var s = this; s = s.replace(/\s*$/g, ''); return s; } } if(typeof String.prototype.trim=='undefined'){ String.prototype.trim = function(){ return this.ltrim().rtrim(); } } if(typeof String.prototype.htmlEncode=='undefined'){ String.prototype.htmlEncode = function(encodeNewLine){//encodeNewLine:是否encode換行符 var s = this; s = s.replace(/&/g, '&'); s = s.replace(/</g, '<'); s = s.replace(/>/g, '>'); s = s.replace(/'/g, '"'); if(encodeNewLine){ s = s.replace(/\r\n/g, '<br />'); s = s.replace(/\r/g, '<br />'); s = s.replace(/\n/g, '<br />'); } return s; } } </script> |
Date物件的擴充套件
getDaysInMonth
:獲取某月有多少天
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
Date.getDaysInMonth = function (year, month) { var days = 0; switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: days = 31 break; case 4: case 6: case 9: case 11: days = 30; break; case 2: if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) days = 29; else days = 28; break; } return days; } if (typeof Date.prototype.format == 'undefined') { Date.prototype.format = function (mask) { var d = this; var zeroize = function (value, length) { if (!length) length = 2; value = String(value); for (var i = 0, zeros = ''; i < (length - value.length); i++) { zeros += '0'; } return zeros + value; }; return mask.replace(/"[^"]*"|'[^']*'|\b(?:d{1,4}|m{1,4}|yy(?:yy)?|([hHMstT])\1?|[lLZ])\b/g, function ($0) { switch ($0) { case 'd': return d.getDate(); case 'dd': return zeroize(d.getDate()); case 'ddd': return ['Sun', 'Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat'][d.getDay()]; case 'dddd': return ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][d.getDay()]; case 'M': return d.getMonth() + 1; case 'MM': return zeroize(d.getMonth() + 1); case 'MMM': return ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][d.getMonth()]; case 'MMMM': return ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][d.getMonth()]; case 'yy': return String(d.getFullYear()).substr(2); case 'yyyy': return d.getFullYear(); case 'h': return d.getHours() % 12 || 12; case 'hh': return zeroize(d.getHours() % 12 || 12); case 'H': return d.getHours(); case 'HH': return zeroize(d.getHours()); case 'm': return d.getMinutes(); case 'mm': return zeroize(d.getMinutes()); case 's': return d.getSeconds(); case 'ss': return zeroize(d.getSeconds()); case 'l': return zeroize(d.getMilliseconds(), 3); case 'L': var m = d.getMilliseconds(); if (m > 99) m = Math.round(m / 10); return zeroize(m); case 'tt': return d.getHours() < 12 ? 'am' : 'pm'; case 'TT': return d.getHours() < 12 ? 'AM' : 'PM'; case 'Z': return d.toUTCString().match(/[A-Z]+$/); // Return quoted strings with the surrounding quotes removed default: return $0.substr(1, $0.length - 2); } }); }; } |
使用原生js實現複製物件及擴充套件
jQuery
的extend()
方法能很方便的實現擴充套件物件方法,這裡要實現的是:使用原生js
實現複製物件,擴充套件物件,類似jQuery
中的extend()
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
var obj1 = { name : 'trigkit4', age : 22 }; var obj2 = { name : 'frank', age : 21, speak : function(){ alert("hi, I'm + name "); } }; var obj3 ={ age : 20 }; function cloneObj(oldObj) { //複製物件方法 if (typeof(oldObj) != 'object') return oldObj; if (oldObj == null) return oldObj; var newObj = Object(); for (var i in oldObj) newObj[i] = cloneObj(oldObj[i]); return newObj; } function extendObj() { //擴充套件物件 var args = arguments;//將傳遞過來的引數陣列賦值給args變數 if (args.length < 2) return; var temp = cloneObj(args[0]); //呼叫複製物件方法 for (var n = 1; n < args.length; n++) { for (var i in args[n]) { temp[i] = args[n][i]; } } return temp; } var obj =extendObj(obj1,obj2,obj3); console.log(obj);//{ name: 'frank', age: 20, speak: [Function] } console.log(obj1);//{ name: 'trigkit4', age: 22 } console.log(obj2);//{ name: 'frank', age: 21, speak: [Function] } console.log(obj3);//{ age: 20 } |
es5-safe 模組
es5-safe
模組裡,僅擴充套件了可以較好實現的可以安全使用的部分方法,包括:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Function.prototype.bind Object.create Object.keys Array.isArray Array.prototype.forEach Array.prototype.map Array.prototype.filter Array.prototype.every Array.prototype.some Array.prototype.reduce Array.prototype.reduceRight Array.prototype.indexOf Array.prototype.lastIndexOf String.prototype.trim Date.now |
物件的建立
JavaScript
支援四種型別的物件:內部物件、生成的物件、宿主給出的物件(如 Internet 瀏覽器中的 window
和 document
)以及ActiveX
物件(外部元件)。
Microsoft Jscript
提供了 11 個內部(或“內建”)物件。它們是Array、Boolean、Date、Function、Global、Math、Number、Object、RegExp、Error
以及 String
物件。每一個物件有相關的方法和屬性,
JavaScript
中物件的建立有以下幾種方式:
1 2 3 |
(1)使用內建物件 (2)使用JSON符號 (3)自定義物件構造 |
一、使用內建物件
1 2 3 4 |
JavaScript可用的內建物件可分為兩種: 1,JavaScript語言原生物件(語言級物件),如String、Object、Function等; 2,JavaScript執行期的宿主物件(環境宿主級物件),如window、document、body等。 |
內建物件列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
Array Boolean Date Error EvalError Function Infinity JSON Map Math NaN Number Object ParallelArray Promise Proxy RegExp Set String Symbol SyntaxError Uint32Array WeakSet decodeURI decodeURIComponent() encodeURI() encodeURIComponent() escape()已廢棄 eval() isFinite() isNaN() null parseFloat parseInt undefined |
自定義物件構造
建立高階物件構造有兩種方式:使用“this
”關鍵字構造、使用原型prototype
構造
Date物件
get系列方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
getDate() 從 Date 物件返回一個月中的某一天 (1 ~ 31)。 getDay() 從 Date 物件返回一週中的某一天 (0 ~ 6)。 getMonth() 從 Date 物件返回月份 (0 ~ 11)。 getFullYear() 從 Date 物件以四位數字返回年份。注意不要使用getYear()。 getHours() 返回 Date 物件的小時 (0 ~ 23)。 getMinutes() 返回 Date 物件的分鐘 (0 ~ 59)。 getSeconds() 返回 Date 物件的秒數 (0 ~ 59)。 getMilliseconds() 返回 Date 物件的毫秒(0 ~ 999)。 getTime() 返回 1970 年 1 月 1 日至今的毫秒數。 getTimezoneOffset() 返回本地時間與格林威治標準時間 (GMT) 的分鐘差。 getUTCDate() 根據世界時從 Date 物件返回月中的一天 (1 ~ 31)。 getUTCDay() 根據世界時從 Date 物件返回週中的一天 (0 ~ 6)。 getUTCMonth() 根據世界時從 Date 物件返回月份 (0 ~ 11)。 getUTCFullYear() 根據世界時從 Date 物件返回四位數的年份。 getUTCHours() 根據世界時返回 Date 物件的小時 (0 ~ 23)。 getUTCMinutes() 根據世界時返回 Date 物件的分鐘 (0 ~ 59)。 getUTCSeconds() 根據世界時返回 Date 物件的秒鐘 (0 ~ 59)。 getUTCMilliseconds() 根據世界時返回 Date 物件的毫秒(0 ~ 999)。 |
set系列方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
setDate() 設定 Date 物件中月的某一天 (1 ~ 31)。 setMonth() 設定 Date 物件中月份 (0 ~ 11)。 setFullYear() 設定 Date 物件中的年份(四位數字)。注意不要使用setYear()方法。 setHours() 設定 Date 物件中的小時 (0 ~ 23)。 setMinutes() 設定 Date 物件中的分鐘 (0 ~ 59)。 setSeconds() 設定 Date 物件中的秒鐘 (0 ~ 59)。 setMilliseconds() 設定 Date 物件中的毫秒 (0 ~ 999)。 setTime() 以毫秒設定 Date 物件。 setUTCDate() 根據世界時設定 Date 物件中月份的一天 (1 ~ 31)。 setUTCMonth() 根據世界時設定 Date 物件中的月份 (0 ~ 11)。 setUTCFullYear() 根據世界時設定 Date 物件中的年份(四位數字)。 setUTCHours() 根據世界時設定 Date 物件中的小時 (0 ~ 23)。 setUTCMinutes() 根據世界時設定 Date 物件中的分鐘 (0 ~ 59)。 setUTCSeconds() 根據世界時設定 Date 物件中的秒鐘 (0 ~ 59)。 setUTCMilliseconds() 根據世界時設定 Date 物件中的毫秒 (0 ~ 999)。 |
toString系列方法
1 2 3 4 5 6 7 |
toString() 把 Date 物件轉換為字串,toString()總是返回一個用美式英語表達的字串。 toTimeString() 把 Date 物件的時間部分轉換為字串。 toDateString() 把 Date 物件的日期部分轉換為字串。 toUTCString() 根據世界時,把 Date 物件轉換為字串。 toLocaleString() 根據本地時間格式,把 Date 物件轉換為字串。 toLocaleTimeString() 根據本地時間格式,把 Date 物件的時間部分轉換為字串。 toLocaleDateString() 根據本地時間格式,把 Date 物件的日期部分轉換為字串。 |
Array物件
屬性
1 2 3 4 5 6 7 8 9 10 11 12 13 |
constructor 指定建立物件原型的函式。 index 如果陣列是通過正規表示式匹配建立的,比配是字串的下標索引為0. input 如果陣列是通過正規表示式匹配建立的,返回原始的字串。 length長度 返回陣列中元素個數. prototype 允許為所有物件附加屬性. |
方法
這些方法可以改變陣列自身:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
pop 移除陣列的最後一個元素,返回值是被刪除的元素。 push 在陣列的末尾新增一個或者多個元素,返回值是新的陣列的長度。 reverse 顛倒陣列中元素的順序,原先第一個元素現在變成最後一個,同樣原先的最後一個元素變成了現在的第一個,也就是陣列的索引發生了變化。 shift 刪除陣列的第一個元素,返回值是刪除的元素。 sort 對陣列中的元素進行排序。 splice 新增或刪除陣列中的一個或多個元素。 unshift 新增一個或者多個元素在陣列的開頭,返回值是新的陣列的長度。 |
Accessor 方法
這些過程不改變陣列自身
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
concat 返回一個包含此陣列和其他陣列和/或值的結合的新陣列 indexOf 返回第一個與給定引數相等的陣列元素的索引,沒有找到則返回-1。 join 將所有的陣列元素連線成一個字串。 lastIndexOf 返回在陣列中搜尋到的與給定引數相等的元素的最後(最大)索引。 slice 返回陣列中的一段。 toSource Returns an array literal representing the specified array; you can use this value to create a new array. Overrides the Object.toSource method. toString 返回代表該陣列及其元素的字元,重寫Object.toString 過程. valueOf Returns the primitive value of the array. Overrides the Object.valueOf method. |
迴圈(迭代)過程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
filter 對陣列中的每一個元素呼叫引數中指定的過濾函式,並將對於過濾函式返回值為true的那些陣列元素集合為新的陣列返回。 forEach 對陣列的每一個元素依次呼叫引數中指定的函式。 every 如果陣列中每一個元素都滿足引數中提供的測試函式,則返回真。 map Creates a new array with the results of calling a provided function on every element in this array. some 如果陣列中至少有一個元素滿足引數函式的測試,則返回true。 |
總結:
1 2 3 |
改變原陣列的方法:pop()、push()、reverse()、shift()、sort()、splice()、unshift() 不改變原陣列的方法:concat()、join()、slice()、toString() |
Boolean
屬性
1 2 3 4 |
Boolean.length 長度屬性,值為1. Boolean.prototype 代表Boolean構造器的原型. |
方法
1 2 3 |
Boolean.prototype.toSource() Boolean.prototype.toString() Boolean.prototype.valueOf() |
String 物件
屬性
1 2 |
String.length String.prototype |
方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
charAt() 方法可返回指定位置的字元。stringObject.charAt(index) charCodeAt() 方法可返回指定位置的字元的 Unicode 編碼。這個返回值是 0 – 65535 之間的整數。 stringObject.charCodeAt(index) concat() 方法用於連線兩個或多個字串。 stringObject.concat(stringX, stringX, …, stringX) indexOf() 方法可返回某個指定的字串值在字串中首次出現的位置。 stringObject.indexOf(searchvalue, fromindex) lastIndexOf() 方法可返回一個指定的字串值最後出現的位置,在一個字串中的指定位置從後向前搜尋。 localeCompare():用本地特定的順序來比較兩個字串stringObject.localeCompare(target) match() 方法可在字串內檢索指定的值,或找到一個或多個正規表示式的匹配。 該方法類似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字串的位置。 stringObject.match(regexp) replace() 方法用於在字串中用一些字元替換另一些字元,或替換一個與正規表示式匹配的子串。stringObject.replace(regexp/substr, replacement) search() 方法用於檢索字串中指定的子字串,或檢索與正規表示式相匹配的子字串。 stringObject.search(regexp) slice() 方法可提取字串的某個部分,並以新的字串返回被提取的部分。 stringObject.slice(start, end) substring()不推薦使用,建議使用slice()替代。 substr()不推薦使用,建議使用slice()替代。 toLocaleLowerCase()不推薦使用,只在土耳其語等少數語種中有用,建議使用toLowerCase()替代。 toLocaleUpperCase()不推薦使用,只在土耳其語等少數語種中有用,建議使用toUpperCase()替代。 toLowerCase() 方法用於把字串轉換為小寫。 toUpperCase() 方法用於把字串轉換為大寫。 |
注意:String
物件的方法 slice()、substring()
和 substr()
都可返回字串的指定部分。強烈建議在所有場合都使用 slice()
方法。
RegExp物件
屬性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
RegExp.prototype.constructor 建立該正則物件的建構函式。 RegExp.prototype.global 是否開啟全域性匹配,也就是匹配目標字串中所有可能的匹配項,而不是隻進行第一次匹配。 RegExp.prototype.ignoreCase 在匹配字串時是否要忽略字元的大小寫。 RegExp.prototype.lastIndex 下次匹配開始的字串索引位置。 RegExp.prototype.multiline 是否開啟多行模式匹配(影響 ^ 和 $ 的行為) RegExp.prototype.source 正則物件的源模式文字。 |
方法
1 2 3 4 5 6 7 |
RegExp.prototype.exec() 在目標字串中執行一次正則匹配操作。 RegExp.prototype.test() 測試當前正則是否能匹配目標字串。 RegExp.prototype.toString() 返回一個字串,其值為該正則物件的字面量形式。覆蓋了Object.prototype.toString() 方法。 |
Object物件
當以非建構函式形式被呼叫時,Object
等同於 new Object()
。
屬性或方法
Object
的每個例項都具有共同的基本屬性和方法
屬性或者方法 | 說明 |
---|---|
constructor | 指向建立當前物件的建構函式 |
hasOwnProperty(name) | 檢測給定屬性name在例項物件(不是原型物件)中是否存在。name以字串形式指定 |
isPropertyOf(object) | 檢測傳入的物件object是否該方法呼叫者的原型物件。一般格式:Class.prototype.isPropertyOf(object) |
propertyIsEnumerable(pr) | 檢測屬性pr能否用for-in迴圈列舉。屬性pro用字串形式指定 |
toLocaleString() | 返回物件的字串表示。與地區和環境對應 |
toString() | 返回物件的字串表示 |
valueOf() | 返回物件的字串、數值或布林值表示 |
靜態方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
Object.create(prototype, descriptors) 以指定的原型建立物件,並且可以(可選)的設定物件的屬性 Object.defineProperty(object, propertyname, descriptor) 對指定的物件的一個屬性設定豐富的值控制 Object.defineProperties(object, descriptors) 對指定的物件的一組屬性提供豐富的值控制 Object.getOwnPropertyDescriptor(object, propertyname) 返回屬性的定義 Object.getOwnPropertyNames(object) 返回所有屬性的名稱,哪怕說是不能列舉的屬性 Object.preventExtensions(object) 防止新的屬性新增到物件 Object.isExtensible(object) 是否可新增屬性到物件 Object.seal(object) 阻止向指定物件新增新屬性或刪除現有屬性 Object.freeze(object) 防止現有屬性和屬性值的修改,並防止新特性的新增。 Object.isFrozen(object) 檢查當前物件是否已凍結 Object.getPrototypeOf(object) 返回指定物件的原型 |