1.函数声明和函数表达式的不同:
浏览器的解析器在执行环境中加载数据时,对函数声明和函数表达式并非一视同仁,解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);至于函数表达式,则必须等到解析器执行到他所在的代码行,才会真正的被解释执行。函数声明一个重要的特征就是函数声明提升。在执行代码之前会先读取函数声明,这就意味着可以把函数声明放在调用它的语句后面。
代码如下:
如果是这样:
2.函数内部的属性
在函数内部,有两个特殊的对象:arguments和this。arguments表示的是传入函数中所有的参数,虽然arguments的主要用途是保存函数参数,但这个对象还有一个名为callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数,举个例子如下:
这样做的不好的一点就是函数内部的函数执行与函数名sum紧紧的耦合在了一起。为了消除这种紧密耦合的情况,可以使用arguments.callee的属性。
这样就解除了上述问题,使得函数更可用。
下面说说this,this引用的是函数执行的环境对象,例如下面的代码:
说的这里有一个十分重要的两个方法,apply和call,这两个方法的用途都是在特定的作用域中调用函数,实际上就是等于设置函数体的this对象的值,首先apply方法接受两个参数,一个是在其中运行函数的作用域,另一个是参数数组。其中第二个参数,可以试试array实例,也可以是arguments对象。
call方法与apply方法相同,他们的区别仅在于接受参数的方式不同,对于call方法而言,第一个参数是this值没有变化,变化的是其余参数都直接传递给函数。换句话说,就是在使用call()方法时,传递给函数的参数必须逐个列举出来。至于是使用apply和call,完全取决于采取哪种给函数传递参数的方式方便。
事实上,传递参数并非apply和call真正的用武之地,他们真正强大的地方是能够扩充函数赖以运行的作用域。如下:
使用call和apply来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系。
其实在JavaScript中还有一个方法,bind(),这个方法会创建一个函数的实例,其中this值会绑定到给bind()函数值,如下:
3.基本包装类型:
为了便于操作基本类型,3个特殊的引用类型Boolean,Number,String。这些知识我在JavaScript对象中的文章有介绍,喜欢的可以参考一下:点击打开链接,
4.函数中的另外两个重要属性:length和protype:
length:代表函数的参数个数。
protype:是保存他们所有实例方法的真正所在。protype属性是不可枚举的,因此for-in无法实现。
5.闭包:
闭包是指:有权访问另一个函数作用域中的变量的函数。说一下闭包的原理:
①.在后台执行环境中,闭包的作用域链包含着它自己的作用域,包含函数的作用域和全局作用域。
②.通常函数的作用域及其所有变量都会在函数执行结束后被销毁。
③.但是,当函数返回一个闭包时,这个函数的作用域将会一直留在内存中保留到闭包不存在为止。使用闭包可以在JavaScript中模仿块级作用域。