整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          32.Javascript循環(huán)結(jié)構(gòu)

          32.Javascript循環(huán)結(jié)構(gòu)

          編寫程序時(shí),我們經(jīng)常需要重復(fù)執(zhí)行某些操作,這時(shí)候循環(huán)結(jié)構(gòu)就顯得非常有用。JavaScript 提供了多種循環(huán)結(jié)構(gòu),以適應(yīng)不同的編程場景。以下是 JavaScript 中常見的循環(huán)結(jié)構(gòu):

          for 循環(huán)

          for 循環(huán)是最常見的循環(huán)結(jié)構(gòu)之一,它允許我們指定循環(huán)開始前的初始化代碼、循環(huán)繼續(xù)的條件以及每次循環(huán)結(jié)束時(shí)要執(zhí)行的代碼。

          基本語法

          for (初始化表達(dá)式; 循環(huán)條件; 循環(huán)后的操作表達(dá)式) {
              // 循環(huán)體代碼
          }
          

          示例:輸出 1 到 10 的數(shù)字

          for (var i=1; i <=10; i++) {
              console.log(i);
          }
          

          while 循環(huán)

          while 循環(huán)在給定條件為真時(shí)將不斷循環(huán)執(zhí)行代碼塊。與 for 循環(huán)不同,while 循環(huán)只有循環(huán)條件,沒有初始化和迭代表達(dá)式。

          基本語法

          while (條件) {
              // 循環(huán)體代碼
          }
          

          示例:使用 while 循環(huán)輸出 1 到 10 的數(shù)字

          var i=1;
          while (i <=10) {
              console.log(i);
              i++;
          }
          

          do...while 循環(huán)

          do...while 循環(huán)和 while 循環(huán)類似,但它至少會(huì)執(zhí)行一次循環(huán)體,無論條件是否為真。

          基本語法

          do {
              // 循環(huán)體代碼
          } while (條件);
          

          示例:使用 do...while 循環(huán)輸出 1 到 10 的數(shù)字

          var i=1;
          do {
              console.log(i);
              i++;
          } while (i <=10);
          

          for...in 循環(huán)

          for...in 循環(huán)用于遍歷對(duì)象的屬性。

          基本語法

          for (var key in 對(duì)象) {
              // 使用 key 訪問對(duì)象屬性
          }
          

          示例:遍歷對(duì)象的屬性

          var person={
              name: "張三",
              age: 30,
              job: "軟件工程師"
          };
          
          for (var key in person) {
              console.log(key + ": " + person[key]);
          }
          

          for...of 循環(huán)

          for...of 循環(huán)用于遍歷可迭代對(duì)象(如數(shù)組、字符串等)的元素。

          基本語法

          for (var item of 可迭代對(duì)象) {
              // 使用 item 訪問元素
          }
          

          示例:遍歷數(shù)組的元素

          var fruits=["蘋果", "香蕉", "橘子"];
          for (var fruit of fruits) {
              console.log(fruit);
          }
          

          總結(jié)

          JavaScript 的循環(huán)結(jié)構(gòu)為我們提供了強(qiáng)大的工具來處理重復(fù)任務(wù)。for 循環(huán)適合于當(dāng)我們知道循環(huán)次數(shù)時(shí)使用;while 和 do...while 循環(huán)適合于循環(huán)次數(shù)未知,但是循環(huán)條件明確的情況;for...in 和 for...of 循環(huán)則讓對(duì)象和數(shù)組的遍歷變得更加簡潔。掌握這些循環(huán)結(jié)構(gòu)有助于我們編寫更加高效和可讀性更強(qiáng)的代碼。

          件語句的代碼可以被想象成是一條條分支的路徑,而循環(huán)語句的代碼則是程序路徑的一個(gè)回路,可以讓一部分代碼重復(fù)執(zhí)行。JavaScript中的循環(huán)語句有for語句和while語句。

          一、for語句

          for語句的語法如下:

          1 for(初始值;布爾值;計(jì)數(shù)器){
          2     //語句塊
          3 }

          在for語句中,如果布爾值是true,就會(huì)一直執(zhí)行語句塊中的內(nèi)容,為了防止死循環(huán),需要有一個(gè)計(jì)數(shù)器,當(dāng)數(shù)值達(dá)到指定值,布爾值就會(huì)變成false,循環(huán)便停止了,下面的示例代碼使用for循環(huán)輸出0~9九個(gè)數(shù)字示例代碼如下:

          1 for(var i=0;i<10;i++){  
          2     // i的初始值是0
          3     // 判斷i是否小于10,如果小于10則執(zhí)行花括號(hào)中的代碼
          4     // 每次執(zhí)行完花括號(hào)中的代碼后,i的值加1
          5     console.log(i);
          6 }

          通過上面的例子我們進(jìn)一步理解了for語句的用法,下面我們來做一個(gè)聯(lián)系,利用for循環(huán)語句輸出100以內(nèi)所有正整數(shù)的加和示例代碼如下:

          1 var sum=0;                 //sum用來存儲(chǔ)循環(huán)過程中正整數(shù)的加和
          2 for(var i=1;i<=100;i++){
          3     sum +=i;
          4 }
          5 console.log(sum); //這時(shí)候輸出的就應(yīng)該是5050

          二、while語句

          while語句語法如下所示:

          1 while(bool){
          2     //bool為true,循環(huán)執(zhí)行
          3 }

          當(dāng)bool為true的時(shí)候,花括號(hào)中的內(nèi)容會(huì)循環(huán)執(zhí)行。為了防止死循環(huán),需要在循環(huán)的過程實(shí)現(xiàn)類似for計(jì)數(shù)器的功能,讓循環(huán)在有限的次數(shù)內(nèi)定制,下面我們使用while語句輸出0~9是個(gè)數(shù)字示例代碼如下:

          1 var n=0;
          2 while(n<10){
          3     console.log(n);
          4     n++;
          5 }

          在每次循環(huán)的過程中都會(huì)讓n的值加1,這樣當(dāng)n的值等于10,循環(huán)便停止,下面我來使用while語句輸出100以內(nèi)所有正整數(shù)的加和示例代碼如下:

          1 var n=0;
          2 var sum=0;
          3 while(n<=100){
          4     sum +=n;
          5     n++;
          6 }
          7 console.log(sum); 

          三、continue

          continue可以結(jié)束本次循環(huán),直接進(jìn)入到下一次循環(huán),例如我們用for循環(huán)語句來實(shí)現(xiàn)輸出0 ~ 5,7 ~ 9九個(gè)數(shù)字(跳過6)示例代碼如下:

          1 for(var i=0;i<10;i++){
          2     if(i===6){
          3         continue;
          4     }
          5     console.log(i);
          6 }

          上面的代碼通過判斷,實(shí)現(xiàn)當(dāng)i的值為6的時(shí)候,跳過本次循環(huán),直接接入下一次循環(huán)。下面我們使用continue來實(shí)現(xiàn)計(jì)算100以內(nèi)所有不能被7整除的正整數(shù)加和示例代碼如下:

          1 var sum=0;
          2 for(var i=0;i<=100;i++){
          3     if(i%7===0){
          4         continue;
          5     }
          6     sum +=i;
          7 }
          8 console.log(sum);

          四、break

          在學(xué)switch語句中,我們已經(jīng)接觸到了break,它可以讓分支語句在結(jié)束一個(gè)case之后,跳出switch語句,break同樣可以用在循環(huán)語句當(dāng)中,當(dāng)代碼執(zhí)行到break時(shí),直接結(jié)束循環(huán)示例代碼如下:

          1 for(var i=0;i<10;i++){
          2     if(i===6){
          3         break;  
          4     }
          5     console.log(i);
          6 }

          如上面的代碼所示,當(dāng)控制帶輸出5之后,循環(huán)結(jié)束。

          五、課后練習(xí)

            1. 分別用for和while語句在控制臺(tái)輸出100以內(nèi)(包括100)所有正整數(shù)的加和。
            2. 分別用for和while語句在控制臺(tái)輸出100以內(nèi)(包括100)所有偶數(shù)的加和。

          【融職教育】在工作中學(xué)習(xí),在學(xué)習(xí)中工作

          wift 使用自動(dòng)引用計(jì)數(shù)(ARC)這一機(jī)制來跟蹤和管理應(yīng)用程序的內(nèi)存

          通常情況下我們不需要去手動(dòng)釋放內(nèi)存,因?yàn)?ARC 會(huì)在類的實(shí)例不再被使用時(shí),自動(dòng)釋放其占用的內(nèi)存。

          但在有些時(shí)候我們還是需要在代碼中實(shí)現(xiàn)內(nèi)存管理。

          ARC 功能

          • 當(dāng)每次使用 init() 方法創(chuàng)建一個(gè)類的新的實(shí)例的時(shí)候,ARC 會(huì)分配一大塊內(nèi)存用來儲(chǔ)存實(shí)例的信息。

          • 內(nèi)存中會(huì)包含實(shí)例的類型信息,以及這個(gè)實(shí)例所有相關(guān)屬性的值。

          • 當(dāng)實(shí)例不再被使用時(shí),ARC 釋放實(shí)例所占用的內(nèi)存,并讓釋放的內(nèi)存能挪作他用。

          • 為了確保使用中的實(shí)例不會(huì)被銷毀,ARC 會(huì)跟蹤和計(jì)算每一個(gè)實(shí)例正在被多少屬性,常量和變量所引用。

          • 實(shí)例賦值給屬性、常量或變量,它們都會(huì)創(chuàng)建此實(shí)例的強(qiáng)引用,只要強(qiáng)引用還在,實(shí)例是不允許被銷毀的。

          ARC 實(shí)例

          class Person {
           let name: String
           init(name: String) {
           self.name=name print("\(name) 開始初始化")
           }
           deinit {
           print("\(name) 被析構(gòu)")
           }}// 值會(huì)被自動(dòng)初始化為nil,目前還不會(huì)引用到Person類的實(shí)例var reference1: Person?var reference2: Person?var reference3: Person?// 創(chuàng)建Person類的新實(shí)例reference1=Person(name: "Runoob")//賦值給其他兩個(gè)變量,該實(shí)例又會(huì)多出兩個(gè)強(qiáng)引用reference2=reference1
          reference3=reference1//斷開第一個(gè)強(qiáng)引用reference1=nil//斷開第二個(gè)強(qiáng)引用reference2=nil//斷開第三個(gè)強(qiáng)引用,并調(diào)用析構(gòu)函數(shù)reference3=nil

          以上程序執(zhí)行輸出結(jié)果為:

          Runoob 開始初始化Runoob 被析構(gòu)

          類實(shí)例之間的循環(huán)強(qiáng)引用

          在上面的例子中,ARC 會(huì)跟蹤你所新創(chuàng)建的 Person 實(shí)例的引用數(shù)量,并且會(huì)在 Person 實(shí)例不再被需要時(shí)銷毀它。

          然而,我們可能會(huì)寫出這樣的代碼,一個(gè)類永遠(yuǎn)不會(huì)有0個(gè)強(qiáng)引用。這種情況發(fā)生在兩個(gè)類實(shí)例互相保持對(duì)方的強(qiáng)引用,并讓對(duì)方不被銷毀。這就是所謂的循環(huán)強(qiáng)引用。

          實(shí)例

          下面展示了一個(gè)不經(jīng)意產(chǎn)生循環(huán)強(qiáng)引用的例子。例子定義了兩個(gè)類:Person和Apartment,用來建模公寓和它其中的居民:

          class Person {
           let name: String
           init(name: String) { self.name=name }
           var apartment: Apartment?
           deinit { print("\(name) 被析構(gòu)") }}class Apartment {
           let number: Int
           init(number: Int) { self.number=number }
           var tenant: Person?
           deinit { print("Apartment #\(number) 被析構(gòu)") }}// 兩個(gè)變量都被初始化為nilvar runoob: Person?var number73: Apartment?// 賦值runoob=Person(name: "Runoob")number73=Apartment(number: 73)// 意感嘆號(hào)是用來展開和訪問可選變量 runoob 和 number73 中的實(shí)例// 循環(huán)強(qiáng)引用被創(chuàng)建runoob!.apartment=number73
          number73!.tenant=runoob// 斷開 runoob 和 number73 變量所持有的強(qiáng)引用時(shí),引用計(jì)數(shù)并不會(huì)降為 0,實(shí)例也不會(huì)被 ARC 銷毀// 注意,當(dāng)你把這兩個(gè)變量設(shè)為nil時(shí),沒有任何一個(gè)析構(gòu)函數(shù)被調(diào)用。// 強(qiáng)引用循環(huán)阻止了Person和Apartment類實(shí)例的銷毀,并在你的應(yīng)用程序中造成了內(nèi)存泄漏runoob=nilnumber73=nil

          解決實(shí)例之間的循環(huán)強(qiáng)引用

          Swift 提供了兩種辦法用來解決你在使用類的屬性時(shí)所遇到的循環(huán)強(qiáng)引用問題:

          • 弱引用

          • 無主引用

          弱引用和無主引用允許循環(huán)引用中的一個(gè)實(shí)例引用另外一個(gè)實(shí)例而不保持強(qiáng)引用。這樣實(shí)例能夠互相引用而不產(chǎn)生循環(huán)強(qiáng)引用。

          對(duì)于生命周期中會(huì)變?yōu)閚il的實(shí)例使用弱引用。相反的,對(duì)于初始化賦值后再也不會(huì)被賦值為nil的實(shí)例,使用無主引用。

          弱引用實(shí)例

          class Module {
           let name: String
           init(name: String) { self.name=name }
           var sub: SubModule?
           deinit { print("\(name) 主模塊") }}class SubModule {
           let number: Int
           init(number: Int) { self.number=number }
           weak var topic: Module?
           deinit { print("子模塊 topic 數(shù)為 \(number)") }}var toc: Module?var list: SubModule?toc=Module(name: "ARC")list=SubModule(number: 4)toc!.sub=list
          list!.topic=toc
          toc=nillist=nil

          以上程序執(zhí)行輸出結(jié)果為:

          ARC 主模塊子模塊 topic 數(shù)為 4

          無主引用實(shí)例

          class Student {
           let name: String
           var section: Marks?
           init(name: String) {
           self.name=name }
           deinit { print("\(name)") }}class Marks {
           let marks: Int
           unowned let stname: Student
           init(marks: Int, stname: Student) {
           self.marks=marks self.stname=stname }
           deinit { print("學(xué)生的分?jǐn)?shù)為 \(marks)") }}var module: Student?module=Student(name: "ARC")module!.section=Marks(marks: 98, stname: module!)module=nil

          以上程序執(zhí)行輸出結(jié)果為:

          ARC學(xué)生的分?jǐn)?shù)為 98

          閉包引起的循環(huán)強(qiáng)引用

          循環(huán)強(qiáng)引用還會(huì)發(fā)生在當(dāng)你將一個(gè)閉包賦值給類實(shí)例的某個(gè)屬性,并且這個(gè)閉包體中又使用了實(shí)例。這個(gè)閉包體中可能訪問了實(shí)例的某個(gè)屬性,例如self.someProperty,或者閉包中調(diào)用了實(shí)例的某個(gè)方法,例如self.someMethod。這兩種情況都導(dǎo)致了閉包 "捕獲" self,從而產(chǎn)生了循環(huán)強(qiáng)引用。

          實(shí)例

          下面的例子為你展示了當(dāng)一個(gè)閉包引用了self后是如何產(chǎn)生一個(gè)循環(huán)強(qiáng)引用的。例子中定義了一個(gè)叫HTMLElement的類,用一種簡單的模型表示 HTML 中的一個(gè)單獨(dú)的元素:

          class HTMLElement {
           let name: String
           let text: String?
           lazy var asHTML: () -> String={
           if let text=self.text {
           return "<\(self.name)>\(text)</\(self.name)>"
           } else {
           return "<\(self.name) />"
           }
           }
           init(name: String, text: String?=nil) {
           self.name=name self.text=text }
           deinit {
           print("\(name) is being deinitialized")
           }
           }// 創(chuàng)建實(shí)例并打印信息var paragraph: HTMLElement?=HTMLElement(name: "p", text: "hello, world")print(paragraph!.asHTML())

          HTMLElement 類產(chǎn)生了類實(shí)例和 asHTML 默認(rèn)值的閉包之間的循環(huán)強(qiáng)引用。

          實(shí)例的 asHTML 屬性持有閉包的強(qiáng)引用。但是,閉包在其閉包體內(nèi)使用了self(引用了self.name和self.text),因此閉包捕獲了self,這意味著閉包又反過來持有了HTMLElement實(shí)例的強(qiáng)引用。這樣兩個(gè)對(duì)象就產(chǎn)生了循環(huán)強(qiáng)引用。

          解決閉包引起的循環(huán)強(qiáng)引用:在定義閉包時(shí)同時(shí)定義捕獲列表作為閉包的一部分,通過這種方式可以解決閉包和類實(shí)例之間的循環(huán)強(qiáng)引用。


          弱引用和無主引用

          當(dāng)閉包和捕獲的實(shí)例總是互相引用時(shí)并且總是同時(shí)銷毀時(shí),將閉包內(nèi)的捕獲定義為無主引用。

          相反的,當(dāng)捕獲引用有時(shí)可能會(huì)是nil時(shí),將閉包內(nèi)的捕獲定義為弱引用。

          如果捕獲的引用絕對(duì)不會(huì)置為nil,應(yīng)該用無主引用,而不是弱引用。

          實(shí)例

          前面的HTMLElement例子中,無主引用是正確的解決循環(huán)強(qiáng)引用的方法。這樣編寫HTMLElement類來避免循環(huán)強(qiáng)引用:

          class HTMLElement {
           let name: String
           let text: String?
           lazy var asHTML: () -> String={
           [unowned self] in
           if let text=self.text {
           return "<\(self.name)>\(text)</\(self.name)>"
           } else {
           return "<\(self.name) />"
           }
           }
           init(name: String, text: String?=nil) {
           self.name=name self.text=text }
           deinit {
           print("\(name) 被析構(gòu)")
           }
           }//創(chuàng)建并打印HTMLElement實(shí)例var paragraph: HTMLElement?=HTMLElement(name: "p", text: "hello, world")print(paragraph!.asHTML())// HTMLElement實(shí)例將會(huì)被銷毀,并能看到它的析構(gòu)函數(shù)打印出的消息paragraph=nil

          以上程序執(zhí)行輸出結(jié)果為:

          <p>hello, world</p>p 被析構(gòu)

          主站蜘蛛池模板: 亚洲一区二区三区夜色| 国产手机精品一区二区| 亚洲色精品aⅴ一区区三区| 日本高清一区二区三区| 成人免费区一区二区三区| 国产伦一区二区三区免费| 波多野结衣一区二区三区| 在线精品动漫一区二区无广告| 伊人久久精品一区二区三区| 亚洲av无码一区二区三区网站| 人妻无码一区二区三区四区| 国产在线一区观看| 在线观看视频一区二区| 好爽毛片一区二区三区四无码三飞 | 国产无吗一区二区三区在线欢 | 国产成人av一区二区三区在线| 日韩免费无码视频一区二区三区| 国产亚洲情侣一区二区无码AV| 日本一区二区三区在线视频| 久久一区二区三区免费播放| 国产亚洲一区二区精品| 免费一区二区三区四区五区| 乱中年女人伦av一区二区| 天海翼一区二区三区高清视频| 久久久精品人妻一区二区三区蜜桃| 亚洲国产精品一区二区九九| 国产凸凹视频一区二区| 精品国产免费一区二区| 国产裸体舞一区二区三区| 狠狠综合久久av一区二区| 日本免费一区二区三区最新vr| eeuss鲁片一区二区三区| 国产乱码精品一区二区三区麻豆| 五十路熟女人妻一区二区| 亚洲AV无码一区二区乱子仑| 天堂一区人妻无码| 精品不卡一区中文字幕 | 国产微拍精品一区二区| 国产在线观看一区二区三区四区 | 无码人妻一区二区三区在线视频| 日韩一区二区三区无码影院|