1. 程式人生 > >Javascript的this指向問題

Javascript的this指向問題

javascript中的this指向是在函式呼叫時確定的。

(1)、this指向全域性物件window的情況

1、全域性作用域中或普通函式中

//全域性作用域
console.log(this); //非嚴格模式window,嚴格模式undefined
//普通函式
function bar(){
    console.log(this); //非嚴格模式window,嚴格模式undefined
}
bar(); //相當於bar.call(window)

2、 匿名函式和自執行函式

匿名函式的執行環境具有全域性性,因此其this物件指向window,閉包中this指向window,可以將全域性變數常駐記憶體。(javascript高階程式設計第2版148頁)

//自執行函式
(function(){
    console.log(this); //window
})();
var name = "the window";
var object = {
    name:"My Object",
    getNameFunc:function(){
        return function(){ //這裡形成一個閉包
            return this.name;  //this指向window
        }
    }
};
console.log(object.getNameFunc()());  //輸出the window

3、巢狀函式和回撥函式中
和變數不同,關鍵字this沒有作用域的限制,巢狀的函式不會從呼叫它的函式中繼承this;如果巢狀函式作為方法呼叫,其this的值指向呼叫它的物件;如果巢狀函式作為函式呼叫,其this值是全域性物件(非嚴格模式)或undefined(嚴格模式下)。呼叫巢狀函式時this並不是指向呼叫外層函式的上下文。

(javascript權威指南第6版171頁)

var o={
       m:function(){
            var self=this;  //將this儲存到變數self中
            console.log(this);  //this指向呼叫它的物件o
            f();
            function f(){   //定義一個巢狀函式f
                console.log(this); //非嚴格模式下,this指向window
                console.log(self); //self儲存的是外層函式的this
} } }; o.m();

(2)、函式作為物件的方法呼叫,this指向那個物件

var obj = {
    name:"123",
    getName:function(){
        console.log(this);//this指向obj
        console.log(this.name); //輸出123
    }
};
obj.getName(); //相當於obj.getName.call(obj)

(3)、建構函式呼叫
1、若建構函式無return或return 一個原始值或null(即數字、字串、布林、undefined、null),this指向new出來的那個物件,返回值型別,有原型方法;

//無返回值的建構函式
function Super1(a){
        this.a = a; 
        //return 123; //返回原始值或null有同樣的效果
}
//定義兩個原型方法
Super1.prototype.sayHello=function(){
        console.log("Hello");
};
Super1.prototype.age = 18;

var newsup1 = new Super1(1);//例項化物件
console.log(newsup1); // Super1 { a=1,  age=18,  sayHello=function()}
console.log(newsup1.a); //1
console.log(newsup1.age); //18
newsup1.sayHello(); //Hello

2、若建構函式return 一個引用型別(即陣列、函式、物件),this指向返回的那個引用型別,返回引用型別,沒有原型方法;

//返回值為引用型別的建構函式
function Super2(a){
        this.a = a; 
        return {a:2}; //返回原始值或null有同樣的效果
}
//定義兩個原型方法,在這裡沒有用
Super2.prototype.sayHello=function(){
        console.log("Hello");
};
Super2.prototype.age = 18;

var newsup2 = new Super2(1);//例項化物件
console.log(newsup2); //  Object { a=2}
console.log(newsup2.a); //2
console.log(newsup2.age); //undefined
newsup2.sayHello(); //出錯,TypeError: newsup2.sayHello is not a function

(4)、事件中this指向
W3C事件處理程式中,this指向觸發這個事件的物件;但IE中,attachEvent中的this總是指向全域性物件window,這是兩者的主要區別。

(5)、綜合應用

第一個例子

var o={
   a:10,
    b:{
        a:12,
        fn:function(){
            console.log(this);
            console.log(this.a);
        }
    }
};
//(1)
o.b.fn(); //輸出b和12

//(2)
var j=o.b.fn;
j(); //輸出window和undefined

//(3)
var j=o.b;
j.fn(); //輸出b和12

上例中(1)相當於o.b.fn.call(b),this永遠指向的是最後呼叫它的物件,所以this指向b;
上例(2)相當於j.call(window),this指向window;
上例(3)相當於j.fn.call(j),實則j.fn.call(o.b),this指向最後呼叫它的物件b。

第2個例子

var name = "222";
var a={
    name:"111",
    say:function(){
        console.log(this.name);//這個this指向物件a
        return function(){
            console.log(this.name);//這個this指向window
        };
    }
}
var fun = a.say;
fun(); //222,相當於fun.call(window)
a.say();//111,a.say.call(a);
a.say()(); //111,222
var b={
    name:"333",
    say:function(fun){
        fun();//巢狀函式裡的this指向window
    }
};
b.say(a.say);//222,因為巢狀函式裡的this指向window
b.say=a.say;//b.say和a.say指向同一個函式
b.say();//333

(5)關於建構函式的new
new的過程
1、建立一個新物件;
2、將建構函式的作用域賦給新物件,即this指向新物件,同時繼承該建構函式的原型;
3、執行建構函式中的程式碼、屬性和方法新增到this指向的新物件中;
4、返回新建立的物件
(6)、ES6中箭頭函式的指向
箭頭函式沒有自己的this,它的this是繼承而來的,預設指向是在定義它時所處的物件(宿主物件)而不是執行時的物件,定義它時可能環境是window;
箭頭函式可以方便地讓我們在setTimeout,setInterval中方便的使用this;
箭頭函式中的this是固定的,會繫結定義時所在的作用域,而不是指向執行時所在的作用域;

普通函式和箭頭函式比較

普通函式

 function foo1(){
    var that = this;//將this存放在變數that中
    setTimeout(function(){
        console.log(this); //回撥函式中的this指向window,輸出window
        console.log(this.b);//undefined
        console.log(that);//obj1
        console.log(that.b); //2
    },1000);
}
var obj1={
    b:2
};
foo1.call(obj1);

箭頭函式

function foo2(){
    var that = this;
    setTimeout(()=>{
        console.log(this); //obj2,這個this指向函式定義時所在的物件
        console.log(this.b); //2
    },1000);
}
var obj2={
    b:2
};
foo2.call(obj2);

箭頭函式的注意事項:

  • 函式體內的this物件,就是定義時所在的物件,而不是使用時所在的物件;
  • 不可以當作建構函式,也就是說,不可以使用new命令,否則會丟擲錯誤;
  • 不可以使用arguments物件,該物件在函式體內不存在,若要用,可以用Rest引數代替;
  • 不可以使用yield命令,因此箭頭函式不能用作Generator函式。

相關推薦

十分鐘徹底理解javascript 的 this指向,不懂請砸店

hub 改變 alert blog var rip def 徹底 文章 函數的this指向誰,和函數在哪裏被定義的,函數在哪裏被執行的沒有半毛錢關系,只遵守下面的規律: 在非嚴格模式中: 1、自執行函數裏面,this永遠指向window; <script

installed jre指向jdk而非jre位置&

信息 進行 pyw classpath www alt+ date 內容 檢查  1、eclipse菜單 - Window - Preferences- Java - Installed JREs 將配置的JRE定位到JDK,例如JRE home:D:\Program F

this指向問題

new ext 一個 bind tex 下標 context 調用 app 1.誰最終調用函數,this指向誰。① this指向的,永遠是對象!!! ②this指向誰,永遠不取決於this寫在哪,而是取決於函數在哪調用 ③this指向的對象,我們稱之為函數的上下問conte

JS中this到底指向誰?

this tex name style cnblogs 回調函數 可能 set [0  關於this的指向,是一個令人很頭疼的問題。但是,你運氣好,碰到了我。老夫這兒有本祖傳秘籍,看懂這個,媽媽再也不用擔心你的this指向不對啦!   歸根結底,this指向就一句話:誰最終

Java--父類的引用指向子類的對象詳解!

show 小明 一個 oid void get color system eight 例:   第一步.創建一個Person類 package com.maya.ball; public class Person { private int age; p

徹底搞清函數中的this指向

指向 重新 全局 pan code 一個 返回 log 改變 近日閱讀《javascript設計模式與開發實踐》 書中的apply和call調用函數層出不窮,很多妙用; 函數中的this是根據調用方式來決定的 函數調用方式有4中 1、直接調用 a(...arg); 函

在javascript中對於this指向的再次理解

全局變量 依據 兩個 uem rip 二次 第一個 定義 無法 總所周知,function () {}函數體內的this對象指向的是調用該函數的對象,那麽我們看一下這個例子 <script> var length = 3; function fn ()

JavaScript中的this的指向

全局 code app 屬性。 () color asc return apply() this是JS的關鍵字,隨著函數使用場合的不同,this值會發生變化。但總的原則是,this總是指向調用this所在函數的那個對象。 1、純函數調用 function test(){

JavaScript this的指向問題

實例 all 它的 cal 會有 bsp con scrip clas this的指向 在函數創建的時候,this的指向還未確定,它最終指向調用它的對象 window.onload=function(){  window.a="我的曾經"  function da()

jQuery 插件 的this 指向問題(實戰)

jquery對象 base64 原型 str avs 查看源碼 sed clear 選中 daterangepicker 是一個JavaScript組件,用來選擇日期。 資源直接搜索 daterangepicker 即可,當然好看的樣式可以基於Bootstrap。 官網:h

淺談this指向問題

nload blog spa 例子 ++ bsp sca type pre 剛開始學習js,被this弄得暈頭轉向,回過頭來也想總結一下希望能幫助正被this‘折磨’的人 我們先來看看直接執行this的情況 alert(this);//指向的是window 函數中執行

TypeScript 中的 this指向問題

編程 依然 5-0 簡單 下午 cal call 調用 src TypeScript 中的 this指向問題 如果你接觸過TypeScript有一段時間,那麽你會發現很多並非語言設計當中的“特征”。這些所謂的特征並非真正TypeScript的語法糖部分,也並非語言設計當中

關於this的指向

function 方法 var use () this user getcount tco 一般來說,this指向的其實就是:包含this的函數(對象)的父元素; var User={   data:this,//包含這個this的是User對象,其父元素是window

Java Script this指向的所有情況

創建 hang script 指向 new func name () 所有 // 1.直接調用,指向全局console.log(this);// 2.在普通函數裏調用,指向全局function fn(){ console.log(this);}fn();3.構造函數普通調用

解決指向iframe的target失效

頁面 ram bug 斷點調試 失效 是否 控制臺 變量 點擊 今天遇到一個bug。 主頁面中點擊左側導航欄【某】項後,右側的iframe頁面加載到了新窗口。之後,所有選項的iframe加載都異常。 檢查<a>標簽target="main"指向正確。 意識到ta

父類引用指向子類對象

static 指向 多繼承 反射機制 board oid 簡單明了 信息 繼承關系 父類引用指向子類對象指的是: 例如父類Animal,子類Cat,Dog。其中Animal可以是類也可以是接口,Cat和Dog是繼承或實現Animal的子類。 Animal animal =

JavaScript中this關鍵字的指向問題

asc 函數調用 javascrip new spa con oba cti func 1、純粹的函數調用,this就代表全局對象Global var x = 1; function test(){ var x = ‘二哈‘; console.log(th

了解Js中的this指向

理解 per pre ron document 它的 執行環境 col .sh   Js中的this對象是在運行時基於函數的執行環境綁定的,其中的this指向很不好理解,一不小心就用錯了位置;。   this的指向在函數定義的時候是確定不了的,只有函數執行的時候才能確定th

javascript中this的指向

span this 有時 變量 mage bsp 匿名函數 javascrip 生成 作為一個前端小白在開發中對於this的指向問題有時候總是會模糊,於是花時間研究了一番。 首先this是JS的關鍵字,this是js函數在運行是生成的一個內部對象,生成的這個this只能在函

父類的引用對象指向子類的對象

() exce png hole 虛擬機 end 類對象 -h 類型   在java的多態中,經常會看到父類的引用對象指向子類的對象,一開始很迷茫,因為按照之前所學的知識,父類的引用對象指向自身對象或者子類的引用對象指向自身對象都不難理解,因此為了方便理解,下面舉了一個例子