js 运算符

JS 运算符

要进行各种各样的运算,就要使用不同的运算符号。

1、算术运算符:+-*/%++--

       A = 10 + 20;

       A = 10 – 20;

       A = 10 * 20;

       A = 10 / 20;

       (1)“%”取余运算符,两个数相除,取余数。

              A = 10 % 3;  // A = 1,如果余数不为0,则两个不能整除

           A = 10 % 2;  // A = 0,如果余数为0,则两个数能除尽

       (2)“++”加1运算符、自加1

              “++”可以作前缀(++i),也可以作后缀(i++)。

              如果不赋值的话,i++和++i的结果是一样的。

      如果要赋值的话,i++和++i的结果就不一样了

       (3)“--”减1运算符,自减1

              “--”可以作前缀(--i),也可以作后缀(i--)。

              如果不赋值的话,i--和--i的结果是一样的。

              如果要赋值的话,i++和++i的结果就不一样了

2、赋值运算符:=+=-=*=/=

       “+=”先加后等。如:a += 10  //展开后  a = a + 10

       “-=”先减后等。如:a -= 10   //展开后  a = a - 10

       “*=”先乘后等。如:a *= 10  //展开后  a = a * 10

       “/=”先除后等。如:a /= 10   //展开后  a = a / 10

3、字符串运算符:++=

       字符串只能进行“连接”运算,不能进行其它运算。

       var a = “abc”;

       var b = a + “def”;   // 结果b = a + “def” = “abc” + “def” = “abcdef”

       var a = “abc”;

       a += 10;   // 结果a = a + 10 = “abc” + 10 = “abc10”

4、比较运算符:><>=<===!====!==

       比较运算符的运算结果是布尔值(true或false)

       A = 10 > 20;       // 结果A=false

       A = 20>=20;       // 结果A=true

       A = 10%2 == 0;    // 结果A=true

       A = 10%2 == “0”;  // 结果A=true

       A = 10%3 != 0;    // 结果A=true

       A = 10%2 === “0”;  //结果A=false

       “=”是赋值号。如:a = 10

       “==”等于。只比较两个变量的,而不管类型。只要值一样,就返回true,否则返回false。

       “===”全等于。既比较变量,也判断类型。如果类型和值都一样,返回true,否则返回false。

5、逻辑运算符:&&||!

       逻辑运算符的运算结果有两个true或false

       “&&”逻辑与(并且关系)。如果左右两个操作数都为true,则结果为true,否则,结果为false。

                     逻辑与,就是两个条件同时满足时,则结果为true。

  “||”逻辑或。左右两个条件,只要有一个满足,则返回true,否则,返回false。

  “!”取反运算。!true = false  、   !false = true  、 !100 = false

6、三元运算符:?:

       所谓“三元运算符”就是指三个操作数。

       语法:条件表达式 ? 结果1 : 结果2

       语法:操作数1 ? 操作数2 : 操作数3

       含义:如果条件为true,则执行“结果1”的代码;如果条件为false,则执行“结果2”的代码。

       其实:三元运算符,就是if else的变形形式。

JS 位运算

js按位运算符及其妙用

大多数语言都提供了按位运算符,恰当的使用按位运算符有时候会取得的很好的效果。

在我看来按位运算符应该有7个:

1、& 按位与

&是二元运算符,它以特定的方式的方式组合操作数中对应的位,如果对应的位都为1,那么结果就是1, 如果任意一个位是0 则结果就是0。

1 & 3的结果为1

那我们来看看他是怎么运行的

1的二进制表示为 0 0 0 0 0 0 1

3的二进制表示为 0 0 0 0 0 1 1

根据 & 的规则 得到的结果为 0 0 0 0 0 0 0 1,十进制表示就是1

2、| 按位或

|运算符跟&的区别在于如果对应的位中任一个操作数为1 那么结果就是1。

1的二进制表示为 0 0 0 0 0 0 1

3的二进制表示为 0 0 0 0 0 1 1

所以 1 | 3的结果为3

3、^ 按位异或

^运算符跟|类似,但有一点不同的是 如果两个操作位都为1的话,结果产生0。

1的二进制表示为 0 0 0 0 0 0 1

3的二进制表示为 0 0 0 0 0 1 1

所以 1 ^ 3的结果为2

4、~ 按位非

~运算符是对位求反,1变0,0变1,也就是求二进制的反码

1的二进制表示为 0 0 0 0 0 0 1

所以 ~1 的结果是-2

5、>> 右移

>>运算符使指定值的二进制所有位都右移规定的次数,对于其移动规则只需记住符号位不变,左边补上符号位即按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1。

1的二进制表示为 0 0 0 0 0 0 1

所以 1>>1的结果为0

6、<< 左移

<<运算符使指定值的二进制所有位都左移规定的次数,对于其移动规则只需记住丢弃最高位,0补最低位即按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。

1的二进制表示为 0 0 0 0 0 0 1

所以 1<<1的结果为2 7、>>> 无符号右移

>>>运算符忽略了符号位扩展,0补最高位,但是只是对32位和64位的值有意义。

位运算符在js中的妙用:

1、使用&运算符判断一个数的奇偶

偶数 & 1 = 0

奇数 & 1 = 1

那么0&1=0,1&1=1

2、使用~~,>>,<<,>>>,|来取整

~~3.14 = 3

3.14 >> 0 = 3

3.14 << 0 = 3 3.14 | 0 = 3 3.14 >>> 0 = 3(>>>不可对负数取整)

注意:~~-3.14 = -3 其它的一样

3、使用<<,>>来计算乘除

乘法:

1*2 = 2

1<>1 = 1(2/2的一次方)

4、利用^来完成比较两个数是否相等

1 ^ 1 = 0

1 ^ 非1数 !=0

所以同一个数……同一个数等于0,否则不等于0

5、使用^来完成值交换

a = 1

b = 2

a ^= b

b ^= a

a ^= b

结果a=2,b=1

6、使用&,>>,|来完成rgb值和16进制颜色值之间的转换

16进制颜色值转RGB:

1

2

3

4

5

6

7

function hexToRGB(hex){

    var hex = hex.replace("#","0x"),

        r = hex >> 16,

        g = hex >> 8 & 0xff,

        b = hex & 0xff;

    return "rgb("+r+","+g+","+b+")";

}

RGB转16进制颜色值:

1

2

3

4

5

function RGBToHex(rgb){

    var rgbArr = rgb.split(/[^\d]+/),

        color = rgbArr[1]<<16 | rgbArr[2]<<8 | rgbArr[3];

    return "#"+color.toString(16);

}

运行hexToRGB("#ffffff")返回"rgb(255,255,255)"

运行RGBToHex("rgb(255,255,255)")返回"#ffffff"

位运算应用场景:

  1. 偷懒简写(|): 取整、断言
  2. 标志位判断 (&): 权限控制
  3. 去掉高位/低位(&): 比较特定位、子网掩码
  4. 数值交换(^): 加密算法、生成随机数/哈希
  5. 构造属性集(|): 边界判断
  6. 缺省数值类型值(|):默认端口
  7. 位填充(>>): HEX2RGB、leftPad
  8. 试图提升算术运算性能

位运算示例:

1. 求 2 的 n 次方:

bitwiseES5ES6+
1 << nMath.pow(2, n)2 ** n

原理: 左移一位, 相当于将原数值与 2 相乘一次 , 即 m << n === m * Math.pow(2, n)

2. 求中间索引

bitwiseES5ES6+
arr.length >> 1Math.floor(arr.length / 2))-

原理: 右移一位,相当于原数值除 2 后向下取整

3. 判断索引存在

bitwiseES5ES6+
!!~'abc'.indexOf('d')'abc'.indexOf('d') !== -1'abc'.includes('d')

原理: 按位非 ~-1 === 0

4. 变量交换

bitwiseES5ES6+
a ^= b; b ^= a; a ^= b;t = a; b = a; b = t;[b, a] = [a, b]

原理: 按位异或 1 ^ 1 === 0, 0 ^ 0 === 1

5. 分支开关

bitwiseES5ES6+
flag ^= 1;flag = flag ? 0 : 1;-

原理: 按位异或 1 ^ 1 === 0, 0 ^ 0 === 1

6. 截取整数位

bitwiseES5ES6+
~~-9.9; -9.9>>0;parseInt(-9.9)Math.trunc(-9.9)

原理: 位运算会默认将非数字类型转换成数字类型再进行运算
注意:

  1. 以上值(还有 -9.9|0 ) 都为 -9, 而 Math.floor(-9.9) 值为 -10
  2. 位运算取整方法不适用超过32位整数最大值 2147483647 的数: 2147483649.4 | 0 的值为 -2147483647

ES6 扩展运算符 ...的使用

1  含义

扩展运算符( spread )是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

  1. console.log(...[1, 2, 3])

  2. // 1 2 3

  3. console.log(1, ...[2, 3, 4], 5)

  4. // 1 2 3 4 5

  5. [...document.querySelectorAll('div')]

  6. // [<div>, <div>, <div>]

该运算符主要用于函数调用。

  1. function push(array, ...items) {

  2. array.push(...items);

  3. }

  4. function add(x, y) {

  5. return x + y;

  6. }

  7. var numbers = [4, 38];

  8. add(...numbers) // 42

上面代码中,array.push(...items)和add(...numbers)这两行,都是函数的调用,它们的都使用了扩展运算符。该运算符将一个数组,变为参数序列。

扩展运算符与正常的函数参数可以结合使用,非常灵活。

  1. function f(v, w, x, y, z) { }

  2. var args = [0, 1];

  3. f(-1, ...args, 2, ...[3]);

2  替代数组的 apply 方法

由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了。

  1. // ES5 的写法

  2. function f(x, y, z) {

  3. // ...

  4. }

  5. var args = [0, 1, 2];

  6. f.apply(null, args);

  7. // ES6 的写法

  8. function f(x, y, z) {

  9. // ...

  10. }

  11. var args = [0, 1, 2];

  12. f(...args);

下面是扩展运算符取代apply方法的一个实际的例子,应用Math.max方法,简化求出一个数组最大元素的写法。

  1. // ES5 的写法

  2. Math.max.apply(null, [14, 3, 77])

  3. // ES6 的写法

  4. Math.max(...[14, 3, 77])

  5. // 等同于

  6. Math.max(14, 3, 77);

上面代码表示,由于 JavaScript 不提供求数组最大元素的函数,所以只能套用Math.max函数,将数组转为一个参数序列,然后求最大值。有了扩展运算符以后,就可以直接用Math.max了。

另一个例子是通过push函数,将一个数组添加到另一个数组的尾部。

  1. // ES5 的写法

  2. var arr1 = [0, 1, 2];

  3. var arr2 = [3, 4, 5];

  4. Array.prototype.push.apply(arr1, arr2);

  5. // ES6 的写法

  6. var arr1 = [0, 1, 2];

  7. var arr2 = [3, 4, 5];

  8. arr1.push(...arr2);

上面代码的 ES5 写法中,push方法的参数不能是数组,所以只好通过apply方法变通使用push方法。有了扩展运算符,就可以直接将数组传入push方法。
下面是另外一个例子。

  1. // ES5

  2. new (Date.bind.apply(Date, [null, 2015, 1, 1]))

  3. // ES6

  4. new Date(...[2015, 1, 1]);

3  扩展运算符的应用

( 1 )合并数组

扩展运算符提供了数组合并的新写法。

  1. // ES5

  2. [1, 2].concat(more)

  3. // ES6

  4. [1, 2, ...more]

  5. var arr1 = ['a', 'b'];

  6. var arr2 = ['c'];

  7. var arr3 = ['d', 'e'];

  8. // ES5 的合并数组

  9. arr1.concat(arr2, arr3);

  10. // [ 'a', 'b', 'c', 'd', 'e' ]

  11. // ES6 的合并数组

  12. [...arr1, ...arr2, ...arr3]

  13. // [ 'a', 'b', 'c', 'd', 'e' ]

( 2 )与解构赋值结合

扩展运算符可以与解构赋值结合起来,用于生成数组。

  1. // ES5

  2. a = list[0], rest = list.slice(1)

  3. // ES6

  4. [a, ...rest] = list

  5. 下面是另外一些例子。

  6. const [first, ...rest] = [1, 2, 3, 4, 5];

  7. first // 1

  8. rest // [2, 3, 4, 5]

  9. const [first, ...rest] = [];

  10. first // undefined

  11. rest // []:

  12. const [first, ...rest] = ["foo"];

  13. first // "foo"

  14. rest // []

如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。

  1. const [...butLast, last] = [1, 2, 3, 4, 5];

  2. // 报错

  3. const [first, ...middle, last] = [1, 2, 3, 4, 5];

  4. // 报错

( 3 )函数的返回值

JavaScript 的函数只能返回一个值,如果需要返回多个值,只能返回数组或对象。扩展运算符提供了解决这个问题的一种变通方法。

  1. var dateFields = readDateFields(database);

  2. var d = new Date(...dateFields);

上面代码从数据库取出一行数据,通过扩展运算符,直接将其传入构造函数Date。

( 4 )字符串

扩展运算符还可以将字符串转为真正的数组。

  1. [...'hello']

  2. // [ "h", "e", "l", "l", "o" ]

上面的写法,有一个重要的好处,那就是能够正确识别 32 位的 Unicode 字符。

  1. 'x\uD83D\uDE80y'.length // 4

  2. [...'x\uD83D\uDE80y'].length // 3

上面代码的第一种写法, JavaScript 会将 32 位 Unicode 字符,识别为 2 个字符,采用扩展运算符就没有这个问题。因此,正确返回字符串长度的函数,可以像下面这样写。

  1. function length(str) {

  2. return [...str].length;

  3. }

  4. length('x\uD83D\uDE80y') // 3

凡是涉及到操作 32 位 Unicode 字符的函数,都有这个问题。因此,最好都用扩展运算符改写。

  1. let str = 'x\uD83D\uDE80y';

  2. str.split('').reverse().join('')

  3. // 'y\uDE80\uD83Dx'

  4. [...str].reverse().join('')

  5. // 'y\uD83D\uDE80x'

上面代码中,如果不用扩展运算符,字符串的reverse操作就不正确。

( 5 )实现了 Iterator 接口的对象

任何 Iterator 接口的对象,都可以用扩展运算符转为真正的数组。

  1. var nodeList = document.querySelectorAll('div');

  2. var array = [...nodeList];

上面代码中,querySelectorAll方法返回的是一个nodeList对象。它不是数组,而是一个类似数组的对象。这时,扩展运算符可以将其转为真正的数组,原因就在于NodeList对象实现了 Iterator 接口。

对于那些没有部署 Iterator 接口的类似数组的对象,扩展运算符就无法将其转为真正的数组。

  1. let arrayLike = {

  2. '0': 'a',

  3. '1': 'b',

  4. '2': 'c',

  5. length: 3

  6. };

  7. // TypeError: Cannot spread non-iterable object.

  8. let arr = [...arrayLike];

上面代码中,arrayLike是一个类似数组的对象,但是没有部署 Iterator 接口,扩展运算符就会报错。这时,可以改为使用Array.from方法将arrayLike转为真正的数组。

( 6 ) Map 和 Set 结构, Generator 函数

扩展运算符内部调用的是数据结构的 Iterator 接口,因此只要具有 Iterator 接口的对象,都可以使用扩展运算符,比如 Map 结构。

  1. let map = new Map([

  2. [1, 'one'],

  3. [2, 'two'],

  4. [3, 'three'],

  5. ]);

  6. let arr = [...map.keys()]; // [1, 2, 3]

Generator 函数运行后,返回一个遍历器对象,因此也可以使用扩展运算符。

  1. var go = function*(){

  2. yield 1;

  3. yield 2;

  4. yield 3;

  5. };

  6. [...go()] // [1, 2, 3]

上面代码中,变量go是一个 Generator 函数,执行后返回的是一个遍历器对象,对这个遍历器对象执行扩展运算符,就会将内部遍历得到的值,转为一个数组。
如果对没有iterator接口的对象,使用扩展运算符,将会报错。

  1. var obj = {a: 1, b: 2};

  2. let arr = [...obj]; // TypeError: Cannot spread non-iterable object

ES5 和 ES6处理字符串的方法

ES5

检索字符串

indexOf

与数组方法类似。

stringObject.indexOf(searchvalue,fromindex)

fromindex规定在字符串中开始检索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略该参数,则将从字符串的首字符开始检索。

lastIndexOf

与indexOf相反。

indexOf和lastIndexOf方法对大小写敏感!

截取字符串

slice(start, end)

  1. start,要抽取的片断的起始下标,如果为负,则从尾部算起。
  2. end,要抽取的片段的结尾的下标,如果为负,则从尾部算起。
String.slice() 与 Array.slice() 相似

substring(start, stop)

  1. start必需。要抽取的片断的起始下标,不能为负。
  2. stop可选。比要提取的子串的最后一个字符的位置多1,不能为负。
如果参数 start 与 stop 相等,那返回一个空串。
如果 start 比 stop 大,那在提取子串之前会先交换这两个参数。
如果同时为负,则返回空串。
如果一个值为负,则转为0,而且如果start 比 stop 大,会交换值。

substr(start, length) --不推荐

  1. start,要抽取的片断的起始下标,如果为负,则从尾部算起。
  2. length,如果为负,则转为0。

trim(),trimLeft(),trimRight()

去除首尾空格。

正则相关

split

把一个字符串分割成字符串数组。

stringObject.split(separator, howmany) //separator必需,字符串或正则表达式
var str="How are you doing today?";
str.split(/\s+/);      //"How", "are", "you", "doing", "today?"
如果把空字符串 ("") 用作 separator,那么 stringObject 中的每个字符之间都会被分割。
String.split() 执行的操作与 Array.join 执行的操作是相反的。

match

可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。

stringObject.match(searchvalue | reg)

字符串检索

var str="Hello world!";
str.match('w');      //["w", index: 6, input: "Hello world!", groups: undefined]

正则检索

// 全局匹配
var str="1 plus 2 equal 3";
str.match(/\d+/g);      //["1", "2", "3"]

var str="1 plus 2 equal 3";
str.match(/\d+/);      //["1", index: 0, input: "1 plus 2 equal 3", groups: undefined]

replace

用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。

stringObject.replace(reg | substr, replacement)

字符串替换

'aaaccc'.replace('ccc', 'b');    //'aaab'

'aaaccc'.replace('bbb', 'b');    //'aaaccc'

'aaaccc'.replace('a', 'b');     //"baaccc"

正则替换

'aaaccc'.replace(/\w/, 'b')     //"baaccc"

//全局匹配
'aaaccc'.replace(/\w/g, 'b')    //"bbbbbb"

replacement
replacement 可以是字符串,也可以是函数。但是 replacement 中的 $ 字符具有特定的含义。

字符替换文本
字符替换文本
$1、$2、...、$99与 regexp 中的第 1 到第 99 个子表达式相匹配的文本。
$&与 regexp 相匹配的子串。
$`位于匹配子串左侧的文本。
$'位于匹配子串右侧的文本。
$$直接量符号。
'aa123BB'.replace(/([a-z]+)(\d+)([A-Z]+)/g, '$1'); // "aa"
'aa123BB'.replace(/([a-z]+)(\d+)([A-Z]+)/g, '$4'); // "$4"
    
'aa123BB'.replace(/([a-z]+)(\d+)([A-Z]+)/g, '$&'); //"aa123BB"
'aa123BB'.replace(/(\d+)/g, '$`'); //"aaaaBB"
'aa123BB'.replace(/(\d+)/g, "$'"); //"aaBBBB"
'aa123BB'.replace(/(\d+)/g, '$$'); //"aa$BB"
ECMAScript v3 规定,replace() 方法的参数 replacement 可以是函数而不是字符串。在这种情况下,每个匹配都调用该函数,它返回的字符串将作为替换文本使用。
'aaaccc'.replace(/\w/g, function() {
    return 'b';
});
//"bbbbbb"

'aaaccc'.replace(/\w/, function() {
    return 'b';
});
//"baaccc"

search

stringObject.search(searchvalue | reg)
'aaaccc'.search('ccc');    //3
'aaaccc'.search(/ccc/);    //3  
var str="Visit W3School!";
str.search(/W3School/);    //6
search() 对大小写敏感

其他

  1. big() 用大号字体显示字符串。
  2. blink() 显示闪动字符串。
  3. bold() 使用粗体显示字符串。
  4. sup() 把字符串显示为上标。
  5. sub() 把字符串显示为下标。
  6. strike() 使用删除线来显示字符串。
  7. small() 使用小字号来显示字符串。
  8. charAt() 返回在指定位置的字符。
  9. charCodeAt() 返回在指定的位置的字符的 Unicode 编码。
  10. toLocaleLowerCase() 把字符串转换为小写。
  11. toLocaleUpperCase() 把字符串转换为大写。
  12. toLowerCase() 把字符串转换为小写。
  13. toUpperCase() 把字符串转换为大写。
  14. toSource() 代表对象的源代码。
  15. toString() 返回字符串。
  16. valueOf() 返回某个字符串对象的原始值。

ES6

includes(), startsWith(), endsWith()

  • includes(searchValue, start):返回布尔值,表示是否找到了参数字符串。
  • startsWith(searchValue, start):返回布尔值,表示参数字符串是否在原字符串的头部。
  • endsWith(searchValue, start):返回布尔值,表示参数字符串是否在原字符串的尾部。
let s = 'Hello world!';

s.startsWith('world', 6);    // true
s.endsWith('Hello', 5);      // true
s.includes('Hello', 6);      // false
s.includes('o');             // true

repeat(value)

返回一个新字符串,表示将原字符串重复n次。

  • 如果value数是负数或者Infinity,会报错。但是,如果参数是 0 到-1 之间的小数,则等同于 0。
  • 如果value是字符串,则会先转换成数字。
  • value为NaN等同于 0。
  • value如果是小数,会被取整。
'a'.repeat(3);     // "aaa"
'a'.repeat(-1);    //VM449:1 Uncaught RangeError: Invalid count value
'a'.repeat('3n');  //""
'a'.repeat('3');   //"aaa"
'a'.repeat(NaN);   //""
'a'.repeat(1.6);   //"a"

padStart(),padEnd()

  • padStart(length, string)用于头部补全。
  • padEnd(length, string)用于尾部补全。
'aaa'.padStart(2, 'ab');            //"aaa"
'aaa'.padStart(10, '0123456789');   //"0123456aaa"
'aaa'.padStart(10)                  //"       aaa"
'aaa'.padEnd(6, 'cd')               //"aaacdc"

模板字符串

模板字符串(template string)是增强版的字符串,用反引号(`)标识。

let name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`    //"Hello Bob, how are you today?"

模板字符串中嵌入变量,需要将变量名写在${}之中。

JS表达式,可以进行运算,以及引用对象属性

let x = 1;
let y = 2;
`${x} + ${y} = ${x + y}`        //"1 + 2 = 3"

var obj = { a: 'eee'}
`obj ${obj}`                   //"obj [object Object]"

调用函数

function fn() {
  return "Hello World";
}

`foo ${fn()} bar`             //"foo Hello World bar"

标签模板

模板字符串可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为“标签模板”功能(tagged template)。

alert`123`; 等同于alert(123);

如果模板字符里面有变量,就不是简单的调用了,而是会将模板字符串先处理成多个参数,再调用函数。

let a = 5;
let b = 10;

function tag(s, v1, v2) {
  console.log(s);
  console.log(v1);
  console.log(v2);

  return "OK";
}

tag`Hello ${ a + b } world ${ a * b}`;
// 等同于 tag(['Hello ', ' world ', ''], 15, 50);

//["Hello ", " world ", "", raw: Array(3)]
//15
//50
//"OK"
  • 9
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值