讀完一本書總結的前端知識點——JS基礎(持續更新中)

1.javascript概述(瞭解)

1.什麼是javascript

javascript簡稱爲js,是一種運行於js解釋器/引擎中的腳本語言
js的運行環境:
1.獨立安裝的js解釋器(node)
2.嵌入在瀏覽器內核中的js解釋器

2.js的發展史

1.1992Nombas公司爲自己開發了一款腳本語言SciptEase
2.1995Netscape(網景)開發了一款腳本語言LiveScrpt,後來更名javascript
3.1996MicrosoftIE3.0版本中克隆javascriptJScript
4.1997年,javascript提交給ECMA(歐洲計算機製造商聯合會)。定義ECMAScript,簡稱ES5ES6

3.js組成部分

1.核心(ECMAScript)
2.DOM (Document object model)文檔對象模型
3.BOM (Browser object model)瀏覽器對象模型

4.js的特點

1.語法類似於c,java
2.無需編譯,由js解釋器直接運行
3.弱類型語言
4.面向對象的

2.JavaScript的基礎語法

1.使用javascript

1.搭建運行環境
  1.獨立安裝的JS解釋器-NodeJS
    1.在命令行界面:輸入node
  console.log("你好,世界");
  在控制檯打印輸出
  說明:js是可以獨立在js解釋器中運行
2.使用瀏覽器內核中嵌的js解釋器
  瀏覽器內核負責頁面內容的渲染,由兩部分組成:
     內容排版引擎-解析:HTML/CSS
     腳本解釋引擎-解析:javascript
 1.直接在Console(控制檯)中輸入腳本並運行
 2.將js腳本嵌入在HTML頁面中執行
   1.html元素的事件中執行js腳本
      事件-onclick-鼠標單擊時要執行的操作
   2.在<script>中編寫腳本並執行
      網頁的任何位置處,嵌入一對<script>標記,並且將腳本編寫在<script>標記中。
       3.使用外部腳本文件(.js爲後綴)
     1.創建腳本文件(.js)並在文件中編寫腳本
     2.在使用的網頁中引用腳本文件
        <script src="腳本文件的url"></script>
      
 3.js調試,F12查看錯誤,出錯時不影響其它代碼塊,後續代碼繼續執行。
   <script>
    /*這個腳本錯誤*/
    document.writ("<h3>周芷若</h3>");
       </script>
      <script>
    /*繼續執行*/
        console.log("金花婆婆");  
      </script>
    3.通過語法規範
  1.語句:可執行的最小單元
          必須以;結束
      嚴格區分大小
      所有的符號必須是英文
      2.註釋:
    // :單行註釋
    /**/:多行註釋

3.變量和常量

1.變量聲明

1.聲明變量
  var 變量名;
2.爲變量賦值
  變量名=值;
3.聲明變量是直接賦值
  var 變量名=值;
  ex:
  var uname="張無忌";
  var age=20;
 注意:
   1.允許在一條語句中聲明多個變量,用逗號隔開變量名。
     var uname="韓梅梅",uage=20;
   2.如果聲明變量,但未賦值,則值默認爲undefined
   3.聲明變量時可以不適用var,但不推薦
     uname="tom";

2.變量名的規範

1.不允許以數字開頭
2.不允許使用關鍵詞和保留關鍵字
3.最好見名知意
  var uname; var uage;
4.允許包含字母,數字,下劃線(_),$
  var $name="Tom";
5.儘量使用小駝峯命名法
  var userName;
  var uname;
  var _uname;//下劃線
  var user_name;//下劃線
  var UserName;//大駝峯命名法

4.變量的使用

1.聲明變量未賦值,值默認爲undefined
2.使用未聲明過的變量 報錯
3.賦值操作
  變量名出現在=的左邊,一律是賦值操作
    var uname="林妹妹";
4.取值操作
  變量只要沒出現在=的左邊,一律是取值操作
    var uage=30;
console.log(uage);
var num1=uage;

5.常量

1.什麼是常量
  在程序中,一經聲明就不允許被修改的數據就是常量。
2.語法
  const 常量名=值;
  常量名在程序中,通常採用大寫形式。
  const PI=3.1415926;

5.1數據類型

1.數據類型的作用

規定了數據在內存中所佔的空間
10.1 64位 8個字節
bit:位
8bit=1byte字節
1024byte=1KB 
1024KB=1MB
1024MB=1G 
1024G=1T

2.數據類型詳解

1.數據類型分兩大類
  原始類型(基本類型)
  引用類型
  1.原始類型
    1.Number 類型
  數字類型
  作用:可以表示32位的整數,也可以表示64位的浮點數(小數)
  整數:
     1.十進制
       10 
     2.八進制
       由0-7八個數字組成,逢八進一
       八進制中以0開始
       var num=010;
     3.十六進制
       由0-9和A-f組成,逢十六進一
          A:10
      B:11
      C:12
      D:13
      E:14
      F:15
       十六進制中以0X開始
      浮點數:又稱小數
    小數點計數法:12.58  
    指數計數法:3.4e33.4*103次方)
2.String類型
  字符串類型
  作用:表示一系列的文本字符數據,如:姓名,性別,住址...
  字符串中的每個字符,都是由Unicode碼的字符,標點和數字組成。
  Unicode碼:每個字符在計算機中都有一個唯一的編碼表示該字符,
  該碼就是unicode碼(他是十六進制)
     1.查找一個字符的unicode碼:
     "李".charCodeAt();
     //10進制輸出

     "李".charCodeAt().toString(2);
     //二進制輸出

     "李".charCodeAt().toString(16);
     //十六進制

       李的unicode碼是:674e
     2.如何將674e轉換爲漢字?
        用\u
       ex:
        var str="\u674e";
    console.log(str);//結果是“李”

    漢字的Unicode碼的範圍:
    \u4e00~\u9fa5
     3.特殊字符需要轉義字符
       \n: 換行
       \t: 製表符(縮進)
       \": "
       \': '
       \\: \
3.Boolean類型
  布爾類型
  作用:在程序中表示真或假的結果
  取值:
     truefalse
  var isBig=true;
  var isRun=false;
  在參與到數學運算時,true可以當成1做運算,false可以當做0做運算。
  var res=25+true; //結果爲26
    4.Undefined類型
  作用:表示使用的數據不存在
  Undefined類型只有一個值,即undefined當聲明的變量未賦值(未初始化)時,
  該變量的默認值就是undefined.
5.Null類型
  null用於表示不存在的對象。
      Null類型只有一個值,即null,如果函數或方法要返回的是對象,
      找不到該對象,返回的就是null

5.2數據類型的轉換

1.隱式(自動)轉換
  不同類型的數據在計算過程中自動進行轉換
  1.數字+字符串:數字轉換爲字符串
    var num=15;
var str="Hello";
var res=num+str; //結果:15Hello
  2.數字+布爾:將布爾轉換爲數字true=1,false=0
    var num1=10;
var isSun=true;
var res1=num1+isSun;//結果:11
  3.字符串+布爾:將布爾轉換爲字符串
    var str1="Hello";
var isSun1=true;
var res2=str1+isSun1;//結果:Hellotrue
  4.布爾+布爾:將布爾轉換爲數字
    true=1,false=0;
    var isSun2=true;
var isSun3=flase;
var res=isSun2+isSun3;//結果1
2.強制轉換 -轉換函數
  1.toString()
    將任意類型的數據轉換爲字符串
語法:
  var num=變量.toString();
  ex:
  var num=15;
  var str=num.toString();
  console.log(typeof(str));
  2.parseInt()
    將任意類型的數據轉換爲整數
如果轉換不成功,結果爲NaN(Not a Number)
語法:var result=parseInt(數據);
  3.parseFloat()
    將任意類型的數據轉換爲小數
如果轉換不成功,結果爲NaN
語法:var result=parseFloat(數據);
  4.Number()
    將任意類型數據轉爲Number類型
注意:如果包含非法字符,則返回NaN
語法:var result=Number(數據);

6.運行符和表達式

1.什麼是表達式

由運算符連接操作數所組成的式子就是表達式。
ex:
  15+20
  var x=y=40
任何一個表達式都會有結果。

2.運算符

1.算術運算符
  +,-,*,/,%,++,--

  5%2=1;
  ++:自增運算,只做+1操作
  ++在前:先自增,再運算;
  ++在後:先運算,再自增;
  ex:
    var num=5;
console.log(num++);//打印5,變爲6
console.log(++num);//變爲7,打印7

ex:
    var num=5;
             5   (6)6   6(7)    (8)8
    var res=num+ ++num +num++ + ++num +num++ +num;  
  8(9)   9
結果:42
2.關係運算符(比較)
  >,<,>=,<=,==,===(全等),!=,!==(不全等)
  關係運算的結果:boolean類型(true,false)
  問題:
    1. 5 > "10" 結果:false
   關係運算符兩端,只要有一個是number的話,另外一個會隱式轉換爲number類型,再進行比較。
2."5">"1 0" 結果:true
  "5".charCodeAt(); //53
  "1".charCodeAt(); //49
  "張三丰" > "張無忌" 結果:false
    19977  >   26080
3."3a" > 10 結果:false
  Number("3a")--->NaN
  注意:
    NaN與任何一個數據做比較運算時,結果都是false.
    console.log("3a">10); false
    console.log("3a"==10); false
    console.log("3a"<10); false
    isNaN()函數:
       語法:isNaN(數據);
       作用:判斷指定數據是否爲非數字,如果不是數字,返回值爲true,是數字的話返回的值爲false
       console.log(isNaN("3")); //false
       console.log(isNaN("3a")); //ture 

       console.log("3a"!=10);//true
3.邏輯運算符
  !,&&,||

  !:取反
  &&:並且,關聯的兩個條件都爲true,整個表達式的結果爲true
  ||:或者,關聯的兩個條件,只要有一個條件爲true,整個表達式的結果就爲true

  短路邏輯:
     短路邏輯&&:
     當第一個條件爲false時,整體表達式的結果就爲false,不需要判斷第二個條件
     如果第一個條件爲true,會繼續判斷或執行第二個條件
 短路邏輯||:
     當第一個條件爲true時,就不再執行後續表達式,整體結果爲true。
     當第一個條件爲false時,繼續執行第二個條件或操作。

4.位運算符
  <<,>>,&,|,^

  右移是把數變小,左移是把數變大
  &:按位與,判斷奇偶性
     任意數字與1做按位與,結果爲1,則爲奇數,結果爲0,則爲偶數。
     var num=323;
 var result=num & 1
 console.log(result); //結果爲1
  |:按位或,對小數取整
     將任意小數與0做按位或,結果則取整數部分。

  ^:按位異或,用於交換兩個數字
      二進制位數,逐位比較,不同則爲1,相同則爲0
   a=a^b;
   b=b^a;
   a=a^b;
5.賦值運算符和擴展賦值運算符
  1.賦值運算 =
    var uname="TOM";
  2.擴展賦值運算符
    +=,-=,*=,/=,%=,^=...
a=a+1 a+=1;a++;++a
a=a^b
a^=b
6.條件(三目)運算符
  單目(一目)運算符,只需要一個操作數或表達式
  ex: a++,b--,!isRun
  雙目(二元)運算符,需要兩個操作數或表達式
   +,-,*,/,%,>,<,>=,<=,==,!=,===,!==,&&,||,&,|,^
  三目(三元)運算符,需要三個操作數或表達式
     條件表達式?表達式1:表達式2;
        先判斷條件表達式的值,
    如果條件爲true,則執行表達式1的操作
    如果條件爲false,則執行表達式2的操作
  ex:成績大於60及格,否則,輸出不及格
 

7.函數-function

1.什麼是函數

函數,function,也稱爲方法(method)
函數是一段預定義好,並可以被反覆執行的代碼塊。
   預定義:提前定義好,並非馬上執行。
   代碼塊:可以包含多條可執行的語句
   反覆執行:允許被多次調用
函數-功能
   parseInt();
   parseFloat();
   Number();
   console.log();
   alert();
   document.write();

2.定義和使用函數

1.普通函數的聲明和調用(無參數無返回值)
  1.聲明
    function 函數名(){
   //函數體
     若干可執行的語句
  
}
  2.調用函數
    在任意javascript合法的位置處通過 函數名(); 對函數進行調用。
 

2.帶參函數的聲明和調用
  1.聲明
    function 函數名(參數列表){
   //函數體
}
參數列表:可以聲明0或多個參數,多個參數間用逗號隔開
聲明函數時,聲明的參數,稱之爲“形參”
 2.調用
   函數名(參數值列表);
   注意:調用函數時,傳遞的參數數值,稱之爲“實參”。
         儘量按照聲明函數的格式進行調用
3.帶返回值函數聲明和調用
  1.聲明
    function 函數名(參數){
   //函數體
   return 值;
   //return關鍵字,程序碰到return關鍵詞,就立馬跳出並且把值帶出去
}
注意:最多隻能返回一個值
  2.調用
    允許使用一個變量接收函數的返回值
    var result=函數名(實參);

8.作用域

1.什麼是作用域
  作用域表示的是變量或函數的可訪問範圍。
  JS中的作用域分兩種:
     1.函數作用域
   只在函數範圍內有效
 2.全局作用域
   代碼的任何位置都有效

2.函數作用域中變量

 又稱爲局部變量,只在聲明的函數中有效
 ex:
   function test(){
     var num=10;
   }
   

3.全局作用域中的變量

 又稱爲全局變量,一經聲明,任何位置都能用
 1.不在function中聲明的變量,爲全局變量
 2.聲明變量不使用var,無論任何位置聲明,都是全局變量(不推薦)

 注意:
   全局變量和局部變量衝突時,優先使用局部變量。
 3.變量的聲明提前
   1.什麼是聲明提前
     在JS程序正式執行之前,function聲明的函數,
     會將所有var聲明的變量,都預讀(聲明)到所在作用域的頂部,但賦值還是保留在原位。
  

9.按值傳遞

1.什麼是按值傳遞

原始(基本)類型的數據(number,string,bool),在做參數傳遞時,
都是按照“值傳遞”的方式進行傳參的。
值傳遞:真正傳遞參數時,實際上傳遞的是值的副本(複製出來一個值),
而不是原始值。

2.函數的作用域

1.分爲兩種
  1.局部函數
    在某個function中聲明的函數。
  2.全局函數
    在最外層(<script>中)定義的函數就是全局函數,全局函數一經定義,
    任何位置處都能調用。

10.ECMAScript提供一組全局函數

1.parseInt()
2.parseFloat()
3.isNaN()
4.encodeURI()

URL:uniform resource locator路徑
URI:uniform resource Identifier
作用:對統一資源標識符進行編碼,並返回編碼後的字符串
所謂的進行編碼,就是將地址中的多字節文字編成單字節的文字
(英文數字:單字節,漢字2-3字節不等)

5.decodeURI()

作用:對已經編碼的URI進行解碼,並返回解碼後的字符串。

6.encodeURIComponent()

encodeURI的基礎上,允許對特殊符號進行編碼。

7.decodeURIComponent()

解碼特殊符號

8.eval()

作用:執行以字符串表示的js代碼

11.遞歸調用

遞歸:在一個函數的內部再一次調用自己
問題:

 1*2*3*4*5
 
 5*4*3*2*15!(5*4*3*2*1) 4!(4*3*2*1) 3!(3*2*1)
       2!(2*1) 1!(1*1)

   5!=5*4!
   4!=4*3!
   3!=3*2!
   2!=2*1!
   1!=1
   通過一個函數,求數字n的階乘
   10!=10*(10-1)!
   效率:
     在本次調用還未結束時,就開始下次的調用,本次調用就會被掛起,
     直到所有的調用都完成之後,纔會依次返回,調用的次數越多,效率越低。
  

12.分支結構

1.if結構

if(條件){
   語句塊;
}
注意:
  條件儘量是boolean的,如果不是boolean,以下情況會當做false處理
   if(0){...}
   if(0.0){...}
   if(""){...}
   if(undefined){...}
   if(null){...}
   if(NaN){...}
注意:if後的{}可以省略,但是不推薦,只控制if後的第一句話。

2.if...else...結構

語法:
  if(條件){
     語句塊
  }else{
     語句塊
  }

3.if....else if...else...

語法:
  if(條件1){
    語句塊1
  }else if(條件2){
     語句塊2
  }else if(條件3){
     語句塊3
  }else{
     語句塊n
  }

4.switch...case

1.作用:(使用場合)
  等值判斷
2.語法
  1.switch(值/表達式){
     case1:
    語句塊1break;//結束switch結構,可選的
 case2:
    語句塊2break;
    ...
 default:
   語句塊n;
   break;
   }
  2.特殊用法
    執行相同操作時:
   switch(值/表達式){
       case1case2case3:
          語句塊;
   }

  

12.循環結構

1.特點

1.循環條件:循環的開始和結束
2.循環操作:要執行的相同或相似的語句

2.循環-while

語法:
   while(條件){
      //循環體-循環操作
      
  //更新循環條件
   }

3.循環的流程控制

1.break
  作用:終止整個循環的運行
2.continue
  作用:終止本次循環的運行,繼續執行下一次循環
 ex:
   循環從彈出框中錄入信息,並且打印,直到輸入exit爲止。
   

4.循環-do...while

1.語法
  do{
     //循環體
  }while(條件);

 執行流程:
     1.先執行循環體
 2.再判斷循環條件
   如果條件爲真,則繼續執行循環體
   如果條件爲假,則跳出循環操作

5.循環-for

語法:
  for(表達式1;表達式2;表達式3){
     //循環操作
  }
  表達式1:循環條件的聲明
  表達式2:循環條件的判斷
  表達式3:更新循環變量
  執行流程:
     1.先執行表達式1
 2.判斷表達式2的結果(boolean類型)
 3.如果2條件爲真,則執行循環體,否則退出
 4.執行完循環體後,再執行表達式3
 5.判斷表達式2的結果
  ex: for(var i=1;i<=10;i++){
      console.log(i);
   }

13.for的特殊用法

1.for(表達式1;表達式2;表達式3;){}

1.省略表達式
  三個表達式可以任意省略,分號不能省
  但一定在循環的內部或外部將表達式補充完整
2.表達式1和表達式3 允許寫多個表達式,用逗號隔開表達式

14.循環嵌套

1.循環嵌套

在一個循環的內部,又出現一個循環
  for(var i=1;i<100;i++){ //外層循環
     for(var j=1;j<=10;j++){
    //內層循環
 }
  }
 外層循環走一次,內層循環走一輪

15.數組

1.什麼是數組

在一個變量中保存多個數據。
數組是按照線型順序來排列的-線型結構
數組中:除了第一個元素外,每個元素都有一個直接的"前驅元素"。
數組中:除了最後一個元素外,每個元素都有一個會直接的"後繼元素"

2.聲明數組

1.語法
  1.var 數組名=[];
    var names=[];
  2.var 數組名=[元素1,元素2,元素3...];
    var names=["孫悟空","豬八戒","沙和尚"];
  3.var 數組名=new Array();
    var names=new Array();
  4.var 數組名=new Array(元素1,元素2...);
    var names=new Array("林黛玉","賈寶玉","王熙鳳");

3.數組的使用

1.取值和賦值操作
  取值:
   數組名[下標]
   var newArr=["tom","lilei"];
   newArr[0]
  賦值:
    數組名[下標]=值;
     newArr[2]="韓梅梅";
2.獲取數組的長度
  數組長度:數組中元素的個數
  屬性:length
  語法:數組名.length
3.配合循環,遍歷數組中的每個元素
  for(var i=0;i<names.length;i++){
      i:表示數組中每個元素的下標
      names[i]:每個元素
  }
  
  length表示數組中即將要插入的元素的下標
  var names=["tom","lili","lucy"];
      names[names.length]="lilei";
 

16.關聯數組

1.關聯數組
  以字符串作爲元素的下標的數組,就是關聯數組。
  以數字作爲下標的數組,就是索引數組。
$array=["name"=>"tom"]
2.js中的關聯數組
  var array=[];
  array["字符串下標"]=值;
  注意:
    1.關聯數組中,字符串下標的內容是不記錄到length中的
2.只能通過 字符串 做下標取值
3.for...in
  遍歷出任意數組中的字符串下標 以及 索引下標
  語法:for(var 變量 in 數組名){
       //變量:字符串下標 或 索引下標
  }

17.冒泡排序

1.什麼是冒泡
  排序算法之一,將一組數據進行排序,小的數字往前排,大的數字往後排。
  兩兩比較,小的靠前。
  var arr=[9,23,6,78,45]; 5個數  比4輪
  第一輪:比較了4次
  第二輪:比較了3次
  第三輪:比較了2次
  第四輪:比較了11.n個數字,則比較n-1輪
    for(var i=1;i<arr.length;i++)
  2.輪數增加,比較的次數較少
    for(var j=0;j<arr.length-i;j++)
          第一輪  5     -1=4次
      第二輪  5     -2=3次
              第三輪  5     -3=2次
      第四輪  5     -4=1次
      兩兩比較 小的靠前
      if(arr[j]>arr[j+1])

         arr[j]^=arr[j+1];
         arr[j+1]^=arr[j];
         arr[j]^=arr[j+1]

18.數組的常用方法

1.toString();

作用:將數組轉換爲字符串,並返回轉換後的結果。
語法: var str=數組對象.toString();

2.join()

作用:將數組的元素通過指定的字符連接到一起,並返回連接後字符串
語法:var str=數組對象.join("字符");

3.concat()

作用:拼接兩個或更多的數組,並返回拼接後的結果
語法:var res=數組對象.concat(數組1,數組2,...);

 

19.數組的函數

1.slice()

作用:截取子數組,從指定的數組中,截取幾個連續的元素組成一個新的數組
語法:var arr=數組名.slice(start,[end]);
      start:從哪個下標位置處開始截取,取值爲正,從前向後算; 
      取值爲負,從後向前算          0      1      2
   var arr=["中國","美國","俄羅斯"];
             -3      -2    -1 
      end:指定結束位置處的下標(不包含自己),該參數可以省略,
      如果省略的話,就是從strat開始一直截取到尾。

2.splice()

作用:允許從指定數組中,刪除一部分元素,同時再添加一部分元素
語法:arr.splice(start,count,e1,e2...);
      start:指定添加或刪除元素的起始下標
  count:指定要刪除元素的個數,取值爲0表示不刪除
  e1:要增加的新元素,可以多個
  返回值:返回一個由刪除元素所組成的數組

3.reverse()

作用:將一個數組反轉
語法:數組名.reverse();
注意:該函數會改變當前數組的內容

4.sort()

作用:排序,默認情況下按照數組元素們的Unicode碼進行升序排序。
語法:數組名.sort();
特殊:
   允許自定義排序函數,從而實現對數字的升序或降序的排序
   ex:
     var arr=[12,6,4,115,78];
 //排序函數(升序)
 function sortAsc(a,b){
    return a-b;
 }
 arr.sort(sortAsc);
  原理:
    1.指定排序行數sortAsc,定義兩個參數a和b,表示數組中相鄰的兩個數字
2.將排序函數指定給數組sort()函數,數組會自動傳遞數據到sortAsc()中,
  如果sortAsc()的返回值>0,則交互兩個數字的位置,否則不變。
  使用函數完成升序排序:
     arr.sort(
       function(a,b){  //匿名函數
         return a-b;
       }
    )

20.進出棧操作

JS是按照標準的“棧式操作”來訪問數組
所有的“棧式操作”的特點就是“後進先出”
1.push()

入棧,在棧頂添加指定的元素,並返回新數組的長度
 var arr=[10,20,30];
 //向棧頂增加新的數據40
 var len=arr.push(40); //4

2.pop()

出棧,刪除(刪除棧頂數據)並返回刪除元素
注意:改變原來數組

3.shift()

刪除數組頭部(第一個)的元素並返回刪除元素
語法:數組名.shift();

4.unshift()

在數組的頭部(第一個)元素的位置處,增加元素,返回的是數組的長度。
語法:數組名.unshift(增加的數據);

3.二維數組
1.什麼是二維數組

在一個數組中的元素又是一個數組,也可以稱爲:數組的數組。

2.二維數組的使用

var names=[
    ["孫悟空","豬八戒","沙和尚"],
["大喬","小喬","曹操"],
["林黛玉","賈寶玉","薛寶釵"]
];
 //打印輸出“小喬”
   console.log(names[1][1]);

寫在最後

大咖的話:

“最近有很多想學習編程的朋友問我有沒有什麼好的編程資料!因爲最近今年我都在認真蒐集有價值的編程資料,技術資料,只爲幫助那些想學習編程而不知道從哪開始的朋友。

下圖就是(部分資料截圖):

如果編譯器是人,對你的代碼會有啥反應?網友:會吐。。。

以上價值3萬元的資料,絕對比羣裏那些漫天飛的資料強多了。今天決定免費分享,用來感謝大家的支持

免費獲取方式:

 添加大咖VX:“cquan123456”,即可免費領取,不需要任何條件,只爲幫助有需要的朋友!一定要備註:“大咖,你真帥(CSDN)”否則不能通過!
歡迎留言分享!
發佈了9 篇原創文章 · 獲贊 63 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章