JS学习--函数

257 阅读3分钟

一、函数的声明方式

1.1 具名函数

 function f(input1,input2){
     return input1 + input2
 }
 f.name // 'f'

1.2 匿名函数

(只写一个return和return undefined是一个意思)

此种方式声明并没有语法错误,只是它不能单独使用,要使用匿名函数,就必须要把它付给另外一个变量

1.3 具名函数赋值

这里为什么说y没有定义;同样的语法放在不同的位置意义就不一样,这叫做不一致性,不一致是被当做垃圾处理

1.4 window.Function 函数对象声明,一般不用

1.5 箭头函数(没有名字,只能赋值给其他变量)

二、函数的name属性(没有规律,死记)

三、函数的调用

 f(input1,input2)
 等价于
 f.call(asThis, input1,input2)

f.call(asThis, input1,input2) 其中 asThis 会被当做 this,[input1,input2] 会被当做 arguments 禁止使用 f(input1, input2),因为学会 .call 才能理解 this

f.call()第一个参数可以用this得到,后面的参数可以用arguments得到

四、this和arguments

这里传入的是undefined,为什么打印的会是window(浏览器错误,此处window应小写)

this也可传入其他值

arguments传入的是伪数组,因为它的__proto__指向了Object。伪数组就是长得像数组,但是它的原型链中没有Array.prototype

五、函数作用域

5.1 定义

按照语法树,就近原则
我们只能确定变量是哪个变量,但是不能确定变量的值

作用域(scope)指的是变量存在的范围。在 ES5 的规范中,Javascript 只有两种作用域:一种是全局作用域,变量在整个程序中一直存在,所有地方都可以读取;另一种是函数作用域,变量只在函数内部存在。ES6 又新增了块级作用域,本教程不涉及。

函数外部声明的变量就是全局变量(global variable),它可以在函数内部读取。

在函数内部定义的变量,外部无法读取,称为“局部变量”(local variable)。

函数内部定义的变量,会在该作用域内覆盖同名全局变量。

注意,对于var命令来说,局部变量只能在函数内部声明,在其他区块中声明,一律都是全局变量。

5.2 作用域

函数本身也是一个值,也有自己的作用域。它的作用域与变量一样,就是其声明时所在的作用域,与其运行时所在的作用域无关。

上面代码中,函数x是在函数f的外部声明的,所以它的作用域绑定外层,内部变量a不会到函数f体内取值,所以输出1,而不是2。

总之,函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域。

很容易犯错的一点是,如果函数A调用函数B,却没考虑到函数B不会引用函数A的内部变量。

上面代码将函数x作为参数,传入函数y。但是,函数x是在函数y体外声明的,作用域绑定外层,因此找不到函数y的内部变量a,导致报错。

同样的,函数体内部声明的函数,作用域绑定函数体内部。

上面代码中,函数foo内部声明了一个函数bar,bar的作用域绑定foo。当我们在foo外部取出bar执行时,变量x指向的是foo内部的x,而不是foo外部的x。正是这种机制,构成了下文要讲解的“闭包”现象。

面试题

六、闭包

    var n = 2
    function f(){
      console.log(n)
    }

如果一个函数使用了它范围外的变量,那么(这个函数+这个变量)就叫做闭包

七、eval 命令

eval命令的作用是,将字符串当作语句执行。