this指向(二)

this指向(二)

技术杂谈小彩虹2021-08-17 9:53:51170A+A-

4 箭头函数(特例)

箭头函数内部是没有this, 是由父级作用域中的this指向

var a = 0
function foo() {
  console.log(this) // obj
  var test = () => {
    console.log(this) // obj
  }
  test()
}
var obj = {
  a: 1,
  foo: foo
}
obj.foo()

那上面的规则对箭头函数this指向有效么?

var a = 0
function foo() {
  var test = () => {
    console.log(this)
  }
  return test
}
var obj1 = {
  a: 1,
  foo: foo
}
var obj2 = {
  a: 2,
  foo: foo
}
obj1.foo()() // 独立调用, 指向却是obj1
// 说明 默认指向 对 箭头函数不生效

var bar = foo().call(obj2) // 指向的却是window
// 说明 显示绑定 对 箭头函数无效
var obj1 = {
  a: 1,
  foo: () => {
    console.log(this)
  }
}
obj1.foo() // 指向window
// 说明隐式绑定对箭头函数无效
var foo = () => {
  console.log(this)
}
new foo() // 报错
// 说明 箭头函数不能当做构造函数

所以所有规则都不适用于箭头函数,箭头函数中的this取决于父环境中的this(箭头函数不存在this)

5 例题

var name = 'window'
var obj1 = {
  name: '1',
  fn1: function() {
    console.log(this.name)
  },
  fn2: () => {
    console.log(this.name)
  },
  fn3: function() {
    return function() {
      console.log(this.name)
    }
  },
  fn4: function() {
    return () => console.log(this.name)
  }
}
var obj2 = {
  name: '2'
}

obj1.fn1()
obj1.fn1.call(obj2)

obj1.fn2()
obj1.fn2.call(obj2)

obj1.fn3()()
obj1.fn3().call(obj2)
obj1.fn3.call(obj2)()

obj1.fn4()()
obj1.fn4().call(obj2)
obj1.fn4.call(obj2)()

结果是 1 2 window window window 2 window 1 1 2

解析:

obj1.fn1() // 对象调用 返回 1
obj1.fn1.call(obj2) // 显示调用obj2 打印2

obj1.fn2() // 箭头函数 指向父级作用域 window
obj1.fn2.call(obj2) // 箭头函数不适用call绑定, 还是window

obj1.fn3()() // 独立调用 window
obj1.fn3().call(obj2) // 指向obj2 2
obj1.fn3.call(obj2)() // 独立调用 指向window 

obj1.fn4()() // 箭头函数指向父级作用域fn4, fn4的作用域是obj1 所以打印1
obj1.fn4().call(obj2) // 同上 箭头函数不适用call绑定
obj1.fn4.call(obj2)() 
// 箭头函数 父作用域变为obj2, 所以 打印2, 此题将父作用域改为了obj2。
// 改变箭头函数的指向 只能通过改变它的父作用域
function Foo () {
  getName = function () {console.log (1)}
  return this
}
Foo.getName = function () {console.log(2)}

Foo.prototype.getName = function () {console.log(3)} // 实例对象上的属性

var getName = function() {console.log (4)} // 函数表达式
function getName() {console.log 5} // 函数声明

Foo.getName() // 2
getName() // 4
Foo().getName() // 1
getName() // 1

new Foo.getName() // 2
new Foo().getName() // 3
new new Foo().getName() // 3

答案: 2 4 1 1 2 3 3

解析:

Foo.getName() // 构造函数的静态属性 直接打印 2
getName() // 4 声明式函数会声明提前 所以被覆盖打印 4
Foo().getName() // Foo 是独立调用, this指向window
// 所以就是window的getName方法 
// 当时函数中的Foo中已经将getName方法 重新赋值 所以打印 1
getName() // 这时候打印的是 1

new Foo.getName() // 2
new Foo().getName() // 3 实例上的属性
new new Foo().getName() // 3 同上

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1
本网站由 提供CDN/云存储服务

联系我们