咱们接着上面一篇继续~
1. Date类型
JavaScript中的Date类型使用自UTC时间,1970年1月1日零时开始的毫秒数来保存日期。
创建一个日期对象:
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() 、 Date.UTC()
还有一些简化的方法:Date.parse() 和 Date.UTC()。其中Date.parse()方法接受一个表示日期的字符串参数,然后尝试根据这个字符串返回相应日期的毫秒数。(但是在JavaScript中并没有规定传入改方法的参数的格式):
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.
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
-
Date.now()
该方法可以获取当前日期和时间的毫秒数:
var start = Date.now() //获取开始时间
do() //做些啥
var stop = Date.now() //获取结束时间
如果某些浏览器不支持的话,我们可以通过以下技巧获得当前时间的毫秒数,就是在前面加一个‘+’:
var s = +new Date()
console.log(s) //1506069877901
-
继承的方法
这里说下继承自Object的三个方法,toLocalString, toString, valueOf:
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返回的是时间对象的毫秒数。
-
日期格式化方法
Date类型还有一些专门用于将日期格式化为字符串的方法:
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"
以上的这些方法都会根据系统环境而异。
-
日期/时间组件方法
下面介绍一下Date对象提供的一些方法,可以取得和设置日期值中特定部分的方法。
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()
二. Function类型
在JavaScript中,函数其实就是一个对象,每个函数都是Function类型的实例,而且和其他引用类型一样具有属性和方法。
因为函数是一个对象,所以函数名其实是一个指向函数对象的指针,不会与某个函数绑定。
定义函数有两种方法:函数声明和函数表达式。
function fn(){ ... }
var fn = function() { ... };
还有一种方法就是通过Function构造函数。Function构造函数可以接受任意数量的参数,但最后一个参数始终都是被看成函数体。前面的额参数则枚举新函数的参数。
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是不会保存对函数的引用。而且由于第一行已经报错了,代码也不会继续向下执行。
-
作为值的函数
JavaScript中,函数名本身也是一个变量,所以函数可以作为值来使用。所以函数可以作为另外一个函数的参数,而且可以将一个函数作为另外一个函数的结果进行返回。
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
}
}
}
-
函数内部属性
-
callee
在函数内部,有两个特殊的对象:arguments和this。arguments是一个类数组的对象,它包含传入函数中的所有参数。该对象还有一个callee的属性,该属性是一个指针,指向的是拥有这个arguments对象的函数。
-
callee
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
函数内部的另一个特殊对象是this,this引用的是函数当前执行的环境对象。this是在函数调用的时候进行绑定的。完全取决于函数的调用位置。
当某个函数在全局作用域中定义的,当在全局作用域中调用改函数时,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的调用位置就是全局作用域
-
caller
另外一个函数对象的属性是:caller.该属性保存着调用当前函数的函数引用。如果在全局作用域中调用当前函数,它的值为null。
function outer() {
inner()
}
function inner() {
console.log(inner.caller)
}
outer()
-
函数属性和方法
前面说过函数也是一个对象,所以函数也是有属性和方法的。每个函数都包含两个属性:length和prototype.其中length属性表示函数接受命名参数的个数。
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的指向,其余的参数都是直接传递给函数。
--本篇记录不是一次性写完,中间有很多事情耽搁了,零零散散的感觉没有什么逻辑,随便看看了各位~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。