函数调用
- 作为函数
- 作为方法
方法调用的参数和返回值的处理,和普通函数调用完全一致。但是,方法调用和函数调用有一个重要的区别,即:调用上下文。属性访问表达式由两部分组成:一个对象和属性名称。在像这样的方法调用表达式里,对象成为调用上下文,函数体可以使用关键字this引用该对象。
大多数方法调用使用点符号来访问属性,使用方括号[]也可以进行属性访问操作。
var f = function (x, y) {
return x + y
}
var o ={m: ''}
o.m = f
console.log(o.m(1, 2)) // => 3
console.log(o["m"](1, 2))
复制代码
- 作为构造函数
如果函数或者方法调用前带有关键字new,它就构成构造函数调用。构造函数调用和普通函数调用以及方法调用在实参处理、调用上下文和返回值方面都有不同。
var o = new Object()
var a = new Arrary() // 有无圆括号表达意思一样复制代码
- 通过它们的call()和apply()方法间接调用
JS中的函数也是对象,和其他JS对象没什么两样,函数对象也可以包含方法。其中的两个方法call()和apply()可以用来间接地调用函数。两个方法都允许显示指定调用所需的this值,也就是说,任何函数可以作为任何对象的方法来调用,哪怕这个函数不是那个对象的方法。两个方法都介意指定调用的实参。
闭包
函数的执行依赖于变量作用域,这个作用域是在函数定义时决定的,而不是函数调用时决定的。函数对象可以通过作用域链相互关联起来,函数体内部的变量都可以保存在函数作用域内。
从一方面来看,所有的JS函数都是闭包: 它们都是对象,它们关联到作用域链。定义大多数函数是的作用域链在调用函数时依然有效,但这并不影响闭包。当一个函数嵌套宁外一个函数,外部函数将嵌套的函数作为返回值返回时就是调用函数时闭包所指向的作用域链和定义函数时的作用域链不是同一个作用域链。
var s = 'g'
function c () {
var s = 'l'
function f () {
return s
}
return f()
}
console.log(c())复制代码