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