[js权威指南]第八章 函数

函数定义

函数挂载在一个对象上,作为对象的一个属性,称为对象的方法,
通过这个对象调用是,该对象就是此次调用的上下文,也就是函数的this

js函数可以嵌套在其他函数中定义,
这样就可以访问他们被定义时所处的作用域的任何变量
构成了一个闭包

函数调用

函数调用

  • 作为函数
  • 作为方法
  • 作为构造函数
  • 通过它们的call()和apply()方法间接调用

任何函数只要作为方法调用实际上都会传入一个隐式的实参
这个实参是一个对象,就是调用方法的母体

方法链:当方法的返回值是一个对象,这个对象还可以再调用它的方法
每次的调用结果都是另外一个表达式的组成部分

函数或方法调用之前带有关键字new,就构成了构造函数调用

构造函数调用创建一个新的空对象,这个对象继承自构造函数的prototyoe属性

间接调用call和apply可以间接调用函数,

  • call使用它自由的实参列表作为函数的实参
  • apply要求以数组的形式传入参数

函数参数

js的函数没有指定函数形参的类型,函数的调用也没有进行类型检查

可选参数

function test(/*...*/ a ){
if(a ===undefined)  a = []  // a没有定义就使用一个新的数组
	return arguments.length  // 返回传入参数的个数
}

当调用的函数的时候传入的实参个数超过了函数定义的形参个数时
在函数体呢,标识符argument指向实参对象的引用
并通过下标来获得其它的参数

可选参数的个数不能为0
arguments不是真正的数组,是一个实参对象

callee是标准的,指代当前正在执行的函数
可以在匿名函数中递归调用自身

var test =function(x){
	if(x<=1) retun 1;
	return x * arguments.calle(x-1);
}

caller是非标准的,指代调用当前正在执行的函数的函数
可以访问调用栈

作为命名空间的函数

将代码放入到一个函数内,然后调用这个函数
这样全局变量就变成了函数内的局部变量
避免与全局变量的冲突

js中是无法声明只在一个代码块内可见的变量的
可以定义一个函数用作临时的命名空间
在这个命名空间内定义的变量都不会污染到全局命名空间


(function() {   // function之前的括号,是把这个函数当作表达式解析
	
}())  // 最后一个括号是立即调用该函数

定义一个匿名函数并立即调用

闭包

函数的执行依赖于变量作用域
这个作用域是在函数定义时决定的

js函数对象的内部状态,不仅包含代码逻辑,还必须引用当前的作用域链
函数对象可以通过作用域链相互关联起来
函数体内部的变量都可以保存在函数作用域内
这种特性称为闭包

闭包是活动的

嵌套的函数不会将作用域内的私有成员复制一份
也不会对所绑定的变量生成静态快照的

this是js的关键字,每个函数调用都包含一个this值,
如果闭包在外部函数里是无法访问this 的,除非外部函数将this 转存为一个变量

函数的属性

  • prototype 属性
    每个函数都包含一个prototype属性
    这个属性是指向一个对象的引用
    这个对象称做原型对象

    每一个函数都包含不同的原型对象
    当函数用作构造函数的时候,
    新创建的对象会从原型对象上继承属性

  • call、apply 方法
    call、apply通过调用方法的形式来间接调用函数
    第一个参数是要调用函数的母对象,是调用上下文 ,this
    在函数体内通过this来获得对它的引用
    传入null 和 undifined 都会被全局对象代替

 // 调用o对象的函数f()
f.call(o)
f.apply(o)

  • bind 方法
    主要作用就是将函数绑定至某个对象,
    在函数f()上调用bind方法传入一个对象作为参数,这个方法将返回一个新的函数
    调用新的函数将会把原始的函数f() 当作对象的方法来调用
    传入新函数的任何参数都将传入原始函数

function f( y ) {
     return this.x + y ;
}

var o  ={x:1}

var g = f.bind(o)

g(2)  // 3

内置函数往往返回一个类似 [native code] 的字符串作为函数体

高阶函数,就是操作函数的函数
接收一个参数,并返回一个新的函数

缓存memorize 接收一个函数作为实参,并返回带有记忆能力的函数

  • function 构造函数
    允许js在运行时动态创建并编译
    创建的函数不使用作用域
    相反,函数体代码的编译总是会在顶层函数执行

猜你喜欢

转载自blog.csdn.net/java_sparrow/article/details/82903327