函数定义和调用形式
函数定义形式
-
函数定义方式
- 通过函数声明的形式来定义
- 通过函数表达式的形式来定义
- 通过 Function 构造函数实例化的形式来定义
-
Function构造函数
-
可以传入任意数量的实参(string类型)
-
最后一个实参为函数体
-
eg: var max = new Function("a","b","return a>b?a:b;"
-
-
函数定义三要素
- 函数名,函数的参数,函数的返回值
-
具名/匿名函数
- 匿名函数
- 单独的匿名函数无法运行,可以赋值给变量或立即执行
- 具名函数优势
- 当遇到错误时,堆栈跟踪会显示函数名,容易寻找错误
- 匿名函数
-
name属性:返回函数实例的名称
-
length属性:函数的形参个数
-
函数的参数:调用时,传递的实参数量可以与形参数量不一致
arguments对象
- arguments对象
- 代表传入函数的实参
- 是函数中的局部变量
- 不能显式创建,只有函数调用时才可用
- 它是一个类数组对象
- 类数组对象
- 与数组一样具有 length 与 index 属性;本质是 Object,length代表实参数量
- arguments与形参的“双向绑定”特性
- 在函数调用时 arguments 对象与实际传递了值的形参变量发生双向绑定,arguments 对象中的对应单元会和命名参数建立关联
call/apply/bind方法
-
函数对象
- 每个函数都是作为对象来运行和维护的
- 对象是一系列属性和方法的集合 ,所以函数也有对应的 属性和方法
- 可以将**函数(函数对象)**赋值给一个变量,或将函数作为参数进行传递
- 属性:name,length,prototype
- 方法:call,apply,bind,toString,valueOf
- 每个函数都是作为对象来运行和维护的
-
this关键字
- 在 function 内部被创建
- 指向调用时所在函数所绑定的对象
- this 不能被赋值,this 的值取决于函数被调用的方式
-
call()方法
-
语法:fn.call(thisObj,arg1,arg2,…)
-
参数:arg1,arg2,…:调用的实参(参数序列)
thisObj:this指向的对象
-
返回值:与fn普通调用相同
-
作用:调用函数,改变函数执行的this指向
-
-
apply()方法
- 语法:fn.apply(thisObj,[arg1,arg2,…])
- 被调用的参数是参数数组
- 返回值:与fn普通调用相同
- 作用:调用函数,改变函数执行的this指向
-
bind()方法
- 语法:fn.bind(thisObj,arg1,arg2,…)
- 参数:调用的是参数序列
- 返回值:返回一个原函数的拷贝(绑定函数),并拥有指定的 this 值和初始参数
- apply,call 都会立即调用函数执行,bind 不会立即调用函数
函数调用形式
- 作为函数直接调用(非严格模式下this为全局对象,严格模式下为undefined)
- 作为方法调用(this指向调用此方法的对象)
- 通过call( )和apply( )间接调用(this为函数对象的call/apply方法的首个参数 )
- 作为构造函数调用(this指向实例化出来的对象)
预解析
- JavaScript代码运行机制
- 执行分两个阶段
- 代码解析阶段:将代码翻译成可执行代码 (预解析:声明提升)
- 代码执行阶段:执行可执行代码
- 编译和执行过程
- 全局解析阶段(全局预解析)
- 全局顺序执行阶段(变量赋值、函数调用等操作)
- 当遇到函数调用时,进行函数范围内的预解析,再执行函数内代码
- 当存在函数嵌套时,以此类推,会进行多次函数解析与执行
- 注意:解析和执行是不断交替的过程
- 执行分两个阶段
- 声明提升
- 所有的变量声明和函数声明提升到当前作用域的最前面
- 声明提升规则:
- 函数声明整体提前
- 变量声明提前,赋值留在原地
- 函数会优先被提升,然后才是变量
- 函数声明有冲突,会覆盖;变量声明有冲突,会忽略