函数参数作用域&this指向

396 阅读2分钟

普通函数

// 示例代码:
let obj2 = {
  sub (oo) {
    oo.fun()
    console.log('oo.uid', oo.uid);
  }
}

let obj1 = {
  add () {
    let uid = 10;
    let sid = 20
    obj2.sub({
      uid,
      fun () {
        console.log('this', this);
        console.log('sid', sid);
      }
    })
  },
}
obj1.add()


箭头函数

// 示例代码1
let obj2 = {
  sub (oo) {
    oo.fun()
    console.log('oo.uid', oo.uid);
  }
}

let obj1 = {
  a: 555,
  add () {
    let uid = 10;
    let sid = 20
    obj2.sub({
      uid,
      fun: () => {
        console.log('this', this);
        console.log('this.a', this.a);
        console.log('sid', sid);
      }
    })
  },
}
obj1.add()

// 示例2
let obj2 = {
  sub (oo) {
    oo.fun()
    console.log('oo.uid', oo.uid);
  }
}

let xx = 9999
let yyy = () => {
        console.log('this', this);
        console.log('this.a', this.a);
//         console.log('sid', sid);
}

let obj1 = {
  a: 555,
  add () {
    let uid = 10;
    let sid = 20
    obj2.sub({
      uid,
      fun: yyy
    })
  },
}
obj1.add()

image.png

注意示例1和2的区别,仅仅是调整了箭头函数的位置。

场景

场景1

var p = {
  age: 20,
  run: function () {
    let x = 10;
    setTimeout(function () {
      console.log('this', this);
      console.log('x', x);
    }, 1000);
  }
}
p.run()

场景2

// 示例1:
var p = {
  tave: () => {
    setTimeout(() => {
      //this指向window
      //由于箭头函数不具有独立作用域,所以需要向上查找,发现还是一个箭头函数,箭头函数再上面没有其他函数作用域,所以是window作用域
      console.log(this);
    }, 1000);
  }
}
p.tave()

场景3

var p = {
  aa: 10,
  travel: function () {
    setTimeout(() => {
      //this指向p对象
      //由于箭头函数不具有独立作用域,所以需要向上查找,发现是一个匿名函数travel,匿名函数指向p对象
      console.log(this);
    }, 1000);
  },
}
p.travel()

场景4

// 示例1:
var p = {
  aa: 20,
  //es6对象函数的简写:推荐使用的方式
  say () {
    console.log("say方法的this:", this); //指向p
    setTimeout(() => {
      console.log(this); //向上查找发现say函数的this指向p,所以箭头函数的this也指向p
    }, 1000);
  }
}
p.say()

结论

箭头函数:

1. this查找: 箭头函数没有独立作用域,所以箭头函数内部this是箭头函数定义所在位置的外层函数决定的。
2. 作用域查找:箭头函数没有独立作用域,所以箭头函数的上级作用域查找是看箭头函数定义所在位置的外层函数的作用域,如果外层函数还是箭头函数,则再外层一直到window

普通函数:

1. this查找: 谁调用函数,函数内部this就指向谁
2. 作用域查找:当前作用域是本函数内部,上层作用域是函数定义位置的上层函数。


更新中......

vue实例方法this

在vue中,实例方法中的this指向已经bind绑定到实例本身,无法再次通过call、apply、bind改变this指向。(已经bind过的方法,无法再次bind)

<!-- 子组件helloworld -->
<template>
  <div class="hello">
  </div>
</template>
<script>
export default {
  name: 'HelloWorld',
  data(){
    return {
      minkey: 'minkey',
      tt: 111111
    }
  },
  mounted(){
    this.say()
  },
  methods:{
    min(){
      console.log('-------',this.tt)
    },
    say(){
      let temp = new Map()
      temp.set(this.minkey, this.min)
      this.$emit('callback', temp)
    }
  }
}
</script>

<!-- 父组件App -->
<template>
  <div id="app">
    <HelloWorld @callback="callbackHandle"/>
  </div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  data(){
    return {
      tt: 99999
    }
  },
  methods:{
    callbackHandle(map){
      // 打印:-------111111,实例方法this在启动阶段已经bind了,无法再次bind
      map.get('minkey').bind(this)()
    }
  }
}
</script>

箭头函数

箭头函数无法通过call、apply、bind改变this指向,普通函数可以

image.png