前端入門8-JavaScript語法之數據類型和變數

来源:https://www.cnblogs.com/dasusu/archive/2018/12/02/10052903.html
-Advertisement-
Play Games

聲明 本系列文章內容全部梳理自以下幾個來源: 《JavaScript權威指南》 "MDN web docs" "Github:smyhvae/web" "Github:goddyZhao/Translation/JavaScript" 作為一個前端小白,入門跟著這幾個來源學習,感謝作者的分享,在其基 ...


聲明

本系列文章內容全部梳理自以下幾個來源:

作為一個前端小白,入門跟著這幾個來源學習,感謝作者的分享,在其基礎上,通過自己的理解,梳理出的知識點,或許有遺漏,或許有些理解是錯誤的,如有發現,歡迎指點下。

PS:梳理的內容以《JavaScript權威指南》這本書中的內容為主,因此接下去跟 JavaScript 語法相關的系列文章基本只介紹 ES5 標準規範的內容、ES6 等這系列梳理完再單獨來講講。

正文-數據類型、變數

JavaScript 里有兩種數據類型:原始類型和對象類型

原始類型

原始類型里包括:

  • 數字(Number)
  • 布爾(Boolean)
  • 字元串(String)
  • null
  • undefined

布爾類型和字元串類型跟 Java 沒多大區別,主要就講一下數字類型、null 和 undefined。

數字

JavaScript 里不像 Java 一樣會區分 int,float,long 等之類的數字類型,全部都歸屬於一個 Number 數字類型中。之所以不加區分,是因為,在 JavaScript 里,所有的數字,不管整數還是小數,都用浮點數來表示,採用的是 IEEE 754標准定義的 64 位浮點格式表示數字。

那麼,它所能表示的數值範圍就是有限的,除了正常數值外,還有一些關鍵字表示特殊場景:

  • Infinity(正無窮)
  • -Infinity(負無窮)
  • NaN(非數值)

對於小數,支持的浮動小數表示法如下:

3.14      
-.2345789 // -0.23456789
-3.12e+12  // -3.12*1012
.1e-23    // 0.1*10-23=10-24=1e-24

另外,因為浮點表示法只能精確的表示如:1/2, 1/8, 1/1024 這類分數,對於 1/10 這種小數只能取近視值表示,因此在 JavaScript 里有個經典的有趣現象:

浮點精度缺失

0.1 + 0.2 在 JavaScript 里是不等於 0.3 的,因為用浮點表示法,無法精確表示 0.1 和 0.2,所以會捨棄一些精度,兩個近似值相加,計算結果跟實際算術運算結果自然有些偏差。

上圖裡也顯示了,在 JavaScript 里,0.1 + 0.2 的運算結果是 0.30000000000000004。

那麼,是否所有非 1/2, 1/4, 1/8 這類 1/2^n 小數的相加結果最後都不會等於實際運算結果呢?

浮點精度缺失

0.1, 0.2, 0.3 都是浮點數無法精確表示的數值,所以在 JavaScript 里都是以近似值存儲在記憶體中,那麼,為何 0.1 + 0.2 != 0.3,但 0.1 + 0.3 == 0.4

這是因為,JavaScript 里在處理這類小數時,允許一定程度的誤差,比如 0.10000000000000001 在允許的誤差中,所以在 JavaScript 里就將這個值當做 0.1 來看待處理。

所以如果兩個是以近似值存儲的小數運算之後的結果,在誤差允許範圍內,那麼計算結果會按實際算術運算結果來呈現。

總之,不要用 JavaScript 來計算一些小數計算且有精度要求,如果非要不可,那麼建議先將小數都按比例擴展到整數運算後,再按比例縮小,如:

浮點精度缺失3

還有另外一點,由於 JavaScript 的變數是不區分類型的,那麼當有需要區分某個變數是不是數字時,可用內置的全局函數來處理:

  • isNaN() -- 如果參數是 NaN 或者非數字值(如字元串或對象),返回 true
  • isFinite() -- 如果參數不是 NaN,或 Infinity 或 -Infinity 時返回 true,通俗理解,參數是正常的數字

null

跟 Java 一樣,JavaScript 里也有 null 關鍵字,但它的含義和用法卻跟 Java 里的 null 不太一樣。

在 Java 里,聲明一個對象類型的變數後,如果沒有對該變數進行賦值操作,預設值為 null,所以在程式中經常需要對變數進行判空處理,這是 Java 里 null 的場景。

但在 JavaScript 中,聲明一個變數卻沒有進行賦值操作的話,預設值不是 null,而是 undefined。

那麼,什麼場景下,變數的值會是 null 呢?我可以告訴你,沒有,沒有任何場景下某個變數或某個屬性的值預設會是 null,除非你在程式中手動將某個變數賦值為 null,那麼此時這個變數的值才會是 null。

所以,才有些書本中會說,null 是表示程式級、正常的或在意料之中的值的空缺。意思就是說,null 是 JavaScript 設計出來的一個表示空值含義的數據類型,用來給你在程式中當有需要給某個變數手動設置為空值的場景時使用。

舉個通俗的例子,對於數字類型變數,你可以用 0 表示它的初始值;對於字元串類型變數,你可以用 "" 表示它的初始值;那麼對於對象類型,當你也需要給它一個表示空值無具體含義的初始值時,你就可以給它賦值為 null。

這也是為什麼用 typeof 運算符獲取 null 的數據類型時,會發現輸出的是 Object。因為 null 實際上是個實際存在的數據值,只是它的含義是空值的意思,用於賦值給對象類型的變數。

那麼,也就是說,不能沿用 Java 里使用 null 的思維應用到 JavaScript 中了,null 可以作為初始值賦值給變數,但變數如果沒有進行初始化,預設值不再是 null 了,這點是 JavaScript 有區別於 Java 的地方,需要註意一下。

不然再繼續挪用 Java 的使用 null 思維,可能在編程中,會遇到一些意料外,沒想通的問題。

undefined

如果聲明瞭一個變數,缺沒有對這個變數進行賦值操作,那麼這個值預設就是 undefined。

那麼在 Java 中的判空操作來判斷變數是否有進行初始化的行為在這裡就是對應判斷變數的值是否為 undefined 的,但實際上,在 JavaScript 里,由於 if 判斷語句接收的為真值,而不像 Java 只支持布爾類型,所以基本沒有類似 Java 的判空的編程場景。

undefined 還有另外一種場景:

當訪問對象中不存在的屬性時,此時會輸出 undefined,表示這個屬性並未在對象中定義。

針對這種場景,undefined 可用於判斷對象中是否含有某些指定的屬性。

總結一下 null 和 undefined:

  • null 是用於在程式中,如果有場景需要,如某個變數在某種條件下需要有一個表示為空值含義的取值,此時,可手動為該變數賦值為 null;
  • 當聲明某個變數,卻沒有對其進行賦值初始化操作時,這個變數預設為 undefined
  • 當訪問對象某個不存在的屬性時,會輸出 undefined,可用於判斷對象中是否含有指定屬性

對象類型

除了原始類型外,其餘都是對象類型,但有一些內置的對象類型,所以大概可以這麼表示

  • 對象類型(Object)
    • 函數(Function)
    • 數組(Array)
    • 日期(Date)
    • 正則(RegExp)
    • ...

也就是,在 JavaScript 里,函數和數組,本質上也是對象。

變數相關

由於我本身有 Java 的基礎了,所以 JavaScript 一些很基礎的語法我可能會漏掉了,但影響不大。

弱類型

雖然 JavaScript 中有原始類型和對象類型,而且每個分類下又有很多細分的數據類型,但它實際上是一門弱類型語言,也叫動態語言。也就是說,使用變數時,無需指明變數是何種類型,運行期間會自動確定。

變數聲明

既然使用變數時不必指明變數的數據類型,那麼自然沒有類似於 Java 中那麼多種的變數聲明方式,在 JavaScript 中聲明變數很簡單,都是通過 var 來:

var name = dasu;

ES5 中,聲明變數的方式就是通過 var 關鍵字,而且同一變數重覆聲明不會出問題,會以後面聲明的為主。

變數的提前聲明

先看段代碼:

<script type="text/javascript">
    console.log(a);  //輸出 undefined
    var a = 1;
    console.log(a);  //輸出 1
    b();
    function b() {
        console.log(a); //輸出 undefined
        var a = 2;
        console.log(a); //輸出 2
    }   
</script>

JavaScript 中有變數的提前聲明特性,也就是在代碼開始執行前,所有通過 var 或 function 聲明的變數和函數都已經提前聲明瞭(下麵統稱變數),所以在聲明語句之前訪問聲明的這個變數並不會拋異常。

但提前的只有變數的聲明,變數的賦值初始化操作並沒有提前,所以第一行代碼輸出變數 a 的值時,因為變數已經被提前聲明瞭,但沒賦值,按照上面介紹的,此時變數 a 值為 undefined,當賦值語句執行完,輸出自然就是賦值的 1 了。

同樣,由於 b 函數已經被提前聲明瞭,所以可以在聲明它的位置之前就調用函數了,而函數調用後,開始執行函數內的代碼時,也同樣會有變數提前聲明的特性。

因此,在執行函數內第一行代碼時,輸出的變數 a 是函數內聲明的局部變數,而不是函數外部的變數,這點行為跟 Java 不一樣,需要註意一下。

有些腳本語言並沒有變數聲明提前的特性,使用的變數或函數只能在聲明瞭它的位置之後才能使用,這是 JavaScript 區別它們的一點。

全局屬性

上面說過,聲明變數時是通過 var 關鍵字聲明,那如果漏掉 var 呢,看個例子:

<script type="text/javascript">
    //console.log(a);  //拋異常,因為沒有找到a變數
    a = 1;
    b();
    function b() {
        console.log(a); //輸出 1
        a = 2;
        console.log(a); //輸出 2
    }
    console.log(a); //輸出 2
</script>

第一行代碼如果不註釋掉,那麼它執行的結果會是拋出一個異常,因為沒有找到 a 變數。

接著執行了 a = 1,a 是一個不存在的變數,直接對不存在的變數進行賦值語句,其實是會自動對全局對象 window 動態添加了一個 a 屬性並賦值,所以後續調用了 b 函數,函數里操作的 a 其實都是來自全局對象 window 的屬性 a,所以在函數內對 a 進行的操作結果,當函數執行結束後,最後再次輸出 a 才會是 2。

這其實是因為對象的特性導致的,在對象一節會來講講,但這裡要清楚一點,切記聲明使用變數時,不要忘記在前面要使用 var

另外,順便提一下,第一行被註釋掉的代碼,如果換成輸出 this.a,那麼此時程式是不會拋異常的,而是輸出 undefined,這是因為前面也有稍微提過,訪問對象不存在的屬性時,會輸出 undefined,都是在講對象時會來說說。

變數作用域

ES5 中,變數有兩種作用域,全局作用域和函數內作用域。

在函數外聲明的變數都具有全局作用域,即使跨 js 文件都能夠訪問;而在函數內聲明的變數,不管聲明變數的語句在哪個位置,整個函數內都可以訪問該變數,因為有變數的提前聲明特性,所以是函數內作用域。

由於在 JavaScript 中,同一變數的重覆聲明不會出問題,所以對於全局變數而言,在多人協作,多模塊編程中,很容易造成全局變數衝突,即我在我寫的 js 文件中聲明的 a 全局變數,其他人在其他 js 文件中,又聲明瞭 a 全局變數,對於瀏覽器而言,它就只是簡單的以後聲明的為主。

但對於程式而已,就會發生不可控的問題,而且極難排查,所以要慎用全局變數。當然針對這種情況也有很多解決方案,後續講到函數一節中會來講講。

包裝對象

JavaScript 里的對象具有很多特性,比如可以動態為其添加屬性等等。但原始類型都不具有對象的這些特性,那麼當需要對原始類型也使用類似對象的特性行為時,這時候包裝對象就出現了。

包裝對象跟 Java 中的包裝類基本是類似的概念,原始數據類似對應的對象類型的值稱為包裝對象:

  • 數字類型 -> Number 包裝對象
  • 布爾類型 -> Boolean 包裝對象
  • 字元串類型 -> String 包裝對象
  • null 和 undefined 沒有包裝對象,所以不允許對 null 和 undefined 的變數進行屬性操作

接下來就講講原始類型和包裝對象之間的轉換,存在兩種場景,程式運行期間自動轉換,或者手動顯示的進行轉換。

隱式轉換

因為屬性是對象才有的特性,所以當對某個原始類型的變數進行屬性操作時,此時會臨時創建一個包裝對象,屬性操作結束後銷毀包裝對象。

看個例子:

var s = "test";   //創建一個字元串,s是原始類型的變數
s.len = 4;   //對s動態添加一個屬性len並賦值,執行這行代碼時,會臨時創建一個包裝對象,所以這裡的s已經不是上面的原生類型變數,進行了一次自動轉換
console.log(s.len);  //輸出 undefined,上一行雖然進行了一次包裝對象的自動轉換,但是是臨時的,那一行代碼執行結束,包裝對象就銷毀了。所以這一行又對s原始類型變數進行屬性操作,又再一次創建一個臨時的包裝對象

需要註意一點,當對原始類型的操作進行屬性操作時,會創建一個臨時的包裝對象,註意是臨時的,屬性操作完畢,包裝對象就銷毀了。下一次再繼續對原始類型進行屬性操作時,創建的又是新的一個臨時包裝對象。

顯示轉換

除了隱式的自動轉換外,也可以顯示的手動轉換。

如果是原始類型 -> 包裝類型的轉換,可使用相對應的包裝對象的構造函數方式:

var a = new Number(123);
var b = new Boolean(true);
var s = new String("dasu");

此時,a, b, s 都是對象類型的變數了,可以對它們進行一些屬性操作。

如果是包裝類型 -> 原始類型的轉換,使用不加 new 的調用全局函數的方式:

var aa = Number(a);
var bb = Boolean(b);
var ss = String(s);

在後續講函數時會講到,一個函數被調用的方式有多種:其中,有跟 new 關鍵字一起使用,此時叫這個函數為構造函數;如果只是簡單的調用,此時叫函數調用;如果是作為對象的屬性被調用,此時稱方法調用;不同的調用方式會有一些區別。

所以,這裡當包裝對象使用構造函數方式使用時,可以顯示的將原始類型數據轉換為包裝對象;但如果不作為構造函數,只是簡單的函數調用,其實就是將傳入的參數轉換為原始類型,參數不單可以是包裝對象類型,也可以是其他類型。

數據類型間相互轉換

上面講了原始類型與包裝對象間的相互轉換,其實本質上也就是不同數據類型間的相互轉換。

按數據類型細分來講的話,一共包括:數字、布爾、字元串、null、undefined、對象(函數、數組等),由於 JavaScript 是弱類型語言,運行期間自動確定變數類型,所以,其實這些不同數據類型之間都存在相互轉換的規則。

先看個例子:

10 + " objects";    // => "10 objects",這裡的 10 自動轉換成 "10"
"7" * "4";          // => 28, 這裡的兩個字元串都自動轉換為數字
var n = 1 - "x";    // => NaN,字元串 "x" 無法轉換為數字
n + " objects";     // => "NaN objects", NaN 轉換為字元串 "NaN"

數字可以轉換成字元串,字元串也可以轉換為數字,原始類型也可以轉換為對象類型等等,反正不同類似之間都可以相互轉換。

基本轉換規則

具體的規則,可以參見下表:

待轉換值 轉換為字元串 轉換為數字 轉換為布爾值 轉換為對象
undefined "undefined" NaN false throws TypeError
null "null" 0 false throws TypeError
true(布爾->其他) "true" 1 -- new Boolean(true)
false(布爾->其他) "false" 0 -- new Boolean(false)
""(空字元串->其他) -- 0 false new String("")
"1.2"(字元串內容為數字->其他) -- 1.2 true new String("1.2")
"dasu"(字元串內容非數字->其他) -- NaN true new String("dasu")
0(數字->其他) "0" -- false new Number(0)
-0(數字->其他) "0" -- false new Number(-0)
1(數字->其他) "1" -- true new Number(1)
NaN "NaN" -- false new Number(NaN)
Infinity "Infinity" -- true new Number(Infinity)
-Infinity "-Infinity" -- true new Number(-Infinity)
{}(對象 -> 其他) 單獨講 單獨講 true --
[] (數組 -> 其他) "" 0 true --
[1] (一個數字元素的數值 -> 其他) "1" 1 true --
['a'] (普通數組 -> 其他) 使用join()方法 NaN true --
function(){} (函數 -> 其他) 單獨講 NaN true --

總之不同類型之間都可以相互轉換,除了 null 和 undefined 不能轉換為對象之外,其餘都可以。

那麼什麼時候會進行這些轉換呢?

其實在程式運行期間,就不斷的在隱式的進行著各種類型轉換,比如 if 語句中不是布爾類型時,比如算術表達式兩邊是不同類型時等等。

那麼,如何進行手動的顯示轉換呢?

在上一小節中,其實有稍微提過了,就是使用:

  • Number()
  • String()
  • Boolean()
  • Object()

註意是以函數調用方式使用,即不加 new 關鍵字的使用方式。參數傳入的值就是表示上表中第一列待轉換的值,而四種不同的函數,就對應著上表中右邊四列的轉換規則。如

Number("dasu")  // => NaN,表示待轉換值為字元串 "dasu",需要轉換為數字類型,按照上表規則,轉換結果NaN
String(true)    // => "true",同理,將布爾類型true轉為字元串類型
Boolean([])     // => true,將空數組轉為布爾類型
Object(3)       // => new Number(3),將數字類型轉為包裝對象

換句話說,這四個函數,其實就是用於將任意類型轉換為函數對應的類型,比如 Number() 函數就是用於將任意類型轉為數字類型,至於具體轉換規則,就是按照表中的規則來進行轉換。

一般來說,應該可以不用將表中所有的轉換規則都詳記,需要自己手動轉換的場景應該也不多,記住一些常用基本的就行了,至於哪些是常見的,寫多了就清楚了,比如數字類型 -> 布爾類型,對象類型 -> 布爾類型等。

對象轉換為原始值規則

所有的數據類型之間的轉換,就對象轉換到原始值的規則會複雜點,其餘的需要的時候,看一下表就行了。

  • 對象 -> 布爾

首先,所有的對象,不管的函數、數組還是普通對象,只要這個對象是定義後存在的,那麼它轉換為布爾值都是 true,所以對象轉布爾也很簡單。反正就記住,對象存在,那麼轉布爾就為 true。

所以,即使一個布爾值 false,先轉成包裝對象 new Boolean(false),再從包裝對象轉為布爾值,那麼此時,包裝對象轉布爾後是 true,因為包裝對象存在,就這麼簡單,不關心這個包裝對象原本是從布爾 false 轉來的。

  • 對象 -> 字元串

對象轉字元串,主要是需要藉助兩個方法:

  1. 如果對象具有 toString(),則調用這個方法,如果調用後返回了一個原始值,那麼就將這個原始值轉為字元串,轉換結束。
  2. 如果對象沒有 toString() 方法,或者調用該方法返回的並不是一個原始值,那麼調用對象的 valueOf() 方法,同樣,如果調用後返回一個原始值,那麼將原始值轉為字元串後,轉換結束。
  3. 否則,拋類型錯誤異常。

這就是對象轉字元串的規則,有些內置的對象,比如函數對象,或數組對象就可能會對這兩個方法進行重寫,對於自定義的對象,也可以重寫這兩個方法,來手動控制它轉成字元串的規則。

  • 對象 -> 數字

對象轉數字的規則,也是需要用到這兩個方法,只是它將步驟替換了下:

  1. 如果對象具有 valueOf() 方法,且調用後返回一個原始值,那麼將這個原始值轉為數字,轉換結束。
  2. 如果對象沒有 valueOf() 方法,或者調用後返回的不是原始值,那麼看對象是否具有 toSring() 方法,且調用它後返回一個原始值,那麼將原始值轉為數字,轉換結束。
  3. 否則,拋類型錯誤異常。

大家好,我是 dasu,歡迎關註我的公眾號(dasuAndroidTv),公眾號中有我的聯繫方式,歡迎有事沒事來嘮嗑一下,如果你覺得本篇內容有幫助到你,可以轉載但記得要關註,要標明原文哦,謝謝支持~
dasuAndroidTv2.png


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 什麼是作用域:瀏覽器給js的生存環境叫作用域。 什麼是變數提升: Js代碼執行前,瀏覽器會給一個全局作用域window Window分兩個模塊一個是存儲模塊一個是執行模塊 存儲模塊找到所有的var和function 關鍵字給這些變數添加記憶體地址 執行模塊,代碼從上到下執行,遇到變數就會去存儲模塊查找 ...
  • 1.事件 瀏覽器客戶端上客戶觸發的行為都稱為事件 所有的事件都是天生自帶的,不需要我們去綁定,只需要我們去觸發。 通過 obj.事件名=function(){} 事件名:onmouseover 滑鼠懸浮 onmouseout 滑鼠移除 onmousedown滑鼠按下 onmouseup 滑鼠抬起 o ...
  • 元素的屬性 div.attributes 是所有標簽屬性構成的數據集合 div.classList 是所有class名構成的數組集合 在classList的原型鏈上看以看到add()和remove() 1.client系列 (1) clientWidth/clientHeight 是我們設置的寬和高 ...
  • @[toc] .val()實例方法的三種用法 1. $('xxx').val() : 獲取匹配的元素集合中第一個元素的當前value屬性值(property) 2. $('xxx').val(value) : 設置匹配的元素集合中每個元素的value屬性值(property) 3. $('xxx') ...
  • 在列表展示中,經常會使用卡片的內容展示形式,為了美觀,常常要求各卡片間的間隙是一致的。 卡片內容不一樣可能高度不等,但一般來說為了整體的一致性,會限制每個卡片的寬高都相等。 本文就基於寬高一致的多個卡片,在不同屏幕大小下,每行卡片數量可能有調整,考量如何實現等間隙的佈局。 點我預覽 放置一張張卡片項 ...
  • 希望能自己獨立的寫出這個小冊。在博客園的第一篇博文,還是寫關於技術方面的,但願語言組織好點。 自己也不算是初級小白了,畢竟學習前端知識很長一段時間了。兩個月前也嘗試寫過一些封裝,但對封裝質量並不滿意,後來讀了一本書,叫《JavaScript設計模式與開發實踐》,從中受益很多。作者是我們國內的騰訊前端 ...
  • 首先,回顧下上篇博文中 "js基礎梳理 究竟什麼是執行上下文棧(執行棧),執行上下文(可執行代碼)?" 的執行上下文的生命周期: 3.執行上下文的生命周期 3.1 創建階段 生成變數對象(Variable object, VO) 建立作用域鏈(Scope chain) 確定this指向 3.2 執行 ...
  • 1.關於數據綁定的問題 小程式更新data後只是把數據的值更新,不會刷新頁面,比如滑動的列表不會回到頂部,導致使用swiper有個小bug: 就是swiper的數據是後臺請求的,可通過切換tab標簽動態獲取,如果在切換之前swiper處在第三張或者更多(比將要點擊的tab下的swiper多),那切換 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...