主要总结
JavaScript的六种数据类型:Boolean、Number、String、Null、Undefined、Object
布尔类型
布尔真假判定:短路原则
x && y
只有在x
和y
都为真的情况下为真。即真真为真,短路:因比较运算为左结合运算,若x为假,&&后面表达式不执行x || y
y
或x
有一个为真的情况下即为真。即一真为真,短路:若x为真,则短路跳出,||后面表达式不执行!x
只有在x非真情况下为真
数值类型
数值大小及精度控制:
JavaScript的数值与大多数编程语言的数值一样,不同于我们日常所见的理想化数值。首先,它们收到计算设备固定大小的物理元件的限制。因此,存在一个最大的数值(在JavaScript里这个值约为
1.79e308
)和一个最小的数值(-1.79e108
)。任何计算得到超过最大数值或者小于最小数值,都会转化为特殊值Infinity
或者-Infinit
y。-
精度不够的问题注意以下几点:
可表示的数值密集度集中在0左右,事实上有一多半都介于1和-1之间;离0越远,就越稀疏。
所有介于正负9e15之间的数都可以精确表示,在这个范围之外,只有部分整数可以表示。
涉及非常大的数值、非常小的数值或者非整数的计算,经常会导致不准确的结果。
关于NaN:
1. `NaN`这个特殊值代表的是**“Not a Number”,**他会在数学计算**得到了非数学意义上的结果**时出现
2. **NaN不等于任何值,也不等于NaN!**
3. **检测一个值是否为数值**,可用 `isNaN()` 方法。
4. 如果**想用十六进制表示整数,在数值前面加上**`0x`
常用数学计算方法:
-
Math.floor(x)
取得小于等于x的最大正整数Math.floor(2.99); // 2 Math.floor(-2.99); // -3
-
Math.ceil(x)
取得大于等于x的最小整数Math.ceil(3.99); // 4 Math.ceil(-3.99); // -3
-
Math.sqrt(x)
对x开方Math.sqrt(100); // 10
-
Math.random(x)
得到一个大于等于0,小于1的数Math.random(); // x大于等于0,小于10
-
Math.pow(x,y)
得到的是x的y次方Math.pow(2,4); // 16
字符串类型
概念及意义:
字符集由一组特定的字符组成,其中每个字符都有唯一的编号,叫码点(codepoint)。与大多数语言一样,JavaScript使用unicode字符集。unicode字符集一般用十六进制为每个字符编码。
要了解全部码点,可访问Unicode码点。-
反斜杠不仅用于通过码点来表示字符,而且也用于与后续字符组织成所谓的转义序列
\'
单引号\"
双引号\xhh
hh是两位十六进制值,相应字符的码点\n、\t、\b、\f、\r、\v
换行符、制表符、退格符、进纸符、回车符、制表符\\
反斜杠本身
u加码点的方式只在JavaScript代码中有效。如果想在HTML文档显示字符,则需要在码点前加上
&#x
;
关注点分离:
大型页面中,所有样式规则也应该保存在一个单独的文件汇总。这样,文档的结构、样式、行为才能各安其位,相互分离。在软件工程中,关注点分离是一个非常重要的思想。
String 对象的方法 slice()、substring()
和 substr()
(不建议使用)都可返回字符串的指定部分。slice() 比 substring() 要灵活一些,因为它允许使用负数(!!!待验证,我的代码无法识别负数
)作为参数。slice()
与 substr()
有所不同,因为它用两个字符的位置来指定子串,而 substr()
则用字符位置和长度来指定子串。
字符串常用方法:
-
substr(start,length)
start
必需。一个非负的整数,规定要提取的子串的第一个字符在 stringObject 中的位置。length
可选。子串中的字符数。必须是数值。如果省略了该参数,那么返回从 stringObject 的开始位置到结尾的字串
-
slice(start,end)
要抽取的片断的起始下标。如果是负数,则该参数规定的是从字符串的尾部开始算起的位置。也就是说,-1 指字符串的最后一个字符,-2 指倒数第二个字符,以此类推
紧接着要抽取的片段的结尾的下标。若未指定此参数,则要提取的子串包括 start 到原字符串结尾的字符串。如果该参数是负数,那么它规定的是从字符串的尾部开始算起的位置
-
substring(start,stop)
必需。一个非负的整数,规定要提取的子串的第一个字符在 stringObject 中的位置
可选。一个非负的整数,比要提取的子串的最后一个字符在 stringObject 中的位置多 1。如果省略该参数,那么返回的子串会一直到字符串的结尾
-
indexOf(searchvalue,fromindex)
方法可返回某个指定的字符串值在字符串中首次出现的位置。
searchvalue
必需。规定需检索的字符串值。fromindex
可选的整数参数。规定在字符串中开始检索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略该参数,则将从字符串的首字符开始检索
。
-
lastIndexOf(searchvalue,fromindex)
lastIndexOf()
方法可返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。searchvalue
必需。规定需检索的字符串值。fromindex
可选的整数参数。规定在字符串中开始检索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略该参数,则将从字符串的最后一个字符处开始检索
。
-
charCodeAt(index)
charCodeAt()
方法可返回指定位置的字符的Unicode 编码
。这个返回值是0 - 65535
之间的整数。
方法charCodeAt()
与charAt()
方法执行的操作相似,只不过前者返回的是位于指定位置的字符的编码,而后者返回的是字符子串
。
-
charAt(index)
charAt()
方法可返回指定位置的字符。index
必需。表示字符串中某个位置的数字,即字符在字符串中的下标。如果参数
index
不在0
与string.length-1
之间,该方法将返回一个空字符串
-
toLowerCase()
andtoUpperCase()
这个不解释了
-
replace(regexp/substr,replacement)
replace()
方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。regexp/substr
必需。规定子字符串或要替换的模式的 RegExp 对象。请注意,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换为 RegExp 对象。-
regexp/substr
必需。规定子字符串或要替换的模式的 RegExp 对象。请注意,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换为 RegExp 对象。console.log("Hello,there".replace("ello","i")); // Hi,there
这个方法可以搭配正则表达式使用,后续会继续研究用法
-
注意几点:
-
slice()
和substring()
有一点共同的注意点:两个参数都为正整数情况下,最后返回的字符串中不包括最后一个被索引的字符!!!
-
var x = "Queen";
x.substring(1,4); // "uee"
x.substring(-1,2); // "Qu" 识别第二个参数,但是是从头部开始两个字母
x.substring(-4,-1); // "" 空字符,两个参数都不接收负数
x.substring(-3); // "Queen" 直接返回整个字符串
// substring(strat,stop)
x.slice(1,4); // "uee"
x.slice(-1,2); // ""
x.slice(-4,-2); // "ue"
x.slice(0,-2); // "Que"
x.slice(-4); // "ueen"
// slice(start,end)
// 共同点!已表达式s.substring(x,y)或 s.slice (x,y)为例
// 都为正整数情况下,会得到字符串s中,从位置x开始直到(但不包含)位置y的所有字符。
var x = "abcdefg";
// 排列组合所有情况 (+)(-) and (a,b)
// (+,+) a>b or a<b
// (+,-) a>b
// (-,-) a>b or a<b
// (-,+) a<b
// 首先是——substring(a,b)
x.substring(5,1) // "bcde"
x.substring(1,5) // "bcde"
// 结论:当b>a,按照正常逻辑返回字符串,当b<a,将ab顺序调换,继续返回?
x.substring(1,-3) // "a"
x.substring(5,-3) // "abcde"
x.substring(7,-3) // "abcdefg"
x.substring(0,-3) // ""
// 结论:当处于(+,-),将按照a的数字(从1开始!),返回字符串中相应的字符(反常规则,没有0)
x.substring(-2,-5) // ""
x.substring(-5,-2) // ""
// 结论:都是负数,不执行
x.substring(-5,1) // "a"
x.substring(-5,4) //"abcd"
x.substring(-5,0) // ""
// 结论:a[-5]是c,但是返回的值和b的值有关
// slice(start,end)
x.slice(1,5) // "bcde"
x.slice(3,1) // "" x[3]索引大于x[1],但是返回空的字符串
// start必须小于end,从小到大
x.slice(2,-2) // "cde"
x.slice(5,-3) // "" 空字符串
x.slice(-5,-1) // x[-5]到x[-1]的位置,符合按从小到大规则
x.slice(-2,-3) // ""
x.slice(-5,5) // "cde"
x.slice(-3,1) // ""
对象
分清理解点运算符和方括号运算符,并灵活运用
-
什么情况下必须使用方括号表访问对象的属性?
使用了不能作为标识符的属性名的情况
将变量的值作为属性名使用的情况
将表达式的求值结果作为属性名使用的情况
// 自行使用console.log()或者alert()调用试验 var test = { 1:"one", name:"name", var:"var", '2 333':2333, "foo-bar":5, x:"x" }; test["1"]; // "one" test.1; // Unexpected number错误 test[1]; // Unexpected number错误 test["name"]; // "name" test.name; // "name" test.var; // "var" test["var"]; // "var" test["2 333"]; // 属性名含有空格必须用方括号 // 属性名不能使用数字! test.foo-bar; // 含有横杠的属性名点运算会引起错误,会解析为:obj.foo减去 bar,引发错误 test["foo-bar"]; // 5 // 下面展示将变量的值作为属性名使用的情况 var key = "name"; test[key]; // "name" 方括号内的变量存储的值依旧是引号包裹的字符串,方括号正常访问
理解对象引用
基本类型值直接存储在变量中,而对象不是。对象的值中存储的是指向对象的引用
由于对象的值其实是引用,所以把一个对象赋值给一个变量,实际上会产生该对象引用的一个副本,而不会赋值对象本身。换句话说,对象赋值不会产生新对象。想想看,对象的赋值与基本类型值赋值过程并没有不同。变量间的赋值就是把保存一个盒子里的东西赋值一份再保存到另一个盒子中,而该盒子中存储的可能是数值,也可能是一个引用。
对象与其他类型值的第二个重要的区别是:
对同一个对象字面量的每次求值,都会产生一个新对象。
对象原型
每个JavaScript对象都有一个暗藏的链接指向自己的原型对象(prototype),如果你读取的的属性不在对象本身上,那么JavaScript就会进一步查询这个对象的原型对象。如果在这个原型对象上也没找到,还会进一步查询原型对象的原型对象,以此类推。这个原型链最后一个对象的暗藏链接,应该指向null值。如果整个原型链都没有你想读取的属性,那么你会看到一个错误。
自有属性和继承属性:
字面意思先简单理解,自有属性在自身,直接访问,不需通过原型链。继承属性继承自原型,通过_proto_向上查询
自引用对象
对象的属性可以引用自身,两个对象也可以通过属性相互作用。但这种情况下,光靠对象字面量无法描述:
先使用对象字面量创建对象的部分属性,然后在通过赋值方式定义其他属性。当然也可以为彼此赋值。
数组
概念:数组是一种特殊的对象,它的属性是从0开始的连续非负整数,而且有一个名为length的对应属性。
数组引用示意图
常用方法:
slice(start,end)
略....
-
concat(arrayX,arrayX,......,arrayX)
concat()
方法用于连接两个或多个数组。该方法不会改变现有的数组
,而仅仅会返回被连接数组的一个副本。arrayX
必需。该参数可以是具体的值,也可以是数组对象。可以是任意多个。
var a = [1,2,3]; var b = ["one","two","three"]; var c = a.concat(b); console.log(c.length) // 6 console.log(a.length+" | "+b.length) // 3 | 3
-
join(separator)
join()
方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。separator
可选。指定要使用的分隔符。如果省略该参数,则使用逗号作为分隔符。
var arr = [1,2,3,4,5,6];
console.log(arr.join()) // "1,2,3,4,5,6"
console.log(arr.join("|")) // "1|2|3|4|5|6"
-
split(separator,howmany)
split()
方法用于把一个字符串
分割成字符串数组。(接受一个字符串,返回的是把字符串分割后各元素组成的数组
)separator
必需。字符串或正则表达式,从该参数指定的地方分割 stringObject。-
howmany
可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。
var os = "Windows Macos Unix Linux android、ios、WP ...";os.split(" ") // "Windows,Macos,Unix,Linux,android、ios、WP,..." os.split("、") // "Windows Macos Unix Linux android,ios,WP ..." "hello world!".split("") // "h,e,l,l,o, ,w,o,r,l,d,!" "how,are,you,?".split(",",2) // "how,are" "1|2|3|4|5".split("|",4) // "1,2,3,4" // separator参数注意是空格符(" "),还是默认(""),具体情况具体分析
数组头尾的增删方法:
-
末尾添加:
push(newelement1,newelement2,....,newelementX)
push()
方法可向数组的末尾添加一个或多个元素,并返回新的长度。push()
方法可把它的参数顺序添加到arrayObject
的尾部。它直接修改arrayObject
,而不是创建一个新的数组。push()
方法和pop()
方法使用数组提供的先进后出栈的功能。
var arr = [1,2,3];
arr.push(4,5,6);
arr.push(["one","two","three"],["a","b","c"])
console.log(arr[4]) // "5"
console.log(arr[6]+" | "+arr[7]) // "one,two,three | a,b,c"
// 添加若干元素,或者添加若干数组
-
末尾删除:
pop()
pop()
方法将删除arrayObject
的最后一个元素,把数组长度减 1,并且返回它删除的元素的值
。如果数组已经为空,则pop()
不改变数组,并返回 undefined 值。
var arr = [1,2,3];
arr.push(4,5,6);
arr.push(["one","two","three"],["a","b","c"])
console.log(arr[4]) // "5"
console.log(arr[6]+" | "+arr[7]) // "one,two,three | a,b,c"
console.log(arr.pop()) // "a,b,c"
console.log(arr.pop()) // "one,two,three"
console.log(arr.length) // 6
-
头部添加:
unshift(newelement1,newelement2,....,newelementX)
unshift()
方法将把它的参数插入 arrayObject 的头部,并将已经存在的元素顺次地移到较高的下标处,以便留出空间。该方法的第一个参数将成为数组的新元素 0,如果还有第二个参数,它将成为新的元素 1,以此类推。newelement1
必需。向数组添加的第一个元素。newelement2
可选。向数组添加的第二个元素。newelementX
可选。可添加若干个元素。
var arr = [1,2,3];
arr.unshift(0,[-1,-2,-3],{x:"x",y:"y"})
arr[0] // 0 传入的第一个参数索引值为0
arr[1] // "-1,-2,-3"
arr[2] // "object"
-
头部删除:
shift()
shift()
方法用于把数组的第一个元素从其中删除,并返回第一个元素的值
。如果数组是空的,那么 shift() 方法将不进行任何操作,返回 undefined 值。请注意,该方法不创建新数组,而是直接修改原有的 arrayObject。
var arr = [1,2,3];
arr.unshift(0,[-1,-2,-3],{x:"x",y:"y"})
console.log(arr.shift()) // "0"
console.log(arr.shift()) // "-1,-2,-3"
console.log(arr.shift()) // "[object Object]"
console.log(arr.length) // 3
类型转换
-
弱类型
转换为数值:false被转换为0,true被转换为1,字符串为转换成可能的值,null被转换成0;如果无法把字符转换成数值,则转换成NaN。对象x会调用x.valueOf();
转换为布尔值:
除了0、空字符串("")、null、undefined、NaN
。其他值都被转换成true
。false一般称为假值,true则为真值;转换为字符串:JavaScript会按常理处理,如例子所示。只是对象x会调用x.toString(),具体后面会讨论。关于valueOf和toString的详细解释,&&与||其实他们并不是真的需要比较布尔值,后续继续讨论。
-
isNaN(x)
isNaN()
函数可用于判断其参数是否是NaN
,该值表示一个非法的数字(比如被 0 除后得到的结果)。
把NaN
与任何值(包括其自身)相比得到的结果均是 false,所以要判断某个值是否是 NaN,不能使用 == 或 === 运算符。正因为如此,isNaN() 函数是必需的。-
isNaN()
函数通常用于检测parseFloat()
和parseInt()
的结果,以判断它们表示的是否是合法的数字。当然也可以用isNaN()
函数来检测算数错误,比如用 0 作除数的情况。isNaN(true); // false,因为true转换成了1 isNaN(null); // false,因为null转换成了0 isNaN("water"); // true,很明显 isNaN("100"); // false,因为"100"转换成了100
-
parseFloat(string)
parseFloat
将它的字符串参数解析成为浮点数并返回。如果在解析过程中遇到了正负号(+ 或 -)、数字 (0-9)、小数点,或者科学记数法中的指数(e 或 E)以外的字符,则它会忽略该字符以及之后的所有字符,返回当前已经解析到的浮点数。同时参数字符串首位的空白符会被忽略。-
如果参数字符串的第一个字符不能被解析成为数字,则 parseFloat 返回 NaN。
console.log(parseFloat("23.9")); // 23.9 console.log(parseFloat("5.663E2")); // 566.3 console.log(parseFloat(" 8.11 ")); // 8.11 console.log(parseFloat("52.3xyz")); // 52.3 console.log(parseFloat("xyz52.3")); // NaN console.log(parseFloat("3 .5 .6")); // 3 console.log(parseFloat("123456 454")); // 123456 // 首尾空格忽略 // 除了+、-、数字、小数点、科学计数法(E或e)这些符号,其他的字符本身以及后面的所有字符都会被忽略 // 如果参数字符串第一个字符串不能被解析为数字,会直接返回NaN
-
parseInt(string, radix)
只有字符串中的第一个数字会被返回。
开头和结尾的空格是允许的。
提示:如果字符串的第一个字符不能被转换为数字,那么 parseFloat() 会返回 NaN。
console.log(parseInt("23.9")); // 23 console.log(parseInt("5.663E2")); // 5 console.log(parseInt(" 8.11 ")); // 5 console.log(parseInt("52.3xyz")); // 52 console.log(parseInt("xyz52.3")); // NaN // 使用parseInt可以转换基数为2到36的任何数值,进制转换 console.log(parseInt("75EF2",16)); // 483058 console.log(parseInt("50",8)); // 40 console.log(parseInt("110101",2)); // 53 console.log(parseInt("hello",30)); // 14167554 console.log(parseInt("36",2)); // NaN
显式转换
// 惯用的数据类型转换方法(最简短的写法)
// 从数值转换为字符串值
var n = 3;
String(n); // 正式写法
n+""; // 将数值3转换为字符串值"3"(利用字符串连接符)
// 从字符串值转换为数值
var s = "3";
Number(s); // 正式写法
+s; // 将字符串值"3"转换为了数值3(利用了正号运算)
-
松散相等操作符
简单归纳为:严格相等运算符
===
和!==
不会进行类型转换,而相等运算==
和!=
会在判断前进行类型转换-
要确定
x == y
的结果,JavaScript会尝试对它们进行类型转换,以便比较。如果x和y中有一个字符串,有一个数值,JavaScript会把字符串转换成数值
如果一个是布尔值,另一个不同,JavaScript会把布尔值转换成数值。
如果是一个对象,另一个是字符串是或数值,JavaScript会把对象转换成字符串或者数值。
最后,
undefined == null
,null == undefined
。待寻找原因。
-
typeof
操作符
typeof 101.3; // number
typeof false; // boolean
typeof "dog"; // string
typeof {x:1,y:2}; // object
typeof undefined; // undefined
typeof null; // object
typeof [1,2,3]; // object
typeof alert; // function
typeof (typeof 1); // string
typeof Infinity); // number
typeof NaN); // number
练习
-
1
:设x = 10,y= 4,b = false
,求下列表达式的值-
x > y >25 && !b || y % -3 !== 22
(((( x > y ) >25) && !b) || ((y % -3) !== 22 ))
true
-
y * 4 === 2 || (b !== true)
(((y * 4) === 2) || (b !== true))
true
加上括号就一目了然了,主要考察运算符优先级和运算符的结合性
-
-
2
:证明a和b均为布尔值,则!a && !b || a && b
与a === b
的结果一样。可以把一式简化成:
!(a && b) || a && b
蠢方法排列组合出的4种情况,代入测试。但是不知道怎么从数学上证明,还没发现两者之间的联系。有看到有想法的读者忘告知!
3
:在本章中,我们看到Math.sqrt(100)
等于10
。点号的使用以为着Math是一个对象,sqrt是它的一个属性。可以试试在编辑器里计算Math["sqrt"](100)
,看结果是否支持是对象的推断。
console.log(Math["sqrt"](100)); // 10
var mi = "pow";
console.log(Math[mi](2,3)); // 8
// 可以看出,Math的确是一个对象,并且是一个全局对象,其中包含了如sqrt、pow在内的运算属性(方法)。
-
4
:使用命令行界面计算~22、~105、~(-28)和其他一些对整个数值应用~的表达式。然后尝试总结这个操作有什么作用。这里涉及到了JS中位运算的相关知识,但是我还没具体了解过,算是待完善的知识点。先送上两篇大神文,之后会另外开设一篇来谈谈我的理解。
5
:运行下列脚本:输入0、37、-40和100.然后再次输入dog、2e600、3ffc和Infinity。 每次运行后,说出观察到的结果是否有意义,如果没有,请解释为什么结果与预期的不符。
var celsius = prompt("Enter a temperature in \u00b0C");
var fahrenheit = 1.8*celsius+32;
alert(celsius+"\u00b0C= "+fahrenheit+"\u00b0F")
// f=1.8*celsius+32
语句意义:获取用户输入的值,将值进行运算处理,弹出值。需要注意的是,
prompt()
方法会把输入的值全部转换为string
型。变量
fahrenheit
里的运算会把字符串隐式转换为数值,然后再进行数学意义上的计算。但是如果输入的是字符串的话,隐式转换后是NaN
,而NaN
进行任何计算结果都将是NaN
。-
2e600转换为数值后显然超过了JS可表示的数字,将会显示
Infinity
,任何计算都将是Infinity
。console.log(5/0); // Infinity 0作为被除数,结果为Infinity console.log(0/0); // NaN console.log(Infinity+Infinity); // Infinity console.log(Infinity-Infinity); // NaN console.log(Infinity*Infinity); // Infinity console.log(Infinity/Infinity); // NaN console.log(Math.sqrt(Infinity)); // Infinity
-
6
:对下列表达式求值:"one two three".split(" "); // result:[one,two,three] "abracadabra".split("a"); // result:[,br,c,d,br,]
7
:编写一个表达式,该表达式在字符串s包含逗号时返回true,否认返回false。
var s = prompt("enter a something").indexOf(",")
if (s!==-1) {
return true;
} else {
return false;
};
8
:画出如下对象的示意图,你认为这个对象表示什么意思?
var obj = {op:"+",l:{op:"*",l:{op:"-",l:3,r:9},r:7},r:{op:"/",l:9,r:{op:"+",l:8,r:2}}};
// 可以变形后如下,其实就是对象的嵌套
var obj1 = {
op:"+",
l:{
op:"*",
l:{
op:"-",
l:3,
r:9
},
r:7,
},
r:{
op:"/",
l:9,
r:{
op:"+",
l:8,
r:2
}
}
};
-
9
:求值下列表达式并解释结果。5 < 10 < 20
-20 < -10 < -5
第二题我很费解,我的理解是, 按运算符优先级,结合性和隐式转换方面考虑这两道题,可问题是对于第二题的结果却是
false
!?小于号左结合,于是相当于(-20<-10)< -5
,很明显括号内运算结果为true
,但问题来了。true<-5
不应该把-5
隐式转换为true
吗?这类比较符号返回值永远是布尔值,但是却得到了一个false
?。
更新:想来是我理解出现了错误,对于何时需要数值,何时需要布尔值不清楚。现在明白了,如下代码:
console.log(-20<-10<-5) // false
console.log(-20<-10) // true
// 问题如下
console.log(true<-5) // false
console.log(true<5) // true
// 可能?
console.log(1<5) // true被转换为了1?
在
<、<=、>、>=、+、-、*、/、%
是需要数值的,即可能会发生隐式转换为数值这一行为。
解释parseInt("250",3)得到的结果。
-
先上结果:
console.log(parseInt("250",3)) // 2
-
合理的假设是,当接受数值不符合进制转换要求,会尽可能将可转换的数字(2)转换。所以这次得出一个:2
console.log(parseInt("115",2)) // (11)2 : 3 console.log(parseInt("129",8)) // (12)8 : 10 console.log(parseInt("FZ",16)) // (F)16 : 15
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。