(JS基礎)this 的指向

定義

this是一個指針,指向的是函數執行的環境對象
javascript


舉例說明 this 的指向

普通函數

普通函數內的this指向執行環境對象,例子中的執行環境是window
java

var a = 'window'
function fn(){
  let a = 'fn'
  return this.a
}
fn();        // 'window'複製代碼

構造函數建立的對象的方法內

構造函數建立的對象的方法內的this指向該對象,例子中的this指向是objapp

function Fn(){
  this.a = 'Fn'
  this.getA = function(){
    return this.a
  }
}
var obj = new Fn()    // {a:'Fn',getA(){return this.a}}
obj.a;        // 'Fn'
obj.getA()    // 'Fn'複製代碼

對象中的方法內

對象中的方法內的this指向對象自己,即對象爲該方法的執行環境。其本質是上例子的語法糖。函數

var a = 'window'
var obj = {
  a: 'obj',
  getA(){
    return this.a
  }
}
obj.getA();    // 'obj'複製代碼

改變this指向

函數賦值

賦值可能會使函數內的this指向發生改變。ui

var a = 'window'
var obj1 = {
  a: 'obj1',
  getA: null
}
var obj2 = {
  a: 'obj2',
  getA(){
    return this.a
  }
}
console.log(obj2.getA())    // 'obj2'
obj1.getA = obj2.getA
console.log(obj1.getA())    // 'obj1'
var getA = obj2.getA
console.log(getA())         // 'window'複製代碼

apply()

apply(thisArg, [argsArray])方法可改變運行函數的上下文,第一個參數傳入"運行函數的上下文";第二個參數爲可選參數,原方法的參數。this

let x = 500;
let obj1 = { x: 100 }
let obj2 = {
  x: 10,
  add(y, z) {
    return this.x + y + z
  }
}
// 也能夠傳入匿名對象
let a = obj2.add.apply(obj1, [3, 4]);         // a=107
let b = obj2.add.apply({ x: 200 }, [20, 30]); // b=250
// 第一個參數爲指定對象時,默認爲全局對象
let b = obj2.add.apply(null, [20, 30]);       // b=550
let b = obj2.add.apply(undefined, [20, 30]);  // b=550
複製代碼

call()

call(thisArg, arg1, arg2, ...)的用法與apply()基本一致,第一個參數也相同,不一樣的只是把第二個參數拆開列出。一樣是上面的例子,使用call()以下:
spa

let a = obj2.add.call(obj1, 3, 4);         // a=107複製代碼

bind()

bind(thisArg[, arg1[, arg2[, ...]]])用於建立一個新的函數,在調用時設置this關鍵字爲提供的值。並在調用新函數時,將給定參數列表做爲原函數的參數序列的前若干項。例子以下:prototype

let obj1 = { x: 100 }
let obj2 = {
  x: 10,
  add(y, z) {
    return this.x + y + z
  }
}
let fn = obj2.add.bind(obj1, 2);   // fn是一個函數,且設置了第一個參數爲2
fn(3);    // 105複製代碼

Function.prototype.apply.call(func, this, Args)

Function.prototype.apply.call(func, args)用於將任意函數綁定任意參數對象執行。如:指針

let obj = { a: 1 }
function fn() {
  console.log(this.a);
}
Function.prototype.apply.call(fn, obj);   // 1複製代碼

要理解該函數並不難,其實相似這種內置對象的原型對象的方法都是同樣的思路:code

默認狀況下,咱們經過實例對象調用該方法(如,fn.apply())。對於apply()來講,fn就是方法的"調用者",即this的指向對象。

當把Function.prototype.apply做爲一個函數總體,則需爲其提供"this"和"thisArgs"。"this"就是相似於fn的函數對象;"thisArgs"就是相似於fn.apply()的參數。

若是文字表述太無力,請看下面例子:

let obj = { c: 100 }
function fn(a, b) {
  console.log(a + b + (this.c || 0))
}
// 如下結果都是 103
fn.call(obj, 1, 2);
fn.apply(obj, [1, 2]);
Function.prototype.apply.call(fn, obj, [1, 2]);
Function.prototype.apply.apply(fn, [obj, [1, 2]]);
Function.prototype.call.call(fn, obj, 1, 2);
Function.prototype.call.apply(fn, [obj, 1, 2]);複製代碼
相關文章
相關標籤/搜索