this 指向和修改this指向

this

this是js中的一個關鍵字,函數運行時自動生成的一個內部對象,只能在函數內部使用。咱們要討論的是 this 的指向。web

this就是函數運行時自動生成的一個內部對象數組

this的指向不是在建立時就決定了,而是由執行環境決定的。app

下面介紹一下幾種狀況下,this的指向函數

一、全局環境

全局環境下,this就表明window對象。(針對web 應用來說)this

var name = 'zhar';
function say(){
  console.log(this.name);//zhar
}
say();

一樣,在 setTimeout 或 setInterval 這樣的延時函數中調用也屬於全局對象spa

var name = 'zhar';
setTimeout(function(){
  console.log(this.name);//zhar
},0);

二、對象環境

對象環境指向對象。指針

var obj = {
  name : "zhar",
  say : function(){
    console.log(this.name);//zhar
  }
}
obj.say();

下面舉兩個經典的例子:code

var name = 'tom';
var obj = {
  name : "zhar",
  say : function(){
    console.log(this.name);
  }
}
var fun = obj.say;
fun();//輸出 ?//tom-->fun定義在全局環境下,即window.fun()
//再次說明了this的指向是由運行時的執行環境來決定的
var name = 'tom';
var obj = {
  name : "zhar",
  say : function(){
    return function(){
      console.log(this.name);
    }
  }
}
obj.say()();//輸出 ?//tom

三、構造函數環境

構造函數中的this 會指向建立出來的實例對象,使用new 調用構造函數時,會先建立出一個空對象,而後用call函數把構造函數中的this指針修改成指向這個空對象。執行完環境後,空對象也就有了相關的屬性,而後將對象返回出去,因此說就不用咱們本身手動返回啦~對象

function Person() {
    this.name = 'zhar';
}
var p = new Person();
console.log(p.name);

綜合以上,構造函數不須要返回值,若是咱們指定一個返回值時,this的指向將發生變化繼承

function Person() {
  this.name = 'zhar';
  return {};
}
var p = new Person();
console.log(p.name);//undefined
//--------------------------------------
function Person() {
  this.name = 'zhar';
  return {name:'tom'};
}
var p = new Person();
console.log(p.name);//tom      若是構造函數返回對象(Object,Array,Function),那 this 將指向這個對象,其它基礎類型則不受影響
//--------------------------------------
function Person() {
  this.name = 'zhar';
  return 1;//number string boolean 等
}
var p = new Person();
console.log(p.name);//zhar

因此,如無必要咱們一般不要設置構造函數的返回值

四、事件對象

在 DOM 事件中使用 this,this 指向了觸發事件的 DOM 元素自己

li.onclick = function(){
    console.log(this.innerHTML);
}

總結下來就是一句話:是誰調用的,this就指向誰

下面介紹一下如何來修改this 的指向

一、可使用局部變量來代替this指針

var name = "zhar";
var obj = {
  name : "zhar",
  say : function(){
    var _this = this;//使用一個變量指向 this
    setTimeout(function(){
      console.log(_this.name);
    },0);
  }
}
obj.say();

該方法爲很是經常使用的一個方法

二、使用call 或 apply 方法

首先說明一下,call也是函數調用的一種形式,能夠經過 函數名.call()來調用函數。可是提供了一個修改this指向的方法。

fun.call(thisObj[,arg1[,arg2[,...]]])

調用方式和傳入參數如上面的形式。其中,因此call(thisObj[,arg1[,arg2[,...]]])中的第一個參數就是要更改this指向的對象,爲必選參數; 以後的參數要根據調用的函數是否須要傳入參數(爲可選的)

下面經過代碼來展現call 如何使用:

var name = 'zhar';
function say(){
  console.log(this.name);
};
say();//zhar;
var obj = {
  name : 'tom',
  say : function(){
    console.log(this.name);
  }
}
say.call(obj);//tom      將 say 函數中的 this 替換爲傳入的對象
obj.say();//tom
obj.say.call(null);//zhar    將 obj.say 函數的 this 替換爲了 null,也就意味着指向了全局環境
//前面課程的繼承代碼
function Person(){
  this.name = "人";
}
function Student(){
  Person.call(this,null);
}
var s = new Student();
console.log(s.name);
li.onclick = function(){
  console.log(this.innerHTML);//此處的 this 表明着 DOM 元素
  function update(){
    this.innerHTML += " new ";
  }
  //update();//這樣作的話,this 的指向將變爲window
  update.call(this);//經過 call 方法修改函數內 this 的指向
}
//call 的傳參
function say(arg1,arg2){
  console.log(this.name,arg1,arg2);
};
var obj = {
  name : 'tom',
  say : function(){
    console.log(this.name);
  }
}
say.call(obj,'one','two');//tom one two

apply

apply的做用和call同樣,不一樣的是傳參的形式。apply須要以數組的形式傳遞參數

//apply 的傳參
function say(arg1,arg2){
  console.log(this.name,arg1,arg2);
};
var obj = {
  name : 'tom',
  say : function(){
    console.log(this.name);
  }
}
say.apply(obj,['one','two']);//tom one two

以上就是關於this指向和如何修改this指向的介紹

做者:丶灰太狼他叔 連接:https://www.jianshu.com/p/8d357981dedb 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。

相關文章
相關標籤/搜索