www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 單片機(jī) > 程序喵大人
[導(dǎo)讀]前言:一轉(zhuǎn)眼從事前端已經(jīng)6年了,從當(dāng)時(shí)的小白到如今大廠的技術(shù)專家,中間也走過(guò)不少?gòu)澛?,從今天開(kāi)始我會(huì)持續(xù)更新前端技術(shù)文章,并且整體的文章會(huì)進(jìn)行體系梳理,整個(gè)知識(shí)體系分為:基礎(chǔ)精講,框架講解,框架及工具原理,前端面試題精講,大廠面試題收錄精講,前端新技術(shù)講解。通過(guò)完善的技術(shù)精講助力...

前言:一轉(zhuǎn)眼從事前端已經(jīng)6年了,從當(dāng)時(shí)的小白到如今大廠的技術(shù)專家,中間也走過(guò)不少?gòu)澛?,從今天開(kāi)始我會(huì)持續(xù)更新前端技術(shù)文章,并且整體的文章會(huì)進(jìn)行體系梳理,整個(gè)知識(shí)體系分為:基礎(chǔ)精講,框架講解,框架及工具原理,前端面試題精講,大廠面試題收錄精講,前端新技術(shù)講解。通過(guò)完善的技術(shù)精講助力各位快速成長(zhǎng),同時(shí)也希望各位能夠在我的幫助下獲得比較好的offer,少走彎路,大家一起加油。那么開(kāi)始我們的第一篇文章吧。


頭疼的this

????為什么說(shuō)是頭疼的this,對(duì)于常年使用C ,C#,Java等這些面向?qū)ο笳Z(yǔ)言的程序員來(lái)說(shuō),幾乎天天都和this打交道。在這些語(yǔ)言里,this含義非常明確,就是指向當(dāng)前的對(duì)象實(shí)例,我們用起來(lái)也是相當(dāng)?shù)姆判?。然而,到了JavaScript這個(gè)動(dòng)態(tài)語(yǔ)言里,this的寫(xiě)法沒(méi)變,但是其含義卻大大地不同了,JavaScript中的this總是讓人迷惑,應(yīng)該是js眾所周知的坑之一。個(gè)人也覺(jué)得js中的this不是一個(gè)好的設(shè)計(jì),由于this晚綁定的特性,它可以是全局對(duì)象,當(dāng)前對(duì)象,或者…有人甚至因?yàn)榭哟蠖挥胻his,我們一般在面試中面試官又會(huì)扔過(guò)來(lái)一堆各種各樣的考察this的題目,很是頭疼。

那到底什么是this?this是什么?

??? this是指包含它的函數(shù)作為方法被調(diào)用時(shí)所屬的對(duì)象。這句話理解起來(lái)感覺(jué)還是很拗口的,但是如果你把它拆分開(kāi)來(lái)變成這三句話后就好理解一點(diǎn)了。

  • 1.包含它的函數(shù)

  • 2.作為方法被調(diào)用時(shí)

  • 3.所屬的對(duì)象

一、this的指向

首先我們先要記住this的幾個(gè)特點(diǎn):

  • this 總是(非嚴(yán)格模式下)指向一個(gè)對(duì)象,而具體指向哪個(gè)對(duì)象是在運(yùn)行時(shí)基于函數(shù)的執(zhí)行環(huán)境動(dòng)態(tài)綁定的,而非函數(shù)被聲明時(shí)的環(huán)境;

  • 除了不常用的with和eval的情況,具體到實(shí)際應(yīng)用中,this指向大概可以分為四種:

    • 作為對(duì)象的方法調(diào)用;

    • 作為普通函數(shù)調(diào)用;

    • 構(gòu)造器調(diào)用;

    • call 或 apply調(diào)用;

    • 箭頭函數(shù)中,this指向函數(shù)上層作用域的this;

  • 構(gòu)造器普通函數(shù)的區(qū)別在于被調(diào)用的方式;

  • A,call(B) => 可以理解成在B的作用域內(nèi)調(diào)用了A方法;

1.1 作為對(duì)象的方法調(diào)用

當(dāng)函數(shù)作為對(duì)象的方法被調(diào)用時(shí),this指向該對(duì)象

var obj = { a: 'jianxi', getName: function(){ console.log(this === obj); console.log(this.a); }};
obj.getName(); // true jainxi
1.2?作為普通函數(shù)被調(diào)用
當(dāng)函數(shù)不作為對(duì)象的屬性被調(diào)用,而是以普通函數(shù)的方式,this總是指向全局對(duì)象(在瀏覽器中,通常是Window對(duì)象)

window.name = 'jianxi';
var getName = function(){ console.log(this.name);};
getName(); // jianxi或者下面這段迷惑性的代碼

window.name = 'koa'var obj = { name: 'jianxi', getName: function(){ console.log(this.name) }};
var getNew = obj.getName;getNew(); // koa而在ES5的嚴(yán)格模式下,this被規(guī)定為不會(huì)指向全局對(duì)象,而是undefined

1.3 構(gòu)造器調(diào)用

除了一些內(nèi)置函數(shù),大部分Js中的函數(shù)都可以成為構(gòu)造器,它們與普通函數(shù)沒(méi)什么不同

構(gòu)造器普通函數(shù)的區(qū)別在于被調(diào)用的方式:當(dāng)new運(yùn)算符調(diào)用函數(shù)時(shí),總是返回一個(gè)對(duì)象,this通常也指向這個(gè)對(duì)象

var MyClass = function(){ this.name = 'jianxi';}var obj = new MyClass()obj.name; // jianxi但是,如果顯式的返回了一個(gè)object對(duì)象,那么此次運(yùn)算結(jié)果最終會(huì)返回這個(gè)對(duì)象。

var MyClass = function () { this.name = 1; return { name: 2 }}var myClass = new MyClass();console.log('myClass.name:', myClass.name); // { name: 2}只要構(gòu)造器不顯示的返回任何數(shù)據(jù),或者返回非對(duì)象類型的數(shù)據(jù),就不會(huì)造成上述問(wèn)題。

1.4 call或apply調(diào)用

跟普通的函數(shù)調(diào)用相比,用call和apply可以動(dòng)態(tài)的改變函數(shù)的this

var obj1 = { name: 1, getName: function (num = '') { return this.name num; }};
var obj2 = { name: 2,}// 可以理解成在 obj2的作用域下調(diào)用了 obj1.getName()函數(shù)console.log(obj1.getName()); // 1console.log(obj1.getName.call(obj2, 2)); // 2 2 = 4console.log(obj1.getName.apply(obj2, [2])); // 2 2 = 41.5箭頭函數(shù)

箭頭函數(shù)不會(huì)創(chuàng)建自己的this,它只會(huì)從自己的作用域鏈的上一層繼承this。因此,在下面的代碼中,傳遞給setInterval的函數(shù)內(nèi)的this與封閉函數(shù)中的this值相同:

this.name = 2var obj = { name: '1', getName: () => { console.log(this.name) }}
obj.getName()
1.6常見(jiàn)的坑

就像標(biāo)題一樣,有的時(shí)候this會(huì)指向undefined

情況一

var obj = { name: '1', getName: function (params) { console.log(this.name) }};obj.getName();
var getName2 = obj.getName;getName2()
這個(gè)時(shí)候,getName2()作為普通函數(shù)被調(diào)用時(shí),this指向全局對(duì)象——window。

情況二

當(dāng)我們希望自己封裝Dom方法,來(lái)精簡(jiǎn)代碼時(shí):

var getDomById = function (id) { return document.getElementById(id);};getDomById('div1') //dom節(jié)點(diǎn)那么我們看看這么寫(xiě)行不行?

var getDomById = document.getElementByIdgetDomById('div1') // Uncaught TypeError: Illegal invocation(非法調(diào)用)這是因?yàn)?

  • 當(dāng)我們?nèi)フ{(diào)用document對(duì)象的方法時(shí),方法內(nèi)的this指向document。

  • 當(dāng)我們用getId應(yīng)用document內(nèi)的方法,再以普通函數(shù)的方式調(diào)用,函數(shù)內(nèi)容的this就指向了全局對(duì)象。

利用call和apply修正情況二

document.getElementById = (function (func) { return function(){ return func.call(document, ...arguments) }})(document.getElementById)// 利用立即執(zhí)行函數(shù)將document保存在作用域中

二、call和apply

不要因?yàn)樗摹皬?qiáng)大”而對(duì)它產(chǎn)生抗拒,了解并熟悉它是我們必須要做的,共勉!

1.call和apply區(qū)別

先來(lái)看區(qū)別,是因?yàn)樗鼈?span>幾乎沒(méi)有區(qū)別,下文代碼實(shí)例call和apply都可以輕易的切換。

當(dāng)它們被設(shè)計(jì)出來(lái)時(shí)要做到的事情一摸一樣,唯一的區(qū)別就在于傳參的格式不一樣

  • apply接受兩個(gè)參數(shù)

    • 第一個(gè)參數(shù)指定了函數(shù)體內(nèi)this對(duì)象的指向

    • 第二個(gè)參數(shù)為一個(gè)帶下標(biāo)的參數(shù)集合(可以是數(shù)組或者類數(shù)組)

  • call接受的參數(shù)不固定

    • 第一個(gè)參數(shù)指定了函數(shù)體內(nèi)this對(duì)象的指向

    • 第二個(gè)參數(shù)及以后為函數(shù)調(diào)用的參數(shù)

因?yàn)樵谒校ǚ羌^)函數(shù)中都可以通過(guò)arguments對(duì)象在函數(shù)中引用函數(shù)的參數(shù)。此對(duì)象包含傳遞給函數(shù)的每個(gè)參數(shù),它本身就是一個(gè)類數(shù)組,我們apply在實(shí)際使用中更常見(jiàn)一些。

call是包裝在apply上面的語(yǔ)法糖,如果我們明確的知道參數(shù)數(shù)量,并且希望展示它們,可以使用call。

當(dāng)使用call或者apply的時(shí)候,如果我們傳入的第一個(gè)參數(shù)為null,函數(shù)體內(nèi)的this會(huì)默認(rèn)指向宿主對(duì)象,在瀏覽器中則是window。

借用其他對(duì)象的方法

我們可以直接傳null來(lái)代替任意對(duì)象

Math.max.apply(null, [1, 2, 3, 4, 5])

2.call和apply能做什么?

使用一個(gè)指定的 this 值和單獨(dú)給出的一個(gè)或多個(gè)參數(shù)來(lái)調(diào)用一個(gè)函數(shù)——來(lái)時(shí)MDN(opens new window)

  • 調(diào)用構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)繼承;

  • 調(diào)用函數(shù)并且指定上下文的?this;

  • 調(diào)用函數(shù)并且不指定第一個(gè)參數(shù);

1.調(diào)用構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)繼承

通過(guò)“借用”的方式來(lái)達(dá)到繼承的效果:

function Product(name, price) { this.name = name; this.price = price;}
function Food(name, price) { Product.call(this, name, price); // this.category = food;}
var hotDog = new Food('hotDog', 20);2.調(diào)用函數(shù)并且指定上下文的?this

此時(shí)this被指向了obj

function showName() { console.log(this.id ':' this.name);};
var obj = { id: 1, name: 'jianxi'};
showName.call(obj)3.使用call單純的調(diào)用某個(gè)函數(shù)

Math.max.apply(null, [1,2,3,10,4,5]); // 10

三、模擬實(shí)現(xiàn)一個(gè)call

先來(lái)看一下call幫我們需要做什么?

var foo = { value: 1};function show() { console.log(this.value);};show.call(foo); //1就像解方程,要在已知條件中尋找突破哦口:

  • call?使得this的指向變了,指向了foo;

  • show?函數(shù)被執(zhí)行了;

  • 傳入的參數(shù)應(yīng)為?this? 參數(shù)列表;

第一版代碼

上面提到的3點(diǎn),僅僅完成了一點(diǎn),且傳入的參數(shù)

var foo = { value: 1}function show() { console.log(this.value);}
Function.prototype.setCall = function (obj) { console.log(this); // 此時(shí)this指向show obj.func = this; // 將函數(shù)變成對(duì)象的內(nèi)部屬性 obj.func(obj.value) // 指定函數(shù) delete obj.func // 刪除函數(shù),當(dāng)做什么都沒(méi)發(fā)生~}show.setCall(foo)第二版代碼

為了解決參數(shù)的問(wèn)題,我們要能獲取到參數(shù),并且正確的傳入:

var foo = { value: 1}function show(a, b) { console.log(this.value); console.log(a b)}Function.prototype.setCall = function (obj) { obj.fn = this; // 將函數(shù)變成對(duì)象的內(nèi)部屬性 var args = []; for(let i = 1; i < arguments.length; i ){ args.push('arguments[' i ']'); } eval('obj.fn(' args ')'); // 傳入?yún)?shù) delete obj.fn; // 刪除函數(shù),當(dāng)做什么都沒(méi)發(fā)生~}
show.setCall(foo, 1, 2); // 1 3此時(shí),我們就可以做到,傳入多個(gè)參數(shù)的情況下使用call了,但是如果你僅想用某個(gè)方法呢?

第三版代碼

Function.prototype.setCall = function (obj) { var obj = obj || window; obj.fn = this; var args = []; for(var i = 1, len = arguments.length; i < len; i ) { args.push('arguments[' i ']'); } var result = eval('obj.fn(' args ')'); delete obj.fn; return result;};// 測(cè)試一下var value = 2;var obj = { value: 1 };
function bar(name, age) { console.log(this.value); return { value: this.value, name: name, age: age }}bar.setCall(null); // 2console.log(bar.setCall(obj, 'kevin', 18));

三、bind

提到了callapply,就繞不開(kāi)bind(),來(lái)看一下MDN上對(duì)**bind()**的解釋:

bind() 方法創(chuàng)建一個(gè)新的函數(shù),在 bind() 被調(diào)用時(shí),這個(gè)新函數(shù)的 this 被指定為 bind() 的第一個(gè)參數(shù),而其余參數(shù)將作為新函數(shù)的參數(shù),供調(diào)用時(shí)使用。

bind 可以被new , 可以進(jìn)行構(gòu)造函數(shù)

我們用Js來(lái)模擬一個(gè)bind方法,以便加深我們的認(rèn)識(shí)

Function.prototype.newBind = function(context) { if(typeof this !== 'function') { throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); } var self = this; var args = Array.prototype.slice.call(arguments, 1); // 間接調(diào)用數(shù)組方法,獲取第一次傳的參數(shù)
let tempFn = function {}; // 利用一個(gè)空函數(shù)作為中轉(zhuǎn)
tempFn.prototype = this.prototype; // 修改返回函數(shù)的 prototype 為綁定函數(shù)的 prototype,實(shí)例就可以繼承綁定函數(shù)的原型中的值
var resultFn = function () { var innerArgs = Array.prototype.slice.call(arguments); if (this instanceof tempFn) { // 如果 返回函數(shù)被當(dāng)做構(gòu)造函數(shù)后,生成的對(duì)象是 tempFn 的實(shí)例,此時(shí)應(yīng)該將 this 的指向指向創(chuàng)建的實(shí)例。 return self.apply(this, args.concat(innerArgs)); } else { return self.apply(context, args.concat(innerArgs)) } }
resultFn = new tempFn(); return resultFn;}

這樣看上去,bind總會(huì)幫我們返回同樣的this值,還是挺堅(jiān)挺的哦~


如果您看到了最后,不妨收藏、點(diǎn)贊、評(píng)論一下吧!??!

持續(xù)更新,您的三連就是我最大的動(dòng)力,共勉!





本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

南京2025年8月18日 /美通社/ -- 8月18日,作為全球家電行業(yè)領(lǐng)導(dǎo)者之一的博西家電正式與小米旗下領(lǐng)先的智能家居平臺(tái)米家聯(lián)手,旗下品牌博世家電和西門(mén)子家電的全品類優(yōu)選產(chǎn)品融入米家生態(tài),實(shí)現(xiàn)跨品牌的智能互聯(lián),共同拓...

關(guān)鍵字: 小米 米家 智能家居 APP

北京 2025年4月27日 /美通社/ -- 日前,元腦InManage數(shù)據(jù)中心智能管理平臺(tái)全面升級(jí),打通IT基礎(chǔ)設(shè)施管理系統(tǒng)與動(dòng)力環(huán)境監(jiān)控系統(tǒng),實(shí)現(xiàn)雙平臺(tái)統(tǒng)一納管,構(gòu)建覆蓋數(shù)據(jù)中心環(huán)境參數(shù)和服務(wù)器關(guān)鍵數(shù)據(jù)的全域數(shù)據(jù)池...

關(guān)鍵字: 溫度 智能管理 GE AN

無(wú)錫2025年4月11日 /美通社/ -- 在春意盎然的四月,布勒集團(tuán)于無(wú)錫隆重舉行研磨與分散應(yīng)用中心開(kāi)工奠基儀式。這一戰(zhàn)略舉措不僅是集團(tuán)在華發(fā)展的重要里程碑,更彰顯了其深耕中國(guó)先進(jìn)材料市場(chǎng)的堅(jiān)定承諾。瑞士集團(tuán)總部高層、...

關(guān)鍵字: BSP 可持續(xù)發(fā)展 GE 電池技術(shù)

上海2025年4月10日 /美通社/ -- 4月1日-2日,2025中國(guó)生成式AI大會(huì)在北京圓滿舉行,匯聚超過(guò)50位產(chǎn)學(xué)研界重量級(jí)嘉賓,深度解構(gòu)DeepSeek引發(fā)的變革狂潮,全面展示深度推理模型、多模態(tài)模型、...

關(guān)鍵字: 模型 生成式AI APP PEN

4月11日消息,據(jù)央視新聞報(bào)道,日前,由中國(guó)移動(dòng)承建的全國(guó)首個(gè)“四算合一”算力網(wǎng)絡(luò)調(diào)度平臺(tái)正式投入使用。

關(guān)鍵字: 中國(guó)移動(dòng) APP 通信

上海2025年3月27日 /美通社/ -- 2025 年 4 月 8 日至 11 日,第 91 屆中國(guó)國(guó)際醫(yī)療器械博覽會(huì)(CMEF)將在上海國(guó)家會(huì)展中心盛大啟幕。歐姆龍健康醫(yī)療(中國(guó))有限公司(以下簡(jiǎn)稱 “歐姆龍”)將以...

關(guān)鍵字: 歐姆龍 醫(yī)療器械 APP Intel

上海2025年3月7日 /美通社/ -- 麥當(dāng)勞中國(guó)今日宣布,年度社交媒體粉絲節(jié)"派DAY"將于3月10日至16日正式開(kāi)啟。第十一屆派Day以"好奇不停,吃派就對(duì)"為主題,呼應(yīng)3月...

關(guān)鍵字: AI APP 數(shù)字化 模型

2月27日消息,日前,中國(guó)移動(dòng)宣布,在河北滄州完成農(nóng)村場(chǎng)景跨通道智能功率共享外場(chǎng)試驗(yàn),成功驗(yàn)證了中國(guó)移動(dòng)研究院創(chuàng)新提出的“5G基站內(nèi)生功率共享技術(shù)”。

關(guān)鍵字: 中國(guó)移動(dòng) APP 通信

TCL Mini LED電視全球出貨量同比增長(zhǎng)近兩倍 香港2025年2月3日 /美通社/ -- TCL電子控股有限公司("TCL電子"或"公司",01070.HK)今天公布2024年TCL電視全球出貨量數(shù)據(jù)。受惠于公司...

關(guān)鍵字: TCL 電子 AI GE

受美國(guó)禁令影響,除了TikTok停止在美服務(wù)之外,字節(jié)跳動(dòng)旗下其它應(yīng)用也將在美國(guó)全部下線。

關(guān)鍵字: APP 手機(jī)
關(guān)閉