日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

js 里面令人头疼的 this

發(fā)布時(shí)間:2025/3/12 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js 里面令人头疼的 this 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

JS中this相關(guān)問(wèn)題梳理

this 就是 js 里的關(guān)鍵字,有特殊意義,代表函數(shù)執(zhí)行主體

一、定義

  • 函數(shù)執(zhí)行主體(不是作用域):意思是誰(shuí)把函數(shù)執(zhí)行了,那么執(zhí)行主體就是誰(shuí)

二、使用情況

  • 全局作用域里的this 是window , 全局作用域下相當(dāng)于是window.fn() 執(zhí)行只是把window 省略了(嚴(yán)格模式下是undefined )。
  • console.log(this === window); // truewindow.a = 13; console.log(this.a); // 13
  • 函數(shù)里的this , 看執(zhí)行主體前有沒(méi)有點(diǎn) ,如果有點(diǎn) ,那點(diǎn) 前面是誰(shuí),函數(shù)里的this 就是誰(shuí),如果沒(méi)有點(diǎn) ,那函數(shù)里的this 就是window ,嚴(yán)格模式下是undefined 。
  • function fn() {console.log(this); } fn(); // windowlet obj = {fn: function() {console.log(this);} } obj.fn(); // obj{...}var f = obj.fn; f(); // window
  • 立即執(zhí)行函數(shù)里的this是window或undefined(嚴(yán)格模式下)
  • (function() {console.log(this); //==> window })(); ~function(){}(); //==> window +function(){}(); //==> window -function(){}(); //==> window !function(){}(); //==> window
  • 回調(diào)函數(shù)里的this一般情況下是window
  • let arr = [1, 2, 3]; arr.forEach(function(item, index) {console.log(this); // 打印了三個(gè)window })setTimeout(function(num) {console.log(num); // 1console.log(this); // window }, 1000, 1)function fn(m) {m(); }fn(function() {console.log(this); // window })
  • 箭頭函數(shù)沒(méi)有this:
  • 但是要是在箭頭函數(shù)里使用this,它就會(huì)往上一級(jí)作用域查找,如果上一級(jí)作用域也沒(méi)有,那就繼續(xù)查找,直到找到全局作用域window為止

    let obj = {num: 2,fn: function() {// this --> objlet m = () => {// this --> objconsole.log(this.num); // obj (要向上一級(jí)查找)}m();} } obj.fn();
  • 構(gòu)造函數(shù)里的this是當(dāng)前的實(shí)例

  • 實(shí)例原型上的公有方法里的this一般是當(dāng)前實(shí)例(下面改變this的方法中有所體現(xiàn))

  • 給元素綁定事件行為,那事件里的this就是當(dāng)前被綁定的元素本身

  • btn.onclick = function() {console.log(this); // btn }

    三、面向?qū)ο笾杏嘘P(guān)私有/公有方法中的THIS問(wèn)題

    總結(jié)下來(lái)this在面向?qū)ο笾?#xff0c;主要還是看誰(shuí)執(zhí)行的,也就是執(zhí)行函數(shù)點(diǎn)前是誰(shuí)

  • 方法執(zhí)行,看前面是否有點(diǎn),點(diǎn)前面是誰(shuí)this就是誰(shuí)
  • 把方法總的this進(jìn)行替換
  • 在基于原型鏈查找的方法確定結(jié)果即可
  • 四、改變this指向:call/apply/bind

    每一個(gè)函數(shù)(普通函數(shù)/構(gòu)造函數(shù)/內(nèi)置類(lèi))都是Function這個(gè)內(nèi)置類(lèi)的實(shí)例,所以函數(shù).__proto__ === Function.prototype,函數(shù)可以直接調(diào)取Function原型上的方法

    • call / apply / bind
    • 原型上提供的三個(gè)公有屬性方法
    • 每一個(gè)函數(shù)都可以調(diào)用這個(gè)方法執(zhí)行
    • 這些方法都是用來(lái)改變函數(shù)中的this指向的
  • call
  • 函數(shù)基于原型鏈扎找到Function.prototype.call這個(gè)方法,并且把它執(zhí)行,在call方法執(zhí)行的時(shí)候改變里面的this關(guān)鍵字

    • 讓當(dāng)前的函數(shù)執(zhí)行
    • 把函數(shù)中的this指向改為第一個(gè)傳遞給call的實(shí)參
    • 把傳遞給call其余的實(shí)參,當(dāng)做參數(shù)信息傳遞給當(dāng)前函數(shù)

    注意

    • 如果執(zhí)行call一個(gè)實(shí)參都沒(méi)有傳遞,非嚴(yán)格模式下是讓函數(shù)中的this指向window,嚴(yán)格模式下指向的是undefined
    • fn.call(null);
    • //=> this.window
    • 嚴(yán)格下是this(第一個(gè)參數(shù)傳遞的是null/undefined/不傳,非嚴(yán)格模式下this指向window,嚴(yán)格模式下傳遞的是誰(shuí)this就是誰(shuí),不傳this是undefined)

    使用方法

    window.name = 'WINDOW'; let obj = {name: 'OBJ'}; function fn(n, m) {console.log(this.name); } fn(10, 20); // WINDOW --> 因?yàn)楹瘮?shù)剛開(kāi)始指向window fn.call(obj); // OBJ --> 改變函數(shù)this指向,此時(shí)函數(shù)fn指向obj fn.call(obj, 10, 20); // OBJ fn.call(10, 20); // undefined

    可以得出:

    • 一個(gè) call 是讓左邊函數(shù)之后執(zhí)行(this是傳遞的參數(shù))
    • 多個(gè) call 是讓最后傳參的函數(shù)執(zhí)行(this是window/undefined)

    2、apply

    和call方法一樣,都是把函數(shù)執(zhí)行,并且改變里面的this關(guān)鍵字,唯一的區(qū)別就是傳遞給函數(shù)參數(shù)的方式不一樣

    • call是一個(gè)個(gè)傳參
    • apply是按照數(shù)組傳參
    let obj = {name: 'OBJ'}; let fn = function(n, m) { console.log(this.name); // } //=>讓fn方法執(zhí)行,讓方法中的this變?yōu)閛bj,并傳遞1, 2給函數(shù) fn.call(obj, 1, 2); fn.apply(obj, [1, 2]);

    3、bind

    和call/apply一樣,也是用來(lái)改變函數(shù)中的this關(guān)鍵字,只不過(guò)基于bind改變this,當(dāng)前方法并沒(méi)有被執(zhí)行,類(lèi)似于預(yù)先改變this

    • bind是預(yù)處理this,他并不會(huì)讓函數(shù)執(zhí)行
    • bind方法的返回值是一個(gè)改變this之后的新函數(shù)

    作用

    • 把函數(shù)中的this指向通過(guò)預(yù)處理的方式改為第一個(gè)傳遞給bind的實(shí)參

    • 一般使用在綁定點(diǎn)擊事件,不讓函數(shù)立即執(zhí)行

    let obj = {name: 'mary'}; function fn() {console.log(this.name); } btn.onclick = fn; // this --> btn// 想讓this指向obj??? btn.onclick = fn.call(obj); // 這樣也不行,call/apply只是把執(zhí)行的結(jié)果返回給點(diǎn)擊事件 btn.onclick = fn.bind(obj); // this --> obj// 如果非要用call/apply btn.onclick = function() {return fn.call(obj); // 把函數(shù)返回給點(diǎn)擊事件才可以 }

    注意

    • 在IE6~8中不支持 bind 方法
    • 預(yù)先做啥事情的思想被稱(chēng)為“柯理化函數(shù)”

    優(yōu)點(diǎn)

    • bind的好處是:通過(guò)bind方法只是預(yù)先把fn中的this修改為obj,此時(shí)fn并沒(méi)有執(zhí)行,當(dāng)點(diǎn)擊事件觸發(fā)才會(huì)執(zhí)行fn(call/apply都是通過(guò)改變this的同時(shí)立即把方法執(zhí)行)

    總結(jié)

    以上是生活随笔為你收集整理的js 里面令人头疼的 this的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。