函数笔记

2018-04-24  本文已影响9人  xingkong_s

函数定义

function foo(){
  console.log(1)
}
var x = foo
var y = foo()
  var fn6 = i => i+1
  var fn7 = (i,j) => i+j
  var fn8 = (i,j) => {console.log(i);return i+j}
//只有一句话 就不需要return了
//有两句话  就把return 现示 的 说出来

词法作用域

不会立即执行
抽象词法树 先看你语法对不对 再从头开始执行

 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 找不到
那么 找当前作用域上一层作用域 在fn2 同级里面找 local 找到了

fn3 里面的 local2 不会影响fn2 里面的 local2s
一个函数里面 能访问那些变量 在做词法分析的时候 就确定了
跟你调用不调用 没关系

注意的是 词法分析 只是 判断 这个变量 是不是 这个变量
不能判断它的值 是不是 这个变量的值 (因为 这个值可能会变)
分析语义 不分析值

call stack 栈

a 在执行之前先把它记下来
执行代码时 也把它的当前记下来
碰到函数 在执行之前 先把它的当前记下来
运行完了 就回到 刚才记下的地方
return 就离开函数 回到函数执行前 记下的位置
call stack 里 记录的是你是从哪儿离开的

call & apply & this & arguments

在你进入一个函数的时候 除了记录你进去的地址
还有你传给函数 的参数有哪些

function f(){
    console.log(this)
    console.log(arguments)
}

思路:

      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')

person.sayHi()的时候
用this就能访问到 调用时候的person
可以这么写
既然你没有传person
那 我得找个 关键字来 代替 函数里面的person --> 用this关键字

person.sayHi()             //以 person 为this 调用sayHi
person.sayHi.call(person)  //以 person 为this 调用sayHi

      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)
          }
      }

js之父 为了 满足 person.sayHi() 这样的代码能够运行
不用传person 我也能知道 当前对象是什么
于是 它创建了 this 这样的关键字
this是什么? 就是 函数之前的 .前面的东西
如果没.呢? this就是 window

var fn = person.sayHi

person.sayHi() //Hi ,I amfrank
fn() //Hi ,I am 
window.name = 'xxx' //Hi ,I amxxx

如果 我不想传 person 就给你传个对象 {name:‘xxx’}

person.sayHi.call({name:'xxx'}) //Hi ,I amxxx


function(){
              console.log('Hi, I am' + this.name)
          }

这个函数 是独立存在的
它和sayHi 、person 没有任何关系
就是和 call有关系
call 什么this 过来
函数里面的 this 就是什么

结论:

fn.bind(this)

返回一个函数 这个函数 会把 bind 前面的函数 包起来
//函数 还没有执行

function(){
    fn.call()                   
}

call里面是什么?
bind里面是什么 它就是什么
bind的作用 就是在 调用fn时 在新fn的后面 加call

fn.bind = function(x,y,z){
    var oldFn = this //外面的fn  bind .前面的东西
    return function(){
        oldFn.call(x,y,z)
    }
}

旧函数调用bind 的时候会返回一个新函数
新的函数被调用的时候 会去调用旧函数
怎么调呢 在旧函数后面加个 call
call的第一个参数 就是bind 的第一个参数

如果你希望 一个函数里面和外面的 this一样的话 用箭头函数
因为箭头函数 本身是没有this的

箭头函数 对它来说 this永远没办法指定
它的this永远是它外面的this

function 本身是一定有this的

当进入一个function的时候
把它压到 call stack 里面
确定一个this 一定会确定this 没传也确定this

箭头函数呢
压到 call stack
不绑定this 绑定 arguments

上一篇 下一篇

猜你喜欢

热点阅读