欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中的this指向綁定規(guī)則及常見面試總結(jié)

 更新時間:2023年12月15日 09:24:58   作者:歸思君  
這篇文章主要為大家介紹了JavaScript中的this指向綁定規(guī)則及箭頭韓碩中的this指向,還b包含了常見面試總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

一、引言

this可以說是前端開發(fā)中比較常見的一個關(guān)鍵字,由于其指向是在運行時才確定,所以大家在開發(fā)中判斷其方向時也會很模糊,今天就把this的指向問題拆開了,揉碎了,好好講一講。

先來看一個場景,看看該處的 this 應(yīng)該指向哪:首先在 request.js 中定義一個 getAction 函數(shù)

export function getAction(url,parameter) {
  let headers = {}
  if (this && this.realReferer && this.realReferer !== '') {
    headers.realReferer = window.location.origin + this.realReferer
  }
  return axios({
    url: url,
    method: 'get',
    params: parameter,
    headers
  });
}

然后在 test.vue 文件中引用該 getAction函數(shù)并使用

import { getAction } from '@api/request'
export default {
  methods: {
    getTableData() {
      getAction(this.url.requestUrl).then(res => {
        //1.這個時候getAction中的this將打印出什么
        //2.在該處打印this,會輸出什么
        console.log(this);
      })
    },
  }
}

現(xiàn)在有兩個問題:

  • 在 test.vue中調(diào)用 getAction()時,此時其內(nèi)部,也就是request.js 中的 this 指向什么?
  • 在 getAction() then 后的箭頭函數(shù)中的 this 指向什么?

思考一下能判斷出這兩個this的指向嗎?先賣個管子,等咱們再講完this的相關(guān)原理后再來解答這兩個問題。這篇文章會從這幾個方面講解:

  • 什么是this,this和執(zhí)行上下文的關(guān)系
  • this中的默認、隱式、顯式和new的綁定規(guī)則

箭頭函數(shù)中的this指向問題

二、什么是this?

this 其實就是一個JavaScript語言中的一個關(guān)鍵字,  它的值是某個對象引用值,其指代的是當前執(zhí)行上下文中的對象。那么為何需要this?我們先來看看一個例子:

var testObj = {
  name: "testObj",
  print: function () {
      console.log(name)
  }
} 
var name = "global name";
//想通過調(diào)用print()來調(diào)用testObj中的name
testObj.print();//global name

從結(jié)果可知,最后print() 輸出"global name", 而不是 testObj 中的 name。為何出現(xiàn)這種情況?
這是因為 JavaScript 語言的作用域鏈是由詞法作用域決定的,而詞法作用域是由代碼結(jié)構(gòu)來確定的:

  • 當 testObj.print()執(zhí)行時,這段代碼的詞法作用域是全局作用域,所以這個時候 js 引擎會去全局作用域中尋找 name,最后打印出“global name”。

因此為了避免這種情況,JavaScript 設(shè)計者引入了 this 機制,來調(diào)用對象的內(nèi)部屬性,如下代碼:

var testObj = {
  name: "testObj",
  print: function () {
      console.log(this.name)
  }
} 
var name = "global name";
testObj.print();//testObj

最后就能夠通過testObj.print() 來調(diào)用對象內(nèi)部的屬性了。
不同于詞法作用域鏈,this的指向是在運行時才能確定,實際上當執(zhí)行上下文創(chuàng)建后,會生成一個this引用值,指向當前執(zhí)行上下文對象,如下圖所示:

而 js 引擎在執(zhí)行代碼時的運行時上下文主要有三種:全局執(zhí)行上下文、函數(shù)執(zhí)行上下文和 eval 執(zhí)行上下文。不同場景的this指向如下:

//全局執(zhí)行上下文,當前對象是window
console.log(this);//window
//函數(shù)執(zhí)行上下文外部對象是全局對象,所以指向全局對象window
function test(){
console.log(this);//window
}
//函數(shù)執(zhí)行上下文外部對象是test,因此指向當前的對象test
var test = {
test: function(){
  console.log(this);//test{...}對象
}
}
//eval執(zhí)行上下文,根據(jù)默認綁定規(guī)則,指向全局對象window
eval(`console.log(this); `) //window

正是因為this在運行中才得以確定其指向的上下文對象,所以為了規(guī)范和標準化this的指向方式,規(guī)定了一系列的綁定規(guī)則,來決定什么情況下this會綁定到哪個對象。下面就來聊聊this的綁定規(guī)則

三、this 綁定規(guī)則

this的綁定大致可以劃分為默認、隱式、顯式和new四種場景下的綁定規(guī)則:

1. 默認綁定

當函數(shù)被獨立調(diào)用時,會將this綁定到全局對象。瀏覽器環(huán)境下是window, 嚴格模式是undefined主要有以下幾種場景:

//1. 定義在全局對象下的函數(shù)被獨立調(diào)用
function test(){
  console.log("global:", this);
}
test();//window
//2. 定義在某個對象下的函數(shù)被獨立調(diào)用
var testObj = {
test: function(){
  console.log("testObj:", this);
}
}
var testfun = testObj.test;
testfun();//window
//3. 定義在某個函數(shù)下的函數(shù)被獨立調(diào)用
function testFun(fn){
  fn();
}
testFun(testObj.test); //window

2. 隱式綁定

當函數(shù)作為對象的方法被調(diào)用時,隱式綁定規(guī)則會將this綁定到調(diào)用該方法的對象,也就是"誰調(diào)用,就指向誰"。

const obj = {
name: 'innerObj',
fn:function(){
  return this.name;
}
}
//調(diào)用者是obj, this指向obj
console.log(obj.fn());//innerObj

const obj2 = {
name: 'innerObj2',
fn: function() {
  return obj.fn(); //此時是obj調(diào)用fn,所以此時this指向obj
}
}
//調(diào)用者是obj, this指向obj
console.log(obj2.fn())//innerObj

現(xiàn)在我們可以回答引言中的問題1:在request.js 的getAction() 中this指向test.vue 中的全局vue對象,因為import {getAction} from '@api/request' 后,相當于vue對象調(diào)用了getAction(),因此其內(nèi)部的this方向符合隱式綁定規(guī)則,所以指向調(diào)用者——test.vue 中的全局vue對象

3. 顯式綁定

顯式綁定主要指通過call、apply和bind方法可以顯式地綁定this的值:

call 方法

語法: function.call(thisArg, arg1, arg2, ...) :

參數(shù): thisArg 表示 this 指向的上下文對象, arg1...argn  表示一系列參數(shù)

功能:  無返回值立即調(diào)用 function 函數(shù)

var test = {
}
function test2(){
  console.log(this);
}
//此時是獨立函數(shù),因此指向全局對象
test2();//window
//call顯式綁定,將函數(shù)內(nèi)部的this綁定至call中指定的引用對象
test2.call(test);//test

apply 方法

語法: function.apply(thisArg, [argsArray]) :

參數(shù): thisArg 表示 this 指向的上下文對象, argsArray  表示參數(shù)數(shù)組

功能: 沒有返回值, 立即調(diào)用函數(shù)

apply 和 call 的區(qū)別在于傳參,call 傳的是一系列參數(shù),apply 傳的是參數(shù)數(shù)組

var test = {
}
function test2(name){
  console.log(this);
  console.log(name);
}
//此時是獨立函數(shù),因此指向全局對象
test2();//window
//call顯式綁定,將函數(shù)內(nèi)部的this綁定至call中指定的引用對象
test2.apply(test, ["name"]);//test, name
test2.call(test, "name"); //test

bind 方法

語法:function.bind(thisArg[, arg1[, arg2[, ...]]])

參數(shù): thisArg 表示 this 指向的上下文對象; arg1, arg2, ...表示 要傳遞給函數(shù)的參數(shù)。這些參數(shù)將按照順序傳遞給函數(shù),并在調(diào)用函數(shù)時作為函數(shù)參數(shù)使用

功能: 返回原函數(shù) function 的拷貝, 這個拷貝的 this 指向 thisArg

var test = {
  fun: function(){
      console.log(this);
      var test = function(){
          console.log("test", this);
      }
      //1. 因為test.fun()在全局作用域中,所以屬于獨立函數(shù)調(diào)用,默認綁定規(guī)則指向全局對象
      test(); //window
      //2. bind方法會創(chuàng)建一個原函數(shù)的拷貝,并將拷貝中的this指向bind參數(shù)中的上下文對象
      var test2 = test.bind(this);
      test2();//test
      //3. apply方法會將this指向參數(shù)中的上下文,并立即執(zhí)行函數(shù)
      test.apply(this);//test
      
  }
}
test.fun();

4. new 綁定

主要是在使用構(gòu)造函數(shù)創(chuàng)建對象時,new 綁定規(guī)則會將 this 綁定到新創(chuàng)建的實例對象,因此構(gòu)造函數(shù)中用 this 指向的屬性值和參數(shù)也會被賦給實例對象:

function funtest(){
  this.name = "funtest"
}
var tete = new funtest();
console.log(tete.name); //"funtest"

new 操作符實際上的操作步驟:

  • 創(chuàng)建一個新的對象 {}
  • 將構(gòu)造函數(shù)中的 this 指向這個新創(chuàng)建的對象
  • 為這個新對象添加屬性、方法等
  • 返回這個新對象

等價于如下代碼:

var obj = {}
obj._proto_ = funtest.prototype
funtest.call(obj)

5. 綁定規(guī)則的優(yōu)先級

上述的綁定規(guī)則有時會一起出現(xiàn),因此需要判斷不同規(guī)則之間的優(yōu)先級,然后再來確定其 this 指向:
a. 首先是默認綁定和隱式綁定,執(zhí)行以下代碼:

function testFun(){
    console.log(this);
}
var testobj = {
    name:"testobj",
    fun:testFun
}
//若輸出window,則證明優(yōu)先級默認綁定大于隱式綁定;
//若輸出testobj,則證明優(yōu)先級隱式綁定大于默認綁定;
testobj.fun()//testobj

輸出為 testobj 對象,所以隱式綁定的優(yōu)先級高于默認綁定b. 下面來看一下隱式綁定和顯式綁定,執(zhí)行以下代碼:

function testFun(){
    console.log(this);
}
var testobj = {
    name:"testobj",
    fun:testFun
}
//若輸出testobj,則證明優(yōu)先級隱式綁定大于顯式綁定
//若輸出{}, 則證明優(yōu)先級顯式綁定大于隱式綁定
testobj.fun.call({})//{}

結(jié)果輸出 { },說明顯式綁定優(yōu)先級大于隱式綁定c. 顯式綁定的 call, apply,bind 的優(yōu)先級相同,與先后順序有關(guān),看以下代碼:

function testFun(){
    console.log(this);
}
var testobj = {
    name:"testobj",
    fun:testFun
}
//若輸出testobj,則證明優(yōu)先級隱式綁定大于顯式綁定
//若輸出{}, 則證明優(yōu)先級顯式綁定大于隱式綁定
testobj.fun.call({})//{}
testobj.fun.call(testobj)

d. 最后來看看顯式綁定和 new 綁定的優(yōu)先級,執(zhí)行以下代碼:

function testFun(){
    console.log(this.name);
}
var testobj = {
    name:"testobj",
}
testFun.call(testobj);//testobj
//new 操作符創(chuàng)建了一個新的對象,并將this重新指向新對象
//覆蓋了testFun原來綁定的testobj對象
var instance = new testFun();
console.log(instance.name) //undefined

從結(jié)果可知,new 綁定的優(yōu)先級大于顯式綁定

最后總結(jié)一下 this 綁定的 優(yōu)先級是:

fn()(全局環(huán)境)(默認綁定)< obj.fn()(隱式綁定) < fn.call(obj)=fn.apply(obj) = fn.bind(obj)(顯式綁定)< new fn()

6. 綁定的丟失

有時 this 綁定可能會在某些情況下丟失,導(dǎo)致 this 值的指向變得不確定:

賦值給變量后調(diào)用

當使用一個變量作為函數(shù)的引用值,并使用變量名執(zhí)行函數(shù)時,會發(fā)生綁定丟失,此時 this 會默認綁定到全局對象或變成 undefined(嚴格模式下)

var lostObj = {
  name: "lostObj",
  fun: function(){
    console.log(this);
    }
}
var lostfun = lostObj.fun;
lostfun();//window
lostObj.fun();//lostObj

從結(jié)果發(fā)現(xiàn),lostfun 雖然指向?qū)ο笾械姆椒?,但是在調(diào)用時發(fā)生了 this 綁定丟失。因為當賦值給變量時,對象中的 fun就失去了與對象的關(guān)聯(lián),變成了一個獨立函數(shù),所以此時執(zhí)行 lostfun也就相當于執(zhí)行獨立函數(shù),默認綁定到全局對象。
那如果通過對象來執(zhí)行呢?看如下代碼:

var lostObj = {
  name: "lostObj",
  fun: function(){
    console.log(this);
    }
}
var lostObj2 = {
  name: "lostObj2",
  fun: lostObj.fun
}
var lostfun = lostObj.fun;
lostfun();//window
lostObj.fun();//lostObj
lostObj2.fun();//lostObj2

同樣,一旦將方法賦值給變量后,其內(nèi)部與對象的關(guān)聯(lián)就此丟失,默認綁定到全局對象。但是將變量放到對象中后,就與該對象進行關(guān)聯(lián)。所以該方法執(zhí)行后的 this 執(zhí)行了 lostObj2對象。

函數(shù)作為參數(shù)傳遞

將函數(shù)作為參數(shù)傳遞到新函數(shù)中,并在新函數(shù)中執(zhí)行該參數(shù)函數(shù):

var lostObj3 = {
  name: "lostObj3",
  fun: function(){
    console.log(this.name);
    }
}
var name = "global"
function doFun(fn){
  fn();
}
doFun(lostObj3.fun);//global

從結(jié)果可知,當函數(shù)作為參數(shù)傳遞后,其形參 fn 被賦值為 lostObj3.fun。實際上也相當于賦值給變量后調(diào)用這種情況,而且 doFun()作為獨立函數(shù)調(diào)用,所以其 this 也就指向全局對象了

回調(diào)函數(shù)

如果將對象方法作為回調(diào)函數(shù)傳遞給其他函數(shù),this 綁定也可能丟失

var lostObj4 = {
  name: 'lostObj4',
  fun: function() {
    setTimeout(function() {
      console.log(`Hello, ${this.name}!`);
    });
  }
};
lostObj4.fun(); // Hello, undefined!

因為 setTimeout 的回調(diào)函數(shù)最后會以普通函數(shù)的形式調(diào)用,所以其 this 指向的是全局對象,所以即便是 lostObj4調(diào)用 fun(),最后其內(nèi)部的 this 仍然會丟失。

嵌套函數(shù)

當某個函數(shù)是嵌套在另一個函數(shù)內(nèi)部的函數(shù)時,內(nèi)部函數(shù)中的 this 綁定會丟失,并且會綁定到全局對象或 undefined(嚴格模式下):

var lostObj5 = {
  name: 'lostObj5',
  fun: function() {
    function innerFun() {
      console.log(`Hello, ${this.name}!`);
    };
    innerFun();
  }
};
lostObj5.fun();// Hello, undefined!

從結(jié)果可以發(fā)現(xiàn),嵌套函數(shù) innerFun()中的 this 此時是指向全局環(huán)境。所以從這個案例可以說明作用域鏈和 this 沒有關(guān)系,作用域鏈不影響 this 的綁定。

原因是當innerFun()被調(diào)用時,是作為普通函數(shù)調(diào)用,不像 fun()屬于對象 lostObj5的內(nèi)部方法而調(diào)用,因此最后其內(nèi)部的 this 指向全局對象。

其實 this 丟失可以通過箭頭函數(shù)來解決,下面就來聊聊箭頭函數(shù)

四、箭頭函數(shù)中的 this

箭頭函數(shù)是 ES6 增加的一種編寫函數(shù)的方法,它用簡潔的方式來表達函數(shù)
語法:()=>{}
參數(shù):(): 函數(shù)的參數(shù),{}: 函數(shù)的執(zhí)行體

1. 箭頭函數(shù)中的 this 指向

箭頭函數(shù)中的this是在定義時確定的,它是繼承自外層詞法作用域。而不是在運行時才確定,如以下代碼:

var testObj2 = {
    name: "testObj2", 
    fun: function(){
        setTimeout(()=>{
            console.log(this);
        })
    }
}
var testObj3 = {
    name: "testObj3", 
    fun: function(){
        setTimeout(function(){
            console.log(this);
        })
    }
}
//即使獨立調(diào)用函數(shù),箭頭函數(shù)內(nèi)的this指向是在定義時就已經(jīng)確定
testObj2.fun();//testObj
testObj3.fun();//window

實際上箭頭函數(shù)中沒有 this 綁定,它是繼承自外層作用域的 this 值。因此在許多情況下,箭頭函數(shù)能解決 this 在運行時函數(shù)的綁定問題。

2. 箭頭函數(shù)與普通函數(shù)中的 this 差異

從 上面的例子可以看出箭頭函數(shù)和普通函數(shù)在 this 的處理上存在很大的差異,主要有:

this 綁定方式

普通函數(shù)的 this 是在運行時確定的;箭頭函數(shù)的 this 值是函數(shù)定義好后就已經(jīng)確定,它繼承自包含箭頭函數(shù)的外層作用域

作用域

普通函數(shù)是具有動態(tài)作用域,其 this 值在運行時基于函數(shù)的調(diào)用方式動態(tài)確定。箭頭函數(shù)具有詞法作用域,其 this 值在定義時就已經(jīng)確定,并繼承外部作用域

綁定 this 的對象

普通函數(shù)中 this 可以通過函數(shù)的調(diào)用方式(如對象方法、構(gòu)造函數(shù)、函數(shù)調(diào)用等)來綁定到不同的對象,而箭頭函數(shù)沒有自己的 this 綁定;箭頭函數(shù)沒有自己的 this 綁定,它只能繼承外部作用域的 this 值,無法在運行時改變綁定對象,而且也無法通過顯式綁定來改變 this 的指向。

var testObj4 = {
  arrowFun: ()=>{
    console.log(this);
  },
  normalFun: function(){
    console.log(this);
  }
}
//此時箭頭函數(shù)的this繼承全局上下文的this,顯式綁定無法修改箭頭函數(shù)中的this值
testObj4.arrowFun();//window
testObj4.arrowFun.apply({});//window
testObj4.normalFun();//testObj4
testObj4.normalFun.apply({});//{}

下面我們就可以解答引言中的問題 2 了。箭頭函數(shù)中的 this 指向其上層的作用域,也就是 getAction() 中的 this 值,而從隱式綁定調(diào)用規(guī)則,當前是 vue 實例調(diào)用 getTableData()然后再調(diào)用 getAction(),因此 this 值指向當前 vue 實例。

五、 this 中的面試題

手寫實現(xiàn)一個 bind 函數(shù)

通過分析 bind 函數(shù)的語法和參數(shù)來:function.bind(thisArg[, arg1[, arg2[, ...]]])

  • 返回值是一個函數(shù)
  • 參數(shù) thisArg 指向

我們暫時不考慮原型問題,實現(xiàn)如下代碼:

Function.prototype.mybind = function (thisArg) {
  //1.隱式綁定,當前的this指向目標函數(shù)
  var targetFn = this;
  //將參數(shù)列表轉(zhuǎn)換為數(shù)組,并刪除第一個參數(shù)
  var args = Array.prototype.slice.call(arguments, 1);
  //2.返回值一個函數(shù)
  return function bound() {
     var innerArgs = Array.prototype.slice.call(arguments);
     var finalArgs = args.concat(innerArgs);
    //解決返回函數(shù)使用new后,綁定this忽略問題
     var _this = targetFn instanceof this ? this: thisArg;
     return targetFn.apply(thisArg, finalArgs)
   }
 }
}

總結(jié)

文章回顧 this 的概念和 this 指向的判斷綁定規(guī)則,

  • 首先是綁定規(guī)則:
  • 獨立函數(shù)調(diào)用執(zhí)行時,使用默認綁定規(guī)則,this 指向 window
  • 當函數(shù)作為對象方法被調(diào)用,使用隱式綁定規(guī)則,this 指向這個對象
  • 當函數(shù)作為構(gòu)造方法時,使用 new 綁定規(guī)則,this 指向返回的對象
  • apply/call/bind 要注意參數(shù)的傳遞和返回值不同
  • 箭頭函數(shù)要看該箭頭函數(shù)在哪個作用域下,this 就指向誰

綁定規(guī)則的優(yōu)先級:

fn()(全局環(huán)境)(默認綁定)< obj.fn()(隱式綁定) < fn.call(obj)=fn.apply(obj) = fn.bind(obj)(顯式綁定)< new fn()

  • 此外要注意綁定失效的情況,善用箭頭函數(shù)來保證 this 的指向穩(wěn)定

以上就是JavaScript中的this指向綁定規(guī)則及常見面試總結(jié)的詳細內(nèi)容,更多關(guān)于JavaScript this指向的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 限制textbox或textarea輸入字符長度的JS代碼

    限制textbox或textarea輸入字符長度的JS代碼

    textbox或textarea的輸入字符限制有很多方法,在本將為大家詳細介紹下js中時如何實現(xiàn)的,感興趣的朋友不要錯過
    2013-10-10
  • 原生js實現(xiàn)移動端觸摸輪播的示例代碼

    原生js實現(xiàn)移動端觸摸輪播的示例代碼

    下面小編就為大家分享一篇原生js實現(xiàn)移動端觸摸輪播的示例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • JavaScript實現(xiàn)簡易的天數(shù)計算器實例【附demo源碼下載】

    JavaScript實現(xiàn)簡易的天數(shù)計算器實例【附demo源碼下載】

    這篇文章主要介紹了JavaScript實現(xiàn)簡易的天數(shù)計算器,結(jié)合實例形式分析了javascript日期與時間計算的相關(guān)技巧,并附帶demo源碼供讀者下載參考,需要的朋友可以參考下
    2017-01-01
  • Javascript 事件流和事件綁定

    Javascript 事件流和事件綁定

    本文中的部分觀點參考至《Javascript高級程序設(shè)計》(很好的一本書,推薦大家看看?。?,addEvent函數(shù)借鑒了YUI2.7的_addListener方法,這里也要謝謝YUI那些牛人,向他們致敬!
    2009-07-07
  • 微信小程序websocket實現(xiàn)聊天功能

    微信小程序websocket實現(xiàn)聊天功能

    這篇文章主要為大家詳細介紹了微信小程序websocket實現(xiàn)聊天功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • 完美實現(xiàn)js拖拽效果 return false用法詳解

    完美實現(xiàn)js拖拽效果 return false用法詳解

    這篇文章主要為大家詳細介紹了完美實現(xiàn)js拖拽效果的代碼,一起學(xué)習return false的用法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 基于javascript處理nginx請求過程詳解

    基于javascript處理nginx請求過程詳解

    這篇文章主要介紹了基于javascript處理nginx請求過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2020-07-07
  • javascript獲取鼠標位置部分的實例代碼(兼容IE,FF)

    javascript獲取鼠標位置部分的實例代碼(兼容IE,FF)

    這篇文章介紹了javascript獲取鼠標位置部分的實例代碼,有需要的朋友可以參考一下
    2013-08-08
  • JavaScript中的document.querySelector()方法使用詳解

    JavaScript中的document.querySelector()方法使用詳解

    HTML的DOM querySelector()方法可以不需要額外的jQuery等支持,也可以方便的獲取DOM元素,語法跟jQuery類似,這篇文章主要給大家介紹了關(guān)于JavaScript中document.querySelector()方法使用的相關(guān)資料,需要的朋友可以參考下
    2024-06-06
  • JS使用可選鏈操作符 (?.) 進行空值檢查的操作

    JS使用可選鏈操作符 (?.) 進行空值檢查的操作

    在 JavaScript 中,處理嵌套對象或數(shù)組時,經(jīng)常會遇到空值檢查的問題,傳統(tǒng)的空值檢查通常比較繁瑣,容易導(dǎo)致代碼冗長且難以閱讀,ES2020 引入了可選鏈操作符 (?.),極大地簡化了這些檢查過程,本文介紹了JS使用可選鏈操作符 (?.) 進行空值檢查的操作
    2024-12-12

最新評論