我們接着上面一篇繼續~javascript
JavaScript中的Date類型使用自UTC時間,1970年1月1日零時開始的毫秒數來保存日期。
建立一個日期對象:java
var now = new Date() console.log(now) //Fri Sep 22 2017 15:42:29 GMT+0800 (中國標準時間)
在調用Date構造函數而不傳參數的狀況下,新建立的對象自動得到當前日期和時間。數組
若是想根據特定的日期和時間建立日期對象,必須傳入表示日期的毫秒數(即從UTC時間開始截止到當前的毫秒數)。瀏覽器
var d = new Date(2165461213546) console.log(d) //Sun Aug 15 2038 13:00:13 GMT+0800 (中國標準時間)
Date.parse()一般有如下幾種格式的參數: 1."月/年/日", 如:6/12/2017 2."英文月名 日,年",如:January 12,2004 3."英文星期幾 英文月名 日 年 時:分:秒 時區",如Tue May 25 2004 00:00:00 GMT-0700 var some = new Date(Date.parse("May 25, 2004")) console.log(some) //Tue May 25 2004 00:00:00 GMT+0800 (中國標準時間) //其實這樣寫也是能夠的,它在內部會先調用Date.parse()方法 var someDate = new Date("May 25, 2004");
Date.UTC()方法一樣也是返回表示日期的毫秒數,它和Date.parse()在構建值時使用不一樣的信息。Date.UTC()接受的參數分別是年份,基於0的月份,月中的哪一天,小時數,分鐘,秒,毫秒。在這些參數中,前兩個參數是必填的。若是沒有提供月中的日期數,則會默認爲1,若是省略其餘數,則都假設爲0.app
var y2k = new Date(Date.UTC(2000, 0)) console.log(y2k) //Sat Jan 01 2000 08:00:00 GMT+0800 (中國標準時間) //其實這樣寫也是能夠的. var d = new Date(2000, 0) var d1 = new Date(2005,4,5,17,55,55) 以上代碼建立的日期對象,只不過此次的日期對象是基於系統設置的be
var start = Date.now() //獲取開始時間 do() //作些啥 var stop = Date.now() //獲取結束時間
若是某些瀏覽器不支持的話,咱們能夠經過如下技巧得到當前時間的毫秒數,就是在前面加一個‘+’:函數
var s = +new Date() console.log(s) //1506069877901
var d = new Date() d.toLocaleString() //"2017/9/22 下午4:49:43" d.toString() //"Fri Sep 22 2017 16:49:43 GMT+0800 (中國標準時間)" d.valueOf() //1506070183078
稍微下他們之間的區別,主要valueOf返回的是時間對象的毫秒數。this
var d = new Date() d.toDateString() //"Fri Sep 22 2017" d.toTimeString() //"17:02:27 GMT+0800 (中國標準時間)" d.toLocaleDateString() //"2017/9/22" d.toLocaleTimeString() //"下午5:02:27" d.toUTCString() //"Fri, 22 Sep 2017 09:02:27 GMT"
以上的這些方法都會根據系統環境而異。prototype
var d = new Date() 1. 獲取日期的毫秒數,和valueOf方法返回的值相同。 d.getTime() //1506071307006 2. 經過毫秒設置日期,會改變當前的日期對象。 d.setTime(1213123) console.log(d) //Thu Jan 01 1970 08:20:13 GMT+0800 (中國標準時間) 3. 獲取4位數的年份 d.getFullYear() // 1970 4. 返回UTC日期的4位數年份 d.getUTCFullYear() //1970 5. 返回日期中的月份,從0開始算起 d.getMonth() // 8 6. 返回UTC日期中的月份,從0開始算起 d.getUTCMonth() //8 7. 返回日期月份中的天數, 若是傳入的值超過了該月應有的天數,則增長月份 d.getDate() // 22 8. 返回UTC日期月份中的天數, 若是傳入的值超過了該月應有的天數,則增長月份 d.getUTCDate() // 22 9. 返回日期中星期的星期幾(0表示星期天,6表示星期6) d.getDay() //6 10. 返回UTC中的日期中的星期幾(0表示星期天,6表示星期6) d.getUTCDay() //1 11.返回日期中的小時數(0~23),傳入的值超過23則增長月份中的天數 d.getHours() // 9 12. 返回UTC日期中的小時數(0~23),傳入的值超過23則增長月份中的天數 d.getUTCHours() 13. 返回日期中的分鐘數(0~59),也能夠進行設置。 d.getMinutes() 14. 返回UTC中日期的分鐘數,也能夠進行設置。 d.getUTCMinutes() 15. 返回日期中的秒數0~59,也能夠進行設置。 d.getSeconds() 16. 返回日期對象中UTC的秒數 d.getUTCSeconds() 17. 返回日期中的毫秒數,也能夠進行設置 d.getMilliseconds()
在JavaScript中,函數其實就是一個對象,每一個函數都是Function類型的實例,並且和其餘引用類型同樣具備屬性和方法。
由於函數是一個對象,因此函數名實際上是一個指向函數對象的指針,不會與某個函數綁定。
定義函數有兩種方法:函數聲明和函數表達式。指針
function fn(){ ... } var fn = function() { ... };
還有一種方法就是經過Function構造函數。Function構造函數能夠接受任意數量的參數,但最後一個參數始終都是被當作函數體。前面的額參數則枚舉新函數的參數。code
var fn = new Function("num1", "num2", "return num1+num2")
從技術的角度來講,這是一個函數表達式。可是最佳實踐中並不推薦使用這種方法,由於這種方法會致使解析兩次代碼。第一次是正常的解析,第二次是解析傳入構造函數中的字符串。
因爲函數名是一個指針,因此函數可能會具備多個函數名:
function fn() {console.log(123)} var fn1 = fn 若是如下操做還能夠繼續訪問: fn = null fn1() // 123
fucntion add (num){ return num + 100 } function add (num) { return num + 200 } console.log(add(100)) // 300
而後改寫下上面的例子:
var add = function(num) { return num + 100 } add = function (num) { return num + 200 } add(100) //300
js引擎在解析的時候會先讀取函數聲明,並使其在執行任何代碼以前能夠訪問。由於在代碼執行以前,解析器就已經經過一個函數聲明提高的過程,讀取並將函數聲明添加到執行環境中。對代碼求值時,JavaScript引擎會在第一遍聲明函數,並將它們放到源代碼樹的頂部。
函數表達式,必須等解析器執行到它所在的代碼行,纔會真正的被解釋執行:
console.log(fn(10, 10)) // error 'fn is not a function' var fn = function(a, b) { return a + b }
以上代碼會報錯,由於在函數位於一個初始化語句中。而不是一個函數聲明。換句話說,在執行到函數所在的語句以前,變量fn是不會保存對函數的引用。並且因爲第一行已經報錯了,代碼也不會繼續向下執行。
function callSomeFn(fn, arg) { return fn(arg) }
如上,這個函數接受兩個參數,第一個參數應該是一個函數,第二個參數是要傳遞給函數的一個值。而後,就能夠以下:
function add(num) { return num+10 } var res = callSomeFn(fn, 10) console.log(res) //20 function greet (name) { return 'hello' + name } var res = callSomeFn(greet, 'world') console.log(res) //'hello world'
並且,咱們能夠在一個函數中返回另一個函數,以下咱們經過函數建立另一個函數而後返回:
function create(proName) { return function (obj1, obj2) { var val1 = obj1[proName] var val2 = obj[proName] if(val1 < val2) { return -1 }else if(val1 > val2) { return 1 }else { return 0 } } }
函數內部屬性
function factor(num) { if(num <= 1) { return 1 }else{ return num * factor(num - 1) } }
如上是一個遞歸函數,經過callee能夠改寫成下面這樣:
function factor(num) { if(num < 1) { return 1 }else{ return num * argument.callee(num - 1) } }
當某個函數在全局做用域中定義的,當在全局做用域中調用改函數時,this引用的是全局對象window.
var a = 12 function b() { console.log(this.a) } b() //12
在理解this的綁定過程以前,咱們瞭解一下調用位置,調用位置表示的是函數所被調用的位置,而不是其聲明的位置。
如何知道函數的調用位置,最重要的是分析函數的調用棧(即爲了到達當前執行位置所調用的全部函數)。那麼調用位置就是當前正在執行函數的前一個調用中。
function baz() { //當前的調用棧是baz //當前的調用位置是全局做用域,即當前調用棧的前一個調用 console.log('baz'); bar(); } function bar() { //當前調用棧是 baz-->bar //當前的調用位置是:baz console.log('bar'); foo(); } function foo() { //當前的調用棧是baz --> bar --> foo //當前調用位置是bar } baz(); //<-- baz的調用位置就是全局做用域
function outer() { inner() } function inner() { console.log(inner.caller) } outer()
funtion setName(name) { console.log(name) } function sun(s1, s2){ //... } console.log(setName.length) // 1 console.log(sun.length) //2
再說下prototype屬性,它是保存全部實例方法的真正所在。
再說下apply()和call()。這兩個方法的用途都是在特定的做用域中調用函數,實際上等於設置函數體內this對象的值。它們是每一個函數都具備的非繼承而來的方法。
apply()接受兩個參數,一個是在其中運行函數的做用域,另外一個是參數數組。其中第二個參數能夠是Array實例,也能夠是arguments對象。
call()和apply()相同,它們的區別僅在於接受參數的方式不一樣。call()第一個參數是this的指向,其他的參數都是直接傳遞給函數。
--本篇記錄不是一次性寫完,中間有不少事情耽擱了,零零散散的感受沒有什麼邏輯,隨便看看了各位~