函数原型链,作用域链,递归

函数也是对象

函数是由new Function创建出来的,因此函数也是一个对象, 所有的函数都是new Function的实例

函数的原型链结构

Function.prototype常用成员

  • call:调用函数,重新指向this
  • apply:调用函数,重新指向this
  • bind:重新指向this,返回一个新的函数,不调用。

完整版原型链

总结:

  1. 所有函数都是new Function创建出来的,因此所有函数.__proto__都是Function.prototype
  2. 所有对象都是new Object创建出来的,因此所有对象.__proto__都是Object.prototyp

作用域

作用域:变量起作用的区域,也就是说:变量定义后,可以在哪个范围内使用该变量。

1
2
3
4
5
6
7
var num = 11;//全局变量
function fn(){
var num1 = 22;//局部变量
console.log(num); // 全局变量在任何地方都能访问到
console.log(num1);
}
console.log(num);

JS中没有块级作用域。

在JS里只有函数可以形成作用域,叫做函数作用域。

因为函数能够形成作用域,所以,函数内部声明的变量函数外部无法访问。

函数作用域是在函数定义的时候作用域就确定下来了,和函数在哪调用无关。

1
2
3
4
5
6
7
8
9
10
var num = 123;
function f1() {
console.log(num);
}

function f2(){
var num = 456;
f1();
}
f2();// ?

作用域链

作用域链:只要是函数,就会形成一个作用域,如果这个函数被嵌套在其他函数中,那么外部函数也有自己的作用域,这个一直往上到全局环境,就形成了一个作用域链。

变量的搜索原则:

  1. 从当前作用域开始查找是否声明了该变量,如果存在,那么就直接返回这个变量的值。
  2. 如果不存在,就会往上一层作用域查询,如果存在,就返回。
  3. 如果不存在,一直查询到全局作用域,如果存在,就返回。如果在全局中也没有找到该变量会报错

递归函数

递归函数:函数内部直接或者间接的调用自己

递归的要求:

  1. 自己调用自己(直接或者间接)
  2. 要有结束条件(出口)

递归函数主要是化归思想,将一个复杂的问题简单化,主要用于解决数学中的一些问题居多。

  • 把要解决的问题,归结为已经解决的问题上。
  • 一定要考虑什么时候结束让函数结束,也就是停止递归(一定要有已知条件)