常用js —— 函数
函数的参数
arguments 对象里保存了所有的实参,是一个伪数组
定义函数的三种方式
- 函数声明
fn() // 函数声明可以先调用,在声明 |
- 函数表达式
var fn = function() { |
- 构造函数 Function
// 函数也是对象,可以使用 Function 构造函数 new 出来 |
Function 属性
- length:获取形参的长度
- name:获取函数的名字,此属性不允许修改
Function.length // 1 |
Function.prototype 成员
- arguments:已废弃,获取函数的实参,现在推荐的做法是使用函数内部可用的
arguments
对象来访问函数的实参 - caller: 已废弃,用于获取当前函数是在哪个函数中调用的
- constructor:指向当前构造函数,Function
- call:调用函数,重新指定 this
- apply:调用函数,重新指定 this
- bind:重新指向 this,返回一个新的函数,不调用
- toString : 得到函数的字符串格式
function a() {} |
函数的四种调用模式
分析 this 指向问题
- 任何函数都有属于自己的 this
- this 是动态的,this 在函数声明的时候是确定不了的,只有当函数被调用了才能够确定 this 的指向,this 的指向和函数在哪被调用没有关系
分析 this 的问题的思路: 1. this 是属于哪个函数 2. 这个函数是何种调用模式
函数调用模式
如果一个函数不是一个对象的属性时,就是被当做一个函数来进行调用的。此时 this 指向了 window
function fn() { |
方法调用模式
当一个函数被保存为对象的一个属性时,我们称之为一个方法。当一个方法被调用时,this 被绑定到当前对象
通过点语法或者中括号语法来访问方法,都是属于方法调用模式
var f = function() { |
构造函数调用模式
如果函数是通过 new 关键字进行调用的,此时 this 被绑定到创建出来的新对象上
function Person() { |
总结:分析 this 的问题,主要就是区分函数的调用模式,看函数是怎么被调用的
// 1. |
方法借用模式
上下文调用模式也叫方法借用模式,分为 apply,call ,bind
任何函数都可以调用 apply,call ,bind 这三个方法
call 方法
call 方法可以调用一个函数,并且可以指定这个函数的 this
指向
call 方法也可以和 () 一样,进行函数调用
第一个参数:指定函数的 this,如果不传,则 this 指向 window;其余参数:和函数的参数列表一模一样
// 调用函数 |
apply 方法
apply()
方法的作用和call()
方法类似,只有一个区别,就是apply()
方法接受的是一个包含多个参数的数组。而call()
方法接受的是若干个参数
function fn(n1, n2) { |
bind 方法
bind() 方法创建一个新的函数、可以绑定新的函数的 this
指向
返回值:新的函数(不会被调用)
参数:新函数的 this 指向,绑定后,无论使用何种调用模式,this 都不会改变
var fn = function() { |
如果对一个函数进行多次 bind,那么上下文会是什么呢
let a = {} |
如果你认为输出结果是 a,那么你就错了,其实我们可以把上述代码转换成另一种形式
// fn.bind().bind(a) 等于 |
可以从上述代码中发现,不管我们给函数 bind 几次,fn 中的 this 永远由第一次 bind 决定,所以结果永远是 window
特殊的 this 指向
- 定时器中的 this 指向了 window,因为定时器的 function 最终是由 window 来调用的
- 事件中的 this 指向的是当前的元素,在事件触发的时候,浏览器让当前元素调用了 function
- call apply bind 第一个参数表示要绑定的 this,不传、传 null 或者 undefined,this 均指向 window,但在严格模式下,不传指向 undefined,传 null 指向 null,传 undefined 指向 undefined
递归函数
递归的要求:1. 自己调用自己 2. 要有结束条件(出口)
// 计算斐波那契数列 |