Loading...
墨滴

二八仔

2021/07/06  阅读:43  主题:全栈蓝

javascript中this的使用

javascript中this的使用

javascript中this指向四个基本场景

  1. 显式绑定,指向绑定对象(call、apply、bind)
  2. 隐式绑定,指向归属属性
  3. new 绑定指向实例
  4. 默认指向全局

一、显式绑定

显式绑定,this的指向比较明确(例如:call、apply、bind等)

var a = 'test '
function foo() {
    console.log('---foo---', this , this.a)
}
const obj = {
    a:'obj'
}
foo.call(obj)  // this => obj对象。 this.a => obj.a

问题1「 如果是foo.call(null), this => 指的对象是什么呢? this.a => 展示的值是什么呢? 」

二、 隐式绑定

隐式绑定常常出现在链式调用中,this总是指向调用它的对象

var a = 'test '
function foo() {
    console.log('---foo---', this , this.a)
}
const obj = {
    a:'obj'
    foo:foo,
    foo2:{
      a:'foo2',
      foo:foo
    }
}
obj.foo() 
// ---foo--- {a: "obj", foo2: {…}, foo: ƒ} obj
// this => {a: "obj", foo2: {…}, foo: ƒ}  this.a => obj

obj.foo2.foo() 
// ---foo--- {a: "foo2", foo: ƒ} foo2
// this => {a: "foo2", foo: ƒ} this.a => foo2

const objFoo = obj.foo;
  • 上面obj.foo的调用中,foothis指向它的调用对象,即obj对象
  • obj.foo2.foo的调用中,foothis指向的是foo2

问题2「执行objFoo(),返回的结果又是什么呢?」

三、new绑定

new绑定的原理其实和显式绑定有一定关系。看下实现new的四步走就明白了

function bar(){
    console.log('---bar---', this , this.a)
}
const fn = new bar();
// ---bar--- bar {} undefined
// this => fn 即Object.create(bar.prototype)

四、默认绑定

当不符合上面的情况的时候,就应该考虑是不是默认绑定全局对象了

问题1

var a = 'test '
function foo() {
    console.log('---foo---', this, this.a)
}
const obj = {
    a: 'obj'
}
foo.call(null)
// ---foo--- Window {window: Window, self: Window, document: document, name: "", location: Location, …} test 
// this => window.  this.a => test

虽然foo显式指定指向了null,显式绑定的方法中会做非空判断,如果不存在便指向当前的上下文对象。

问题2

var a = 'test '
  function foo() {
      console.log('---foo---', this , this.a)
  }
  const obj = {
      a:'obj'
      foo:foo,
      foo2:{
        a:'foo2',
        foo:foo
      }
  }
  const objFoo = obj.foo;
  objFoo()
  // ---foo--- Window {window: Window, self: Window, document: document, name: "", location: Location, …} test 
  this => window.  this.a => test

为什么这次明明使用了obj.foo还是指向默认绑定呢?

答案:obj.foo指向的是foo的引用地址,此时把这个引用地址赋值给了objFoo,等价于 const objFoo = foo,而此时调用 objFoo() 和直接调用 foo() 是等价的,都使用了默认绑定

参数的形式

var a = 'test '
function foo() {
    console.log('---foo---', this, this.a)
}
function bar(fn) {
    fn()
}
const obj = {
    a:'obj'
    foo:foo
}
bar(foo)
bar(obj.foo)
// foo 还是 obj.foo 传递的都是引用地址
// this都是指向全局上下文对象

多层嵌套

var a = 'test '
function foo() {
    console.log('---foo---', this, this.a)
}
function bar() {
    function barch(){
        foo()
        function barchch(){
            foo()
        }
        barchch()
    }
    barch()
}
bar()
// this => window

this指向可以总结为:有绑定指向绑定对象,有归属指向归属对象,有new指向实例对象,其他指向上下文对象

二八仔

2021/07/06  阅读:43  主题:全栈蓝

作者介绍

二八仔