Rumah  >  Artikel  >  hujung hadapan web  >  Tutorial Lanjutan JavaScript 5.6 Jenis Pembungkusan Asas (Butiran)_Kemahiran Javascript

Tutorial Lanjutan JavaScript 5.6 Jenis Pembungkusan Asas (Butiran)_Kemahiran Javascript

WBOY
WBOYasal
2016-05-16 15:30:411201semak imbas

Untuk memudahkan operasi nilai jenis asas, ECMAScript juga menyediakan 3 jenis rujukan khas: Boolean, Number, String.

Malah, apabila nilai jenis asas dibaca, latar belakang harus mencipta objek daripada jenis pembalut asas yang sepadan, supaya kita boleh memanggil beberapa kaedah untuk mengendalikan data ini.

var s1="some text";
  var s2=s1.substring(2);
  console.log(s2);//me text

Dalam contoh ini, s1 mengandungi rentetan, yang merupakan nilai jenis asas Baris kedua memanggil kaedah substring() s1 dan menyimpan hasil yang dikembalikan dalam

Apabila baris kedua kod mengakses s1, proses capaian berada dalam mod baca, iaitu nilai rentetan ini dibaca daripada memori Apabila mengakses rentetan dalam mod baca, latar belakang akan Melengkapkan pemprosesan berikut secara automatik .

(1) Buat tika jenis String;

(2) Panggil kaedah yang dinyatakan pada contoh;

(3) Musnahkan kejadian ini.

Tiga langkah di atas boleh dibayangkan sebagai melaksanakan kod berikut:

var s1=new String("some text");
  var s2=s1.substring(2);
  s1=null;
  console.log(s2);//me text

Selepas pemprosesan ini, nilai rentetan asas menjadi sama dengan objek Dan tiga langkah di atas juga boleh digunakan untuk nilai Boolean dan angka yang sepadan dengan jenis Boolean dan Nombor masing-masing

Perbezaan utama antara jenis rujukan dan jenis pembungkusan asas ialah jangka hayat objek.

Instance jenis rujukan yang dibuat menggunakan operator baharu disimpan dalam memori bersama-sama sebelum aliran pelaksanaan meninggalkan skop semasa Walau bagaimanapun, objek jenis pembungkus asas yang dibuat secara automatik hanya wujud pada masa baris kod dilaksanakan, dan kemudian Dimusnahkan. serta-merta. Ini bermakna kita tidak boleh menambah sifat dan kaedah pada jenis asas pada masa jalan.

var s1="some text";
  s1.color="red";
  console.log(s1.color);//undefined
Punca masalah ialah objek String yang dicipta dalam baris kedua telah dimusnahkan apabila baris ketiga kod dilaksanakan Baris ketiga kod mencipta objek Stringnya sendiri, dan objek ini tidak mempunyai atribut warna .

Panggilan typeof pada contoh jenis pembalut asas akan mengembalikan "objek", dan semua objek jenis pembalut asas akan ditukar kepada nilai Boolean true.

Pembina Objek juga akan, seperti kaedah kilang, mengembalikan tika jenis pembungkusan asas yang sepadan mengikut jenis nilai yang diluluskan.

var obj=new Object("some text");
  console.log(obj instanceof String);//true
Jika anda menghantar rentetan kepada pembina Objek, contoh String akan dibuat, jika anda lulus dalam parameter angka, anda akan mendapat contoh Nombor, dan jika anda lulus dalam parameter Boolean, anda akan mendapat contoh Boolean.

Perlu diingat bahawa menggunakan new untuk memanggil pembina jenis pembungkusan asas adalah berbeza daripada memanggil terus fungsi transformasi dengan nama yang sama.

var value="25";
  var number=Number(value);//转型函数
  console.log(typeof number);//number
  var obj=new Number(value);//构造函数
  console.log(typeof obj);//object

Dalam contoh ini, nombor pembolehubah menyimpan nilai jenis asas 25 dan pembolehubah obj menyimpan tika Nombor.

5.6.1 Jenis Boolean

Jenis Boolean ialah jenis rujukan yang sepadan dengan nilai Boolean Untuk mencipta objek Boolean, anda boleh memanggil pembina Boolean seperti berikut dan menghantar nilai benar atau palsu.

var booleanObject=new Boolean(true);
Instance jenis Boolean mengatasi kaedah valueOf() untuk mengembalikan nilai jenis asas true atau false; kaedah toString() ditindih untuk mengembalikan rentetan "true" dan "false", Walau bagaimanapun, objek Boolean dalam ECMAScript Ia tidak begitu berguna kerana ia sering menyebabkan orang salah faham.

Salah satu masalah yang paling biasa ialah menggunakan objek Boolean dalam ungkapan Boolean.

var falseObject=new Boolean(false);
  var result=falseObject&&true;
  console.log(result);//true
  var falseValue=false;
  result=falseValue&&true;
  console.log(result);//false
Dalam contoh ini, objek Boolean dibuat menggunakan nilai palsu Kemudian ungkapan AND logik dibina antara objek ini dan nilai jenis asas true ini dalam contoh dilakukan pada falseObject dan bukannya nilainya (. false) Penilaian Semua objek dalam ungkapan Boolean akan ditukar kepada benar, jadi objek falseObject mewakili benar dalam ungkapan Boolean.

Terdapat dua perbezaan antara nilai Boolean jenis asas dan jenis rujukan: Pertama, jenis operasi mengembalikan "boolean" untuk jenis asas, manakala "objek" dikembalikan untuk jenis rujukan Kedua, kerana objek Boolean adalah contoh jenis Boolean, jadi Menggunakan operator instanceof untuk menguji objek Boolean mengembalikan benar, manakala menguji nilai Boolean jenis asas mengembalikan palsu.

console.log(typeof falseObject);//object
  console.log(typeof falseValue);//boolean
  console.log(falseObject instanceof Boolean);//true
  console.log(falseValue instanceof Boolean);//false

5.6.2 Jenis nombor

Nombor ialah jenis rujukan yang sepadan dengan nilai angka Untuk mencipta objek Nombor, anda boleh menghantar nilai yang sepadan kepada pembina Nombor apabila memanggilnya

var numberObject=new Number(10);
  console.log(typeof numberObject);//object
Seperti jenis Boolean, jenis Number juga mengatasi kaedah valueOf(), toLocaleString() dan toString().

Kaedah valueOf() yang ditulis semula mengembalikan nilai jenis asas kes objek dan dua kaedah lain mengembalikan nilai dalam bentuk rentetan.

Anda boleh menghantar parameter yang mewakili asas kepada kaedah toString() dan memberitahunya untuk mengembalikan bentuk rentetan nilai perpuluhan.

var num=10;
  console.log(num.toString());//10
  console.log(num.toString(2));//1010
  console.log(num.toString(8));//12
  console.log(num.toString(10));//10
  console.log(num.toString(16));//a
Selain kaedah yang diwarisi, jenis Nombor juga menyediakan beberapa kaedah untuk memformat nilai angka ke dalam rentetan.

Antaranya, kaedah toFixed() akan mengembalikan perwakilan rentetan nilai mengikut tempat perpuluhan yang ditentukan.

var num=10;

console.log(num.toFixed(2));//10.00


Nilai 2 dihantar ke kaedah toFixed() di sini, yang bermaksud bilangan tempat perpuluhan yang dipaparkan

Jika nilai itu sendiri mengandungi lebih banyak tempat perpuluhan daripada yang ditentukan, nilai yang hampir dengan tempat perpuluhan maksimum yang ditentukan akan dibundarkan.

能够自动舍入的特性,使得toFixed()方法很适合处理货币值.但需要注意的是,不同浏览器给这个方法设定的舍入规则可能会有所不同.在给toFixed()传入0的情况下,IE8及之前的版本不能正确舍入范围在{(-0.94,-0.5],[0.5,0.94)}之间的值.对于这个范围内的值,IE会返回0,而不是-1或1;其他浏览器都能返回正确的值.IE9修复了这个问题.

另外可用于格式 化数值的方法是toExponential(),该方法返回以指数表示法(也称e表示法)表示数值的字符串形式.与toFixed()方法一样,toExponential()也接收一个参数,而且该参数同样也是指定输出结果中的小数位数.

var num=10;
  console.log(num.toExponential(1));//1.0e+1

对于一个数值来说,toPrecision()方法可能会返回固定大小(fixed)格式,也可能返回指定(exponential)格式;具体规则是看哪种格式最合适.这个方法接收一个参数,即表示数值的所有数字的位数(不包括指数部分).

var num=99;
  console.log(num.toPrecision(1));//1e+2
  console.log(num.toPrecision(2));//99
  console.log(num.toPrecision(3));//99.0

第二行是用一位数来表示99,第三行是用两位数来表示,第四行是用三位数来表示.

实际上,toPrecision()会根据要处理的数值决定到底是调用toFixed()还是调用toExponential(),而这三个方法都可以通过向上或向下舍入,做到以最准确的形式来表示带有正确小数位的值.

toPrecision()方法可以表现1到21位小数.

仍然不建议直接实例化Number类型.具体来讲,就是在使用typeof和instanceof操作符测试基本类型数值与引用类型数值时,得到的结果完全不同.

var numberObject=new Number(10);
  var numberValue=10;
  console.log(typeof numberObject);//object
  console.log(typeof numberValue);//number
  console.log(numberObject instanceof Number);//true
  console.log(numberValue instanceof Number);//false

在使用typeof操作符测试基本类型数值时,始终会返回"number",而在测试Number对象时,则会返回"object”.类似地,Number对象是Number类型的实例,而基本类型的数值则不是.

5.6.3 String类型

String类型是字符串的对象包装类型,可以像下面这样使用String构造函数来创建.

var stringObject=new String("hello world");

String对象的方法也可以在所有基本的字符串值中访问到.其中,继承的valueOf(),toLoaleString()和toString()方法,都返回对象所表示的基本字符串值.

String类型的每个实例都有一个length属性,表示字符串包含多个字符.

var stringValue="hello world";
  console.log(stringValue.length);

应该注意的是,即使字符串中包含双字节字符(不是占一个字节的ASCII字符),每个字符也仍然算一个字符.

1.字符方法

两个用于访问字符串中特定字符的方法是:charAt()和charCodeAt().这两个方法都接收一个参数,即基于0的字符位置.

charAt()方法以单字符字符串的形式返回给定位置的那个字符.

如果想得到的不是字符而是字符编码,就需要使用charCodeAt()了.

ECMAScript还定义了另一个访问个别字符的方法.在支持此方法的浏览器中,可以使用方括号加数字索引来访问字符串中的特定字符.

var stringValue="hello world";
  console.log(stringValue[1]);//e

使用方括号表示法访问个别字符的语法得到了IE8及FF,Safari,Chrome和Opera所有版本的支持.如果在IE7及更早版本中使用这种语法,会返回undefined值.

2.字符串操作方法

concat(),用于将一或多个字符串拼接起来,返回拼接得到的新字符串.

var stringValue="hello";
  var result=stringValue.concat("world");
  console.log(result);//helloworld
  console.log(stringValue);//hello

concat()返回一个拼接的字符串,不改变原数组的值.它可以接受任意多个参数,也就是说可以通过它拼接任意多个字符串.

var stringValue="hello";
  var result=stringValue.concat("world","!")
  console.log(result);//hellowworld!
  console.log(stringValue);//hello

虽然concat()是专门用来拼接字符串的方法,但实践中使用更多的还是加号操作符(+).而且,使用加号操作符在大多数情况下都比使用concat()方法要简便易行(特别是在拼接多个字符串的情况下).

ECMAScript还提供了三个基于子字符串创建新字符串的方法:slice(),substr()和substring().

这三个方法都会返回被操作字符串的一个子字符串,而且也都接受一或两个参数.第一个参数指定子字符串的开始位置,第二个参数(在指定的情况下)表示子字符串到哪里结束.slice()和substring()的第二个参数指定的是子字符串最后一个字符后面的位置.而substr()的第二个参数指定的则是返回的字符个数.如果没有给这些方法传递第二个参数,则将字符串的长度作为结束位置.与concat()方法一样,slice(),substr()和substring()也不会修改字符串本身的值--它们只是返回一个基本类型的字符串值,对原始字符串没有任何影响.

var stringValue="hello world";
  console.log(stringValue.slice(3));//lo world
  console.log(stringValue.substring(3));//lo world
  console.log(stringValue.substr(3));//lo world
  console.log(stringValue.slice(3,7));//lo w
  console.log(stringValue.substring(3,7));//lo w
  console.log(stringValue.substr(3,7));//lo worl

substr()返回"lo worl”,因为它的第二个参数指定的是要返回的字符个数.

在传递给这些方法的参数是负值的情况下,slice()方法会将传入的负值与字符串的长度相加,substr()方法将负的第一个参数加上字符串的长度,而将负的第二个参数转换为0.最后,substring()方法会把所有负值参数都转换为0.

var stringValue="hello world";
  console.log(stringValue.slice(-3));//rld
  console.log(stringValue.substring(-3));//hello world
  console.log(stringValue.substr(-3));//rld
  console.log(stringValue.slice(3,-4));//lo w
  console.log(stringValue.substring(3,-4));//hel
  console.log(stringValue.substr(3,-4));//(空字符串)

注意:IE的JavaScript实现在处理向substr()方法传递负值的情况时存在问题,它会返回原始的字符串.IE9修复了这个问题.

当第二个参数是负值时,三个方法的行为各不相同.slice()方法会把第二个参数转换成7,substring()方法会把第二个参数转换为0,而由于这个方法会将小的数作为开始位置,将较大的数作为结束位置.substr()也会将第二个参数转换成0,也就意味着返回包含零个字符的字符串,也就是一个空字符串.

3.字符串位置方法

有两个可以从字符串中查找子字符串的方法:indexOf()和lastIndexOf().这两个方法都是从一个字符串中搜索给定的子字符串,然后返子字符串的位置(如果没有找到该字符串,则返回-1).

indexOf()方法从字符串的开头向后搜索子字符串,而lastIndexOf()方法是从字符串的末尾向前搜索子字符串.

var stringValue="hello world";
  console.log(stringValue.indexOf("o"));//4
  console.log(stringValue.lastIndexOf("o"));//7

如果"o”在这个字符串中仅出现一次,那么indexOf()和lastIndexOf()会返回相同的位置值.

这两个方法都可以接收可选的第二个参数,表示从字符串中的哪个位置开始搜索.换句话说,indexOf()会从该参数指定的位置向后搜索,忽略该位置之前的所有字符;而lastIndexOf()则会从指定的的位置向前搜索,忽略该位置之后的所有字符.

var stringValue="hello world";
  console.log(stringValue.indexOf("o"),6);//4 6
  console.log(stringValue.indexOf("o",6));//7
  console.log(stringValue.lastIndexOf("o",6));//4
var stringValue="Lorem ipsum dolor sit amet, consectetur adipisicing elit";
  var positions=new Array();
  var pos=stringValue.indexOf("e");
  while(pos>-1){
    positions.push(pos);
    pos=stringValue.indexOf("e",pos+1);
  }
  console.log(positions);//[3,24,32,35,52]

这个例子通过不断增加indexOf()方法开始查找的位置,遍历了一个长字符串.在循环之外,首先找到了"e"在字符串中的初始位置,而进入循环后,则每次都给indexOf()传递上一次的位置加1.这样,就确保了每次搜索都从上一次找到的子字符串的后面开始.每次搜索返回的位置依次被保存在数组positions中,以便将来使用.

4.trim()方法

ECMAScript 5为所有字符串定义了trim()方法.这个方法会创建一个字符串的副本,删除前置及后缀的所有空格,然后返回结果.

var stringValue="  hello world  ";
  var trimmedStringValue=stringValue.trim();
  console.log(stringValue);//  hello world  
  console.log(trimmedStringValue);//hello world

由于trim()返回的是字符串的副本,所以原始字符串中的前置及后缀空格会保持不变.支持这个方法的浏览器有IE9+,FF3.5+,Safari5+,Opera 10.5+和Chrome.此外,FF3.5+,Safari 5+和Chrome 8+还支持非标准的trimLeft()和trimRight()方法,分别用于删除字符串开头和末尾的空格.

5.字符串大小写转换方法

ECMAScript中涉及字符串大小写转换的方法有4个:toLowerCase(),toLocaleLowerCase(),toUpperCase()和toLocaleUpperCase().

var stringValue="hello world";
  console.log(stringValue.toLocaleUpperCase());//HELLO WORLD
  console.log(stringValue.toUpperCase());//HELLO WORLD
  console.log(stringValue.toLocaleLowerCase());//hello world
  console.log(stringValue.toLowerCase());//hello world

一般来说,在不知道自己的代码将在哪种语言环境中运行的情况下,还是使用针对地区的方法更稳妥一些.

6.字符串的模式匹配方法

String类型定义了几个用于在字符串中匹配模式的方法.第一个方法就是match(),在字符串上调用这个方法,本质上与调用RegExp的exec()方法相同.match()方法只接受一个参数,要么是一个正则表达式,要么是一个RegExp对象.

var text="cat,bat,sat,fat";
  var pattern=/.at/;
  //与pattern.exec(text)相同
  var matches=text.match(pattern);
  console.log(matches.index);//0
  console.log(matches[0]);//cat
  console.log(pattern.lastIndex);//0

本例中的match()方法返回了一个数组;如果是调用RegExp对象的exec()方法并传递本例中的字符串作为参数,那么也会得到与此相同的数组:数组的第一项是与整个模式匹配的字符串,之后的每一项(如果有)保存着与正则表达式中的捕获组匹配的字符串.

另一个用于查找模式的方法是search().这个方法的唯一参数与match()方法的参数相同:由字符串或RegExp对象指定的一个正则表达式.search()方法返回字符串中第一个匹配项的索引;如果没有找到匹配项,则返回-1.而且,search()方法始终是从字符串开头向后查找模式.

var text="cat,bat,sat,fat";
  var pos=text.search(/at/);
  console.log(pos);//1

为了简化替换子字符串的操作,ECMAScript提供了replace()方法.这个方法接受两个参数:第一个参数可以是一个RegExp对象或者一个字符串(这个字符串不会被转换成正则表达式),第二个参数可以是一个字符串或者一个函数.如果第一个参数是字符串,那么只会替换第一个子字符串.要想替换所有子字符串,唯一的办法就是提供一个正则表达式,而且要指定全局(g)标志.

var text="cat,bat,sat,fat";
  var result=text.replace("at","ond");
  console.log(result);//cond,bat,sat,fat
  result=text.replace(/at/g,"ond");//cond,bond,sond,fond

Langkah seterusnya ialah menggantikan semua "at" dengan "ond" dengan menukar parameter pertama kepada ungkapan biasa dengan bendera global.

Jika parameter kedua ialah rentetan, anda juga boleh menggunakan beberapa jujukan aksara khas untuk memasukkan nilai yang diperolehi oleh operasi ungkapan biasa ke dalam rentetan hasil.

Jujukan aksara khas yang disediakan oleh ECMAScript ini disenaraikan di bawah.

digunakan digunakan
Jujukan watak Teks pengganti
$$ $
$& Memadankan subrentetan keseluruhan corak yang sama dengan RegExp.lastMatch
$' Subrentetan sebelum subrentetan dipadankan Nilai yang sama seperti RegExp.leftContext
$` Subrentetan selepas subrentetan dipadankan Nilai yang sama seperti RegExp.rightContext
$n Padan dengan subrentetan kumpulan tangkapan ke-n, dengan n bersamaan dengan 0~9 Contohnya, $1 ialah subrentetan yang sepadan dengan kumpulan tangkapan pertama, dan $2 ialah subrentetan yang sepadan dengan kumpulan tangkapan kedua hidup. Jika tiada kumpulan penangkapan ditakrifkan dalam ungkapan biasa, rentetan kosong
$nn Padan dengan subrentetan kumpulan tangkapan ke-n, dengan nn bersamaan dengan 01~99 Contohnya, $01 ialah subrentetan yang sepadan dengan kumpulan tangkapan pertama, $02 ialah subrentetan yang sepadan dengan kumpulan tangkapan kedua, jadi Dan seterusnya. . Jika tiada kumpulan penangkapan ditakrifkan dalam ungkapan biasa, rentetan kosong

通过这些特殊的字符序列,可以使用最近一次匹配结果中的内容.

var text="cat,bat,sat,fat";
  result=text.replace(/(.at)/g,"word ($1)");
  console.log(result);//word(cat),word(bat),word(sat),word(fat)

在此,每个以".at”结尾的单词都被替换了,替换结果是"word"后跟一对圆括号,而圆括号中是被字符序列$1所替换的单词.

replace()方法的第二个参数也可以是一个函数.在只有一个匹配项(即与模式匹配的字符串)的情况下,会向这个函数传递3个函数:模式的匹配项,模式匹配项在字符串的位置和原始字符串.在正则表达式中定义了多个捕获组的情况下,传递给函数的参数 依次是模式的匹配项,第一个捕获组的匹配项,第二个捕获组的匹配项....,但最后两个参数仍然分别是模式的匹配项在字符串中的位置和原始字符串.这个函数应该返回一个字符串,表示应该被替换的匹配项使用函数作为replace()方法的第二个参数可以实现更加精细的替换操作.

function htmlEscape(text){
    return text.replace(/[<>"&]/g,function(match,pos,originalText){
      switch(match){
        case "<":
          return "<";
        case ">":
          return ">";
        case "&":
          return "&";
        case "\"":
          return """;
      }
    });
  }
  console.log(htmlEscape("<p class=\"greeting\">Hello world!</p>*"));//<p class="greeting">Hello world!</p>*

这里,我们为插入HTML代码定义了函数htmlEscape(),这个函数能够转义4个字符:小于号,大于号,和号以及双引号.实现这种转义的最简单方式,就是使用正则表达式查找这几个字符,然后定义一个能够针对每个匹配的字符返回特定HTML实例的函数.

最后一个与模式匹配有关的方法是split(),这个方法可以基于指定的分隔符将一个字符串分割成多个子字符串,并将结果放在一个数组中.分隔符可以是字符串,也可以是一个RegExp对象(这个方法不会将字符串看成正则表达式).split()方法可以接受可选的第二个参数,用于指定数组的大小,以便确保返回的数组不会超过既定大小.

var colorText="red,blue,green,yellow";
  var color1=colorText.split(",");
  console.log(color1);//["red", "blue", "green", "yellow"]
  var color2=colorText.split(",",2);
  console.log(color2);//["red", "blue"]
  var color3=colorText.split(/[^\,]+/);
  console.log(color3);//["", ",", ",", ",", ""]

在最后一次调用split()返回的数组中,第一项和最后一项是两个空字符串.之所以会这样,是因为通过正则表达式指定的分隔符出现在了字符串的开头(即子字符串"red")和末尾(即子字符串"yellow").

对split()中正则表达式的支持因浏览器而异.尽管对于简单的模式没有什么差别,但对于未发现匹配项以及带有捕获组的模式,匹配的行为就不大相同了.以下是几种觉的差别.

IE8及之前的版本会忽略捕获组.IE9能正确地在结果中包含捕获组.

FF3.6及之前版本在捕获组未找到匹配项时,会在结果数组中包含空字符串;ECMA-262规定没有匹配项的捕获组在结果数组中应该用undefined表示.

在正则表达式中使用捕获组时还有其他微妙的差别.

7.localeCompare()方法

这个方法比较两个字符串,并返回下列值中的一个:

如果字符串在字母表中应该排在字符串参数之前,则返回一个负数(大多数情况下是-1,具体的值要视实现而定)

如果字符串等于字符串参数,则返回0.

如果字符串在字母表中应该排在字符串参数之后,则返回一个正数(大多数情况下是1,具体的值同样要视实现而定)

var stringValue="yellow";
  console.log(stringValue.localeCompare("brick"));//1
  console.log(stringValue.localeCompare("yellow"));//0
  console.log(stringValue.localeCompare("zoo"));//-1

因为localeCompare()返回的数值取决于实现,所以最好是像下面例子所示的这样使用这个方法.

function determineOrder(value){
    var result=stringValue.localeCompare(value);
    if(result<0){
      console.log("The string 'yellow' comes before the string '"+value+"'.");
    }else if(result>0){
      console.log("The string 'yellow' comes after the string '"+value+ "'.");
    }else{
      console.log("The string 'yellow' is equal to the string '"+value+"'.");
    }
  }
  determineOrder("brick");
  determineOrder("yellow");
  determineOrder("zoo");

8.fromCharCode()方法

另外,String构造函数还有一个静态方法:fromCharCode().这个方法的任务是接收一或多个字符编码,然后将它们转换成一个字符串.从本质上来看,这个方法与实例方法charCodeAt()执行的是相反的操作.

以上内容是小编给大家介绍的关于JavaScript高级教程5.6之基本包装类型(详细),希望大家喜欢。

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn