JavaScript函数全解

1.函数声明

JavaScript函数有匿名函数、具名函数和箭头函数三种。

匿名函数
let fn = function () {
  return 1
} //引用匿名函数的地址
let fn2 = fn //引用匿名函数地址
console.log(fn.name) //fn
console.log(fn2.name) //fn

函数就是对象,对象存在堆内存里面。匿名函数的函数名就是引用它的变量的名字。

具名函数
function fn3() {
  return 3
}
console.log(fn3.name)  //fn3

let fn5 = function fn4() {
  return 4
}
console.log(fn4.name) //Uncaught ReferenceError: fn4 is not defined
console.log(fn5.name) //fn4

fn3的作用域的全局,fn5引用了fn4,所以fn4的作用域是函数本身。

箭头函数
let fn6 = i => i + 1  //一个参数写法
let fn7 = (i, j) => {  //多个参数写法
  console.log(i, j)
  return i + j;
}

箭头函数没有name,但是箭头函数没有this

2.词法作用域(静态作用域)

静态作用域又叫做词法作用域,采用词法作用域的变量叫词法变量。词法变量有一个在编译时静态确定的作用域。词法变量的作用域可以是一个函数或一段代码,该变量在这段代码区域内可见(visibility);在这段区域以外该变量不可见(或无法访问)。词法作用域里,取变量的值时,会检查函数定义时的文本环境,捕捉函数定义时对该变量的绑定。【维基百科】

var global1 = 1  //全局变量
function fn1(param1){
  var local1 = 'local1'  //局部变量 
  var local2 = 'local2'  //局部变量
  function fn2(param2){
    var local2 = 'inner local2'  //局部变量
    console.log(local1)
    console.log(local2)
  }
  function fn3(){
    var local2 = 'fn3 local2'  //局部变量
    fn2(local2)
  }
  fn2() 
  //local1
  //inner local2
  fn3()
  //local1
  //inner local2
}
fn1()
词法树

词法树只能确定变量的关系,不能确定变量的值。

3.this和arguments

this 就是 call 的第一个参数!call 的其他参数统称为 arguments
call才是正常的函数调用,其他调用函数的方式都是语法糖。

function f(){
  console.log(this)
  console.log(arguments)
}
f.call() // window,相当于f.call(undefined)
f.call({name:'frank'}) // {name: 'frank'}, []
f.call({name:'frank'},1) // {name: 'frank'}, [1]
f.call({name:'frank'},1,2) // {name: 'frank'}, [1,2]

this 是隐藏的第一个参数,且一般是对象,用于占位。arguments是伪数组,第二到最后一个参数都放里面,如果只有一个参数就为[]。

4.call、apply和bind

fn.call(asThis, p1,p2) 是函数的正常调用方式
当你不确定参数的个数时,就使用 apply
fn.apply(asThis, params)

call 和 apply 是直接调用函数,而 bind 则是返回一个新函数(并没有调用原来的函数),这个新函数会 call 原来的函数,call 的参数由你指定。

5.函数柯里化

函数柯里化就是只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。(返回函数的函数)

//柯里化之前
function sum(x,y){
  return x+y
}
//柯里化之后
function addOne(y){
  return sum(1, y)
}
//柯里化之前
function Handlebar(template, data){
  return template.replace('{{name}}', data.name)
}
//柯里化之后
function Handlebar(template){
  return function(data){
    return template.replace('{{name}}', data.name)
  }
}

6.高阶函数

在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:
a.接受一个或多个函数作为输入:forEach sort map filter reduce,
b.输出一个函数:lodash.curry,
c.不过它也可以同时满足两个条件:Function.prototype.bind

7.回调函数

被当做参数的函数就是回调函数(调用这个回调),回调跟异步没有任何关系。

//同步回调
array.sort.call(array, fn)
array.forEach.call(array, fn)
array.map.call(array, fn)
array.filter.call(array, fn)
array.reduce.call(array, fn)
//异步回调
setTimeout(fn, 1000)

8.构造函数

返回对象的函数就是构造函数,一般首字母大写。

new Number(1)
new String('s')

function Empty(){
  this.name = 'null'
  return this
}
var empty = new Empty  //Empty.call({})

你可能感兴趣的:(JavaScript函数全解)