你真的瞭解this指向嗎?

前言

相信不少人都對JavaScript中的this指向問題只知其一;不知其二,因此今天就來詳細看看它究竟是怎麼判斷的。

一. 先看幾道題

var length = 10;
    function fn() {
      console.log(this.length);
    }

  var obj = {
    length: 5,
    method: function(fn) {
      fn();
      arguments[0]();
    }
  };

  obj.method(fn, 1); // 10 2
var name = 'window';

  function f1() {
    var name = 'f1';
    return function f2() {
      var name = 'f2';
      console.log(this.name);
    }
  }

  var foo = f1();
  var bar = {
    name: 'bar',
    foo: foo
  };

  foo(); // window
  bar.foo(); // bar
var name = 'window';
  var bar = {
    name: 'bar',
    foo: function () {
      var self = this;
      console.log(this.name);
      console.log(self.name);
      (function () {
        console.log(this.name);
        console.log(self.name);
      })()
    }
  };

  bar.foo(); // bar bar window bar
var name = 'window';

  function f1() {
    var name = 'f1';
    return () => {
      var name = 'f2';
      console.log(this.name);
    }
  }

  var foo = f1();
  var bar = {
    name: 'bar',
    foo: foo
  };

  foo(); // window
  bar.foo(); // window

二. this綁定規則

1.綁定默認

  1. 當其餘規則沒法應用時將採用默人綁定
  2. 默認綁定將會綁定到全局對象
  3. 嚴格模式(strict mode)下不能講全局對象用於默認綁定
function foo() {
    console.log(this === window);
  }
foo() // true

function bar() {
    "use strict";
    console.log(this === window);
    console.log(this);
  }
bar() // false undefined

2.隱式綁定

若是函數引用有上下文對象時,this將會綁定到這個對象。椎確來講是函數調用時是否有引用上下文對象。app

var name = 'window';
    function foo() {
      console.log(this.name);
    }
  var obj = {
    name: 'obj',
    foo: foo
  };
  obj.foo(); // obj 隱式綁定,上下文對象obj

  var bar = obj.foo;
  bar(); // window 無上下文對象

3.顯示綁定

這也是經常使用的的方式:call、apply、bind 就不一一舉例了。函數

function foo() {
    console.log(this.name);
  }
  var obj = {
    name: 'obj'
  };
  foo.call(obj) // obj

4.new綁定

var a;
  function foo(a) {
    this.a = a
  }
  var bar = new foo(2);

  console.log(a); //undefined
  console.log(bar.a); // 2  this了bar

三.優先級

var a;

  function foo(a) {
    this.a = a;
  }

  var obj = {
    foo: foo
  };
  var obj2 = {};

  console.log(a); // undefined

  obj.foo(1);
  console.log(obj.a); // 1

  obj.foo.call(obj2, 2);
  console.log(obj2.a); // 2

  var baz = obj.foo.bind(obj2);
  var bar = new baz(3);
  console.log(bar.a); // 3

從上面的代碼能夠看出優先級從高到低依次是:new綁定、顯示綁定、隱式綁定、默認綁定。this

相關文章
相關標籤/搜索