JS

JS深入浅出之关于函数的二三事(一)

Posted by weite122 on 2018-02-13

函数

  • 函数分为匿名函数,具名函数和箭头函数。匿名函数没有名字,具名函数有名字,但两者都有name值,匿名函数的name默认为被赋值的名字。

词法作用域(也叫静态作用域)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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)
}
}

用语法树的方法分析以上代码,很容易看出local之间的关系。

深度截图_选择区域_20180213222518.png

词法作用域只能确定变量之间的关系,但不能确认变量的值是否相同。

1
2
3
4
5
6
7
var a = 1
fn1() {
console.log(a)
}

//a = 2如果不加这行代码,你就可能认为a的值就是1
fn1()

深入阅读:

Call Stack

this & arguments

1
2
3
4
5
6
7
8
function f(){
console.log(this)
console.log(arguments)
}
f.call() // window
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 为什么必须是对象

    因为 this 就是函数与对象之间的羁绊

  var person = {
      name: 'frank',
      sayHi: function(person){
          console.log('Hi, I am' + person.name)
      },
      sayBye: function(person){
          console.log('Bye, I am' + person.name)
      },
      say: function(person, word){
          console.log(word + ', I am' + person.name)
      }
  }
  person.sayHi(person)
  person.sayBye(person)
  person.say(person, 'How are you')

  // 能不能变成 
  person.sayHi()
  person.sayBye()
  person.say('How are you')

  // 那么源代码就要改了
  var person = {
      name: 'frank',
      sayHi: function(){
          console.log('Hi, I am' + this.name)
      },
      sayBye: function(){
          console.log('Bye, I am' + this.name)
      },
      say: function(word){
          console.log(word + ', I am' + this.name)
      }
  }
  // 如果你不想吃语法糖
  person.sayHi.call(person)
  person.sayBye.call(person)
  person.say.call(person, 'How are you')

  // 还是回到那句话:this 是 call 的第一个参数
  // this 是参数,所以,只有在调用的时候才能确定
  person.sayHi.call({name:'haha'})  // 这时 sayHi 里面的 this 就不是 person 了
  // this 真的很不靠谱

  // 新手疑惑的两种写法
  var fn = person.sayHi
  person.sayHi() // this === person
  fn()  // this === window