摘要:構(gòu)造器的調(diào)用這其實很簡單,就是使用創(chuàng)建的是一個對象,而不是一個函數(shù)這里的指向的就是上的。但需要注意在構(gòu)造器內(nèi)不能顯示的返回一個對象否則你的實例化就會被破壞。
this的使用
關(guān)于js里面有哪些難點(diǎn),艸,js里面全是難點(diǎn)。。。什么閉包,原型,函數(shù),對象,類型檢測,this。。。但是作為一名正統(tǒng)的前端愛好者而言---這點(diǎn)痛算什么。今天我們來解決this這個點(diǎn)。由于牽扯到this,則必定會牽扯到函數(shù),因為沒有函數(shù)就沒有this的存在的意思。
話不多說,Cut~
1. 作為對象的方法調(diào)用 2. 作為普通函數(shù)調(diào)用 3. 構(gòu)造器調(diào)用 4. call,apply調(diào)用作為對象方法調(diào)用
var obj = { name :"jimmy", getName(){ return this.name; } } console.log(obj.getName()); // jimmy
這里的this指向的是該對象.由于函數(shù)里面this是在運(yùn)行時指定的,所以有一個訣竅就是,函數(shù)里面的this,指的是使用"."調(diào)用函數(shù)的所有者。
document.querySelector("#jimmy").onclick = function(){ console.log(this.tagName); }
上面的this指的就是document.querySelector("#jimmy")。還有一種情況,當(dāng)你使用的時候前面什么都沒加,則這是函數(shù)中的this是global對象---window. 那上面的法則不是不對嗎? 其實,在window里面調(diào)用函數(shù),可以這樣寫.
function getName(){ console.log("jimmy"); } window.getName(); //jimmy getName(); //jimmy
上面兩種寫法是完全等價的,只是一般比較懶,直接寫成下面那一種了。
作為普通函數(shù)調(diào)用上面已經(jīng)說了,普通函數(shù)的this的不指定性,即,在使用之前函數(shù)的this都是不定的,直到函數(shù)執(zhí)行的時候。
在es5中規(guī)定,當(dāng)你的函數(shù)在全局中執(zhí)行,該this會指向window.如果在嚴(yán)格模式下,則this為undefined
function name(){ console.log(this); } console.log(name()); // undefined
通常,當(dāng)你的函數(shù)作為普通函數(shù)被調(diào)用的時候,this指向的是window,這個已經(jīng)說過了~
function getName(){ console.log(this.name); } var obj = { name : "jimmy", getName:getName } obj.getName(); //jimmy
在事件執(zhí)行的時候,this指向的是該元素的引用
123//js document.querySelector(".name").onclick = function(){ console.log(this); } //得到的結(jié)果是.[object HTMLDivElement]
同樣,加深印象。
構(gòu)造器的調(diào)用這其實很簡單,就是使用new + funciton 創(chuàng)建的是一個對象,而不是一個函數(shù).
function GetName(){ this.name = "jimmy"; } GetName.prototype.getName = function(){ return this.name; } var get = new GetName(); get.name(); //jimmy get.getName(); //jimmy
這里的this指向的就是getName.prototype上的。
但需要注意在構(gòu)造器內(nèi)不能顯示的返回一個對象,否則你的實例化就會被破壞。
function GetName(){ this.name = "jimmy"; return {}; //顯示返回一個對象 } GetName.prototype.getName = function(){ return this.name; } var name = new GetName(); console.log(name); //{} var name2 = GetName(); console.log(name2); //{} //顯示返回一個非對象 function GetName(){ this.name = "jimmy"; return "sam"; //返回非對象 } GetName.prototype.getName = function(){ return this.name; } var name = new GetName(); console.log(name); //["Object Object"] var name2 = GetName(); console.log(name2); //samcall,apply調(diào)用
call和apply的區(qū)別,一個是傳入?yún)?shù)為枚舉,一個為數(shù)組
實際上,他們的用處還有擴(kuò)展了函數(shù)的作用域
function getName(){ console.log(this.name); } var obj = { name : "jimmy" } getName.call(obj); //jimmy //相當(dāng)于 obj.getName = getName; obj.getName(); //這一個執(zhí)行過程
使用call || apply改變this的作用域是非常關(guān)鍵的.
this的丟失
所謂的this丟失一般指的就是函數(shù)中this的丟失. 因為函數(shù)中的this只有在執(zhí)行的時候才會確定指向。
var getId = document.getElement; getId("#name"); //這里會報錯
上面的錯誤主要是因為,使用document.getElement時,this是指向document,在getElement里面會需要使用this上面的一系列方法,而上面的方式則和普通調(diào)用函數(shù)的方式一樣,這時this的指向是全局的global,所以會造成有些方法使用不到. 這里可以改進(jìn):
var getId = (function(fn){ return funciton(){ //返回函數(shù) return fn.apply(document,arguments); } })(document.getElement); //保存引用 console.log(getId("#name"));
但其實上面寫法還不如直接return好使.這里只是方便講解.
而es5里面的bind函數(shù)應(yīng)該算是一個將call和apply用到了點(diǎn)子上的方法。
var getName = function(){ console.log(this.tagName); //DIV var sam = function(){ console.log(this.tagName); //undefined } sam(); } document.querySelector(".name").onclick = getName;
上面的問題其實已經(jīng)說到過了,就是出在函數(shù)作為普通函數(shù)調(diào)用的時候,里面的this永遠(yuǎn)指向的是 被賦予的對象。比如sam。 上面getName函數(shù)在執(zhí)行的時候this是指向document.querySelector(".name")的.所以不會有什么問題.
改進(jìn)的辦法就是將this保存作用域(閉包).
var getName = function(){ var _this = this; var sam = function(){ console.log(_this.tagName); //DIV } sam(); } document.querySelector(".name").onclick = getName;
由于閉包的長相完全是芙蓉姐姐,所以在es6中為了避免閉包的露臉加上了 箭頭函數(shù)的feature.
var getName = function(){ var sam =()=>{ console.log(this.tagName); } sam(); } document.querySelector(".name").onclick = getName; //DIV
完美輸出. 雖然這樣會顯得你比較牛逼,但是如果你把這個投入生產(chǎn),保證leader分分鐘切si 你。 md這么長.
這時候apply就完美登場了。
var getName = function(){ console.log(this.tagName); } document.querySelector(".name").onclick = function(){ getName.apply(this); };
是不是感覺少了很多代碼~ 其實還可以再次改進(jìn),使用bind.
document.querySelector(".name").onclick = getName.bind(document.querySelector(".name"));
但這樣其實還不如使用apply. 還需要注意的是call和apply都會直接執(zhí)行函數(shù),而bind只是返回一個函數(shù).
apply和call的用法還有一個,就是借用其他對象的方法.
比如Math.max();函數(shù),本來他只能接受枚舉的參數(shù),但可以使用apply進(jìn)行裝換
var num = [1,2,3,4,3,22]; console.log(Math.max.apply(null,num)); //22
上面基本說明了apply和call的用處,但事實上,只要你用得好,apply和call的價值應(yīng)該灰常大的。比如你還可以使用[].slice.call(arguments),用來將arguments類數(shù)組對象轉(zhuǎn)化為一個真正的數(shù)組。
Ending~
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/78461.html
摘要:在使用利用面向?qū)ο蟮乃枷雱?chuàng)建類和對象時,通常是使用構(gòu)造函數(shù),工廠方式,原型方式,原型構(gòu)造函數(shù)方式等。 在使用javascript利用面向?qū)ο蟮乃枷雱?chuàng)建類和對象時,通常是使用構(gòu)造函數(shù),工廠方式,原型方式,原型構(gòu)造函數(shù)方式等。構(gòu)造函數(shù)其實就是使用一個使用new操作符調(diào)用函數(shù),當(dāng)使用new調(diào)用時,構(gòu)造函數(shù)內(nèi)用到的this對象會指向新創(chuàng)建的對象實例,例如: function Person(na...
摘要:我們的引擎使用預(yù)定義的分隔符來連接日志中的信息,并存儲在一個中。在抽象類中定義帶參數(shù)的構(gòu)造函數(shù)在抽象類中定義動態(tài)屬性的第一種方法是定義一個參數(shù)的構(gòu)造函數(shù)。 翻譯:瘋狂的技術(shù)宅原文:http://programmergate.com/def...本文首發(fā)微信公眾號:充實的腦洞 Abstract關(guān)鍵字通常被用于類和方法,用來把某些行為的實現(xiàn)委托給子類。由于Java不支持抽象屬性,如果你試圖...
摘要:翻譯瘋狂的技術(shù)宅原文本文首發(fā)微信公眾號歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章現(xiàn)在已經(jīng)成為一個實驗性功能,但是只有在中才能用在生產(chǎn)中。創(chuàng)建完成后,我們可以導(dǎo)入并用它來創(chuàng)建我們的,我們稱之為。在巨大的宣傳攻勢下將會使變得過時。 翻譯:瘋狂的技術(shù)宅原文:https://www.toptal.com/react/... 本文首發(fā)微信公眾號:jingchengyideng歡迎關(guān)注,每天都...
摘要:餅狀圖將數(shù)據(jù)用切割成份的圓來展示。至于半徑,我們用寬度的一半與高度的一半的較小值,因為我們不想讓餅狀圖超出。結(jié)果看起來如下這樣繪制圓環(huán)圖我們已經(jīng)看到如何創(chuàng)建餅狀圖。怎樣畫洞呢我們可以畫一個白色的圓在餅狀圖上。 showImg(https://segmentfault.com/img/bVObDh?w=850&h=362); 原文:https://code.tutsplus.com/zh...
閱讀 1755·2021-11-18 13:20
閱讀 1140·2021-10-11 10:59
閱讀 2987·2021-08-24 10:01
閱讀 3499·2019-08-29 14:21
閱讀 3351·2019-08-29 14:15
閱讀 3512·2019-08-26 12:23
閱讀 3342·2019-08-26 11:46
閱讀 3344·2019-08-26 11:35