摘要:前幾天在牛客網上做題,遇到一道關于指向的問題,以前就對一知半解的我瞬間懵逼,下面我們來看看這道題,順便講解一下中的指向問題。這個時候中的就指向臨時調用它的對象了,自然得到的就是大白。
前幾天在牛客網上做題,遇到一道關于this指向的問題,以前就對this一知半解的我瞬間懵逼,下面我們來看看這道題,順便講解一下js中this的指向問題。
題目:填寫內容讓下面代碼支持a.name = “name1”; b.name = “name2”;
function obj(name){ _______ } obj._____ = "name2"; var a = obj("name1"); var b = new obj;
在做這道題之前,我們先來學習一下this的知識。首先我們必須要明白的是,在javascript中this的指向是在函數被調用時才能確定的,在定義時是不能夠確定的this指向的,準確一點說this最終指向的是調用它的對象。下面我們舉例說明:
1.作為多帶帶的函數被調用1 var name = "小黑"; // 全局變量name 2 function Func() { 3 var name = "大白"; // 局部變量name 4 console.log(this); 5 console.log(this.name); 6 } 8 Func(); 9 console.log(window.Func() === Func()) //true
上面的代碼中,當我們調用Func()函數時,實際上Func()是作為window對象的方法被調用的(第9行代碼可以可以驗證),因此this指向的就是全局對象window,第4行代碼打印出來的也就是window,第5行代碼打印出來的自然也就是全局變量name(所有的全局變量都作為window的屬性)。
2.作為對象的方法被調用還是先看下面的示例代碼:
1 var Obj = { 2 name: "大白", 3 getName: function() { 4 console.log(this.name) 5 } 6 } 7 Obj.getName(); // 大白 8 window.Obj.getName(); // 大白
這段代碼中getName()作為對象Obj的方法被Obj調用,因此這個時候this指向的便是Obj對象,自然this.name得到的就是"大白"。那么在第8行代碼中window調用了getName()為什么不是指向window呢?因為window實際上是通過調用Obj間接調用getName()的,所以this還是指向直接調用它的Obj。
3.作為構造函數被調用function Func() { this.name = "大白"; } var fn = new Func(); console.log(fn.name) // 大白
當我們通過new關鍵字構造一個實例對象的過程中,構造函數中的this一般情況下指向我們構造出來的實例化對象(特殊情況后面有多帶帶講解),因此在構造過程中this.name = "大白"這句代碼就相當于給實例對象fn創建了一個name屬性并賦值"大白"。
使用apply()/call()改變this的指向1 function getName() { 2 console.log(this.name); 3 } 4 var Obj = { 5 name: "大白" 6 } 7 getName.apply(Obj); // 大白 8 console.log(Obj); //{ name: "大白" }
這里用到了apply()方法改變this的指向(不知道apply()用法的自行百度),第7行代碼中我們可以理解成將getName()函數臨時綁定在Obj對象上作為Obj對象的方法,同時調用這個方法。這個時候getName()中的this就指向臨時調用它的Obj對象了,自然this.name得到的就是"大白"。注意這里并沒有改變Obj對象,如第8行代碼所示。
最后要解決前面留下的題,我們還需要講個知識點:當構造函數中的this遇到return時的情況。
//示例1 function Fn1() { this.name = "大白"; return { name: "小黑" }; // 返回一個空對象 } var fn1 = new Fn1(); console.log(fn1.name); // 小黑 //示例2 function Fn2() { this.name = "大白"; return true; // 返回true } var fn2 = new Fn2(); console.log(fn2.name); // 大白
你可能會奇怪,一模一樣的代碼為什么得到的值不一樣呢? 注意!這里兩段代碼是區別的,示例1中函數返回值是一個對象,示例2中的返回值是true,當構造函數中返回值是一個對象時,this指向的就是返回的那個對象,如果返回值不是對象時,返回值指向的就是構造函數的示例對象,因此實例1中的this.name得到的是小黑而不是大白。
現在我們就可以來做上面的題了:填寫內容讓下面代碼支持a.name = “name1”; b.name = “name2”;
//創建全局函數 1 function obj(name){ 2 if(name) { // 區分普通調用和實例化調用 this.name = name; } return this; // 返回this引用,調用時this指向window 3 } 4 obj.prototype.name = "name2"; // 設置原型對象 5 var a = obj("name1"); //直接調用函數,a等于window,name為window的屬性。 6 var b = new obj; //調用函數實例化對象,this指向obj的實例化對象。
上面第4行代碼涉及到對象原型的知識,如果對這方面還有疑問的可以看看我總結的另一篇文章:javaScript原型及原型鏈詳解(一)
以上內容都是我個人的理解,難免會有理解不到位的地方,希望各位不吝賜教!大家一起進步。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/83104.html
摘要:當碰到時呵呵再看一個呵呵再來呵呵呵呵呵呵呵呵什么意思呢如果返回值是一個對象,那么指向的是構造函數的實例但是并沒有被返回,如果返回值不是一個對象那么還是指向構造函數創建的實例。 為什么要學習this?如果你學過面向對象編程,那你肯定知道干什么用的,如果你沒有學過,那么暫時可以不用看這篇文章,當然如果你有興趣也可以看看,畢竟這是js中必須要掌握的東西。 1. this指向調用他的對象 首先...
摘要:下面只探討在瀏覽器中的指向,有興趣的也可以把后面的例子在中跑一下。 我們知道js中有個全局對象就是window,如果在頂層聲明一個變量如 var a=1 //就相當于window.a=1 同時有了node以后,js也可以在服務端運行了,官方解釋為Node.js 是一個基于 Chrome V8 引擎的 JavaScript 運行環境。通俗說node是一個支持js語法的容器,直接寫js就可...
摘要:問題修改實例的,即修改了構造函數的原型對象的共享屬性到此處,涉及到的內容大家可以再回頭捋一遍,理解了就會覺得醍醐灌頂。 開場白 大三下學期結束時候,一個人跑到帝都來參加各廠的面試,免不了的面試過程中經常被問到的問題就是JS中如何實現繼承,當時的自己也是背熟了實現繼承的各種方法,回過頭來想想卻不知道__proto__是什么,prototype是什么,以及各種繼承方法的優點和缺點,想必有好...
閱讀 2671·2023-04-25 18:10
閱讀 1606·2019-08-30 15:53
閱讀 2788·2019-08-30 13:10
閱讀 3216·2019-08-29 18:40
閱讀 1128·2019-08-23 18:31
閱讀 1201·2019-08-23 16:49
閱讀 3400·2019-08-23 16:07
閱讀 877·2019-08-23 15:27