JavaScript入门(二)

4 函数

4.1 定义函数

  1. 定义方式一
function abs(x){
            if(x>=0){
                return x;
            }else{}
            return -x;
        }
  1. 定义方式二,注意函数体结束后,末尾加分号,表示赋值语句结束
var abs = function (x){
            if(x>=0){
                return x;
            }else{}
            return -x;
        };
//注意函数体结束后,末尾加分号

function (x){…}这是一个匿名函数,但是可以把结果赋值给abs,通过abs就可以调用函数!

  1. 函数调用

    ①正常按顺序传入参数

    abs(10)
    10
    abs(-9)
    9
    

    以下两种情况为JavaScript特有,JavaScript允许传入任意个参数而不影响调用,因此传入的参数比定义的参数多也没有问题,虽然函数内部并不需要这些参数:传入参数也不影响。

    ②不传入参数

    abs()
    NaN
    

    ③传入实参个数多于形参个数

    abs(10,9,8,56)
    10
    
  2. arguments关键字

arguments是一个JS免费赠送的一个关键字。

它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。arguments类似Array但它不是一个Array

'use strict'
        var abs = function (x){
            console.log("x=>"+x);
            for(let i=0;i<arguments.length;i++){
                console.log("arg"+i+":"+arguments[i])
            }
            console.log("================");
            if(x>=0){
                return x;
            }else{}
            return -x;
        };
abs(10,9,8,-9,-7,6)
 x=>10
arg0:10
arg1:9
arg2:8
arg3:-9
arg4:-7
arg5:6
================
10

由于JavaScript函数允许接收任意个参数,于是我们就不得不用arguments来获取所有参数:

  1. rest

获取多余参数,为了获取除了已定义参数ab之外的参数,我们不得不用arguments,并且循环要从索引2开始以便排除前两个参数,这种写法很别扭,如果我们只是为了获得额外的rest参数,能否采用一种简介的方式呢?===》ES6中引入了rest参数

'use strict'
        function foo(a, b, ...rest) {
            console.log('a = ' + a);
            console.log('b = ' + b);
            console.log(rest);
        }
foo()
a = undefined
 b = undefined
 []

foo(1)
 a = 1
 b = undefined
 []

foo(2,3)
a = 2
 b = 3
[]

foo(3,4,5)
9 a = 3
 b = 4
 [5]

function sum(...rest) {
            let sum = 0;
            for(let i = 0;i < rest.length;i++){
                sum += rest[i]; }
            return sum;
        }

        // 测试:
        var i, args = [];
        for (i=1; i<=100; i++) {
            args.push(i);
        }
        if (sum() !== 0) {
            console.log('测试失败: sum() = ' + sum());
        } else if (sum(1) !== 1) {
            console.log('测试失败: sum(1) = ' + sum(1));
        } else if (sum(2, 3) !== 5) {
            console.log('测试失败: sum(2, 3) = ' + sum(2, 3));
        } else if (sum.apply(null, args) !== 5050) {
            console.log('测试失败: sum(1, 2, 3, ..., 100) = ' + sum.apply(null, args));
        } else {
            console.log('测试通过!');
        }
  1. 前面我们讲到了JavaScript引擎有一个在行末自动添加分号的机制,这可能让你栽到return语句的一个大坑:

  2. JavaScript引擎有一个在行末自动添加分号的机制,这可能让你栽到return语句的一个大坑,所以不要不要不要将return和你需要返回的值分行书写。

4.2 变量的作用域

在JavaScript中,var定义变量实际是有作用域的。

在函数体中声明的变量,在函数体外无法使用~(非要实现的话,可以研究闭包,我还没研究呢)

'use strict'
    function f() {
        var x = 1;
        x = x + 1;
    }
    x = x + 2;   //Uncaught ReferenceError: x is not defined

下面这种情况,两个函数各自独立,当然不会相互影响

function f() {
        var x = 1;
        x = x + 1;
    }
    function f1() {
        var x = "A";
        x = x + 1;
    }

嵌套时需要注意啦,内部函数可以调用外部函数的变量,反之不行

function f() {
        var x = 1;
        x = x + 1;
        function f1() {
            x = x + 2;
            console.log("inner:"+x);
    }
    
       console.log("outer:"+x);
    }
    f();

JavaScript中函数查找变量由内向外,假设自身已经有该变量,则自动屏蔽外部同名的变量。

function f() {
        var x = 1;
        x = x + 1;
        function f1() {
            var x = "a";
            x = x + 2;
            console.log("inner:"+x);
    }
       console.log("outer:"+x);
    }
    f();

上面并没有显示inner,因为没有调用函数f1()

'use strict'
    function f() {
        var x = 1;
        x = x + 1;
        function f1() {
            var x = "a";
            x = x + 2;
            console.log("inner:"+x);
    }
    f1();
       console.log("outer:"+x);
    }
    f();
}

变量作用域提升

JavaScript的引擎自动提升了变量的作用域。

JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部:

'use strict';
function foo() {
        var x = 'Hello, ' + y;
        console.log(x);
        var y = 'Bob';
    }

    foo();

虽然是strict模式,但语句var x = 'Hello, ' + y;并不报错,原因是变量y在稍后申明了。但是console.log显示Hello, undefined,说明变量y的值为undefined。这正是因为JavaScript引擎自动提升了变量y的声明,但不会提升变量y的赋值。

在JavaScript中遵守先声明后使用。

全局变量

'use strict';
    var x = 1;
    function f() {
        console.log(x)
    }
    f()
    console.log(x)

全局对象window

'use strict';
    //全局变量&函数
    var x = 1;
//以下四条等价
    alert(x);
    alert(window.x);//默认所有的全局变量都会绑定在window对象下
    window.alert(x);
    window.alert(window.x)
 'use strict';
    //全局变量
    var x = 1;

    window.alert(x);
    var orig_alert = window.alert;
    orig_alert(123)
    window.alert = function () {//由JS函数的第二种定义方式可知,对象即函数,

    }
    window.alert("我不能弹出");
//    恢复alert,将之前的对象赋值给它即可
    window.alert = orig_alert;
    window.alert("我回来了")

JavaScript实际上只有一个全局作用域,任何变量(函数也可视为变量),如果在函数体内没有找到,就会向外查找,如果最后在全局作用域都没有找到,报错ReferenceError

规范

由于我们所有的全局变量都会绑定到window上,如果不同的js文件,使用了相同的全局变量,就会导致冲突。如何减少冲突呢?

'use strict';
//唯一全局变量
    var MyFun = {};
    MyFun.name = "tom";
    MyFun.score = 89;
    MyFun.sum = function (x,y) {
        return x+y;
    }
    MyFun.sum(3,4);

把自己定义的变量放入自己定义的唯一全局变量空间中,降低不同js命名相同时造成的冲突问题。

jQuery=$,查

局部作用域let

'use strict';
    function f() {
        for(var i = 0;i<100;i++){
            
        }
        console.log(i+1);//出了作用域还能调用???
    }

ES6中使用let关键字

'use strict';
    function f() {
        for(let i = 0;i<100;i++){

        }
        console.log(i+1);//Uncaught ReferenceError: i is not defined
    }

一般建议使用let

常量const

由于varlet申明的是变量,如果要申明一个常量,在ES6之前是不行的,我们通常用全部大写的变量来表示“这是一个常量,不要修改它的值”:

ES6标准引入了新的关键字const来定义常量,constlet都具有块级作用域:常量的值无法改变

'use strict';
    const  PI = 3.14;
    console.log(PI);
    PI  = 3;// Uncaught TypeError: Assignment to constant variable.

变量作用域与解构赋值 - 廖雪峰的官方网站 (liaoxuefeng.com)

4.3 方法

定义方法

方法就是把函数放在对象里面,对象只有属性和方法两个东西

'use strict'
    var tom = {
        name:"tom",
        birth:"2010",
        //方法
        age :function () {
            //今年-出生年
            var now  = new Date().getFullYear();
            return now - this.birth;
        }
    }
    //属性
    tom.name
//方法,方法一定要带括号。
tom.age()    

this的含义是什么呢?

'use strict'
    function getAge() {
        //今年-出生年
        var now  = new Date().getFullYear();
        return now - this.birth;
    }
    var tom = {
        name:"tom",
        birth:"2010",
        //方法
        age :getAge
    }
    //tom.age()
    //11
    //getAge()       Uncaught TypeError: Cannot read properties of undefined (reading 'birth')
    //this的默认对象指向了window

this是无法指向的,默认指向调用它的那个对象;

apply

在js中可以控制this指向

getAge.apply(tom,[])
11

5 内部对象

标准对象

typeof 123
'number'
typeof '123'
'string'
typeof true
'boolean'
typeof NaN
'number'
typeof []
'object'
typeof{}
'object'
typeof Math.abs
'function'
typeof undefined
'undefined'

5.1 Date

基本使用

'use strict'
    var now = new Date();
//年月日 星期几  时分秒   时间戳
    now.getFullYear();
    now.getMonth();
    now.getDate()
    now.getDay();
    now.getHours()
    now.getMinutes();
    now.getSeconds();
    now.getTime();
    new Date(1633855548347)
    Sun Oct 10 2021 16:45:48 GMT+0800 (China Standard Time)
    

转换

now.toGMTString()//调用的是方法,而非属性
    'Sun, 10 Oct 2021 08:45:48 GMT'
    now.toDateString()
    'Sun Oct 10 2021'
    now.toLocaleString()
    '10/10/2021, 4:45:48 PM'
    now.toLocaleDateString()
    '10/10/2021'

5.2 JSON

JSON是什么?

早期,所有数据传输习惯使用xml文件

  • JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。
  • 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
  • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

在JavaScript一切皆对象,任何js支持的类型都可以用JSON来表示;number,string…

格式:

  • 对象,Map都使用{}
  • 数组,set都使用[]
  • 所有键值对都使用 key:value

JSON和JS对象的转换

'use strict'
    let user = {
        name : "tom",
        age : 3,
        gender : "male"
    }
//对象转化为JSON字符串
    let jsonuser = JSON.stringify(user);

    //json字符串转化为对象
    let user1 = JSON.parse(jsonuser);
    let user2 = JSON.parse('{"name":"tom","age":3,"gender":"male"}');

    // typeof user
    // 'object'
    // user
    // {name: 'tom', age: 3, gender: 'male'}
    // jsonuser
    // '{"name":"tom","age":3,"gender":"male"}'
    // user1
    // {name: 'tom', age: 3, gender: 'male'}
    // user2
    // {name: 'tom', age: 3, gender: 'male'}

JSON和JS字符串有啥区别呢?

let obj = {
        'a':"hello",
        b:"hellob"
    };
    let jsonstring = JSON.stringify(obj);
    //jsonstring = '{"a":"hello","b":"hellob"}'

5.3 Ajax

  • 原生的js写法,xhr异步请求
  • jQuery封装好的方法${#name}.ajax(""),
  • axios 请求

6. 面向对象

原型对象

JavaScript,Java,c#…面向对象;

JavaScript有些区别

类: 模板 原型对象(JavaScript)

对象: 具体的实例

在JavaScript中需要转换一下思路?????、

原型:

'use strict'
    let user = {
        name : "tom",
        age : 3,
        gender : "male",
        run:function () {
            console.log(this.name+"  is running....")
        }
    }
    let xiaoming = {
        name: "xiaoming"
    }
user.run()
tom  is running....

xiaoming.run()
Uncaught TypeError: xiaoming.run is not a function

开始魔幻了

'use strict'
    let user = {
        name : "tom",
        age : 3,
        gender : "male",
        run:function () {
            console.log(this.name+"  is running....")
        }
    };
    let xiaoming = {
        name: "xiaoming"
    };

    xiaoming.__proto__ = user;
user.run()
tom  is running....

xiaoming.run()
xiaoming  is running....

在加了xiaoming.__proto__ = user;相当于继承了user的方法和不重名属性,

再来看以下例子

 'use strict'
    let user = {
        name : "tom",
        age : 3,
        gender : "male",
        run:function () {
            console.log(this.name+"  is running....")
        }
    };
    let xiaoming = {
        name: "xiaoming"
    };

    xiaoming.__proto__ = user;
    let Bird = {
        fly:function () {
            console.log(this.name+"  is flying....")
        }
    }
    //小明从人变成鸟
    xiaoming.__proto__ = Bird;

xiaoming.fly()
xiaoming  is flying....

xiaoming.run()
 Uncaught TypeError: xiaoming.run is not a function

class继承

class关键字是在ES6引入的,

所有的 JavaScript 对象都会从一个 prototype(原型对象)中继承属性和方法:有的时候我们想要在所有已经存在的对象添加新的属性或方法。另外,有时候我们想要在对象的构造函数中添加属性或方法。使用 prototype 属性就可以给对象的构造函数添加新的属性:当然我们也可以使用 prototype 属性就可以给对象的构造函数添加新的方法:

function Student(name) {
        this.name = name;
    }
    //给student新增一个方法
    Student.prototype.hello = function () {
        console.log("hello")
    }
    Student.prototype.age =13;
    let xm = new Student("xiaoming");

ES6之后,类似于java语法

 //ES6之后
    class Person{
        constructor(name) {
            this.name = name;
        }
        hello(){
            alert("hello")
        }
    }
    let xl = new Person("xiaoli");

  1. 定义一个类 ,属性。方法
//ES6之后
    class Person{
        constructor(name) {
            this.name = name;
        }
        hello(){
            alert("hello")
        }
    }
    let xl = new Person("xiaoli");

  1. 继承
 //ES6之后
    class Student{
        constructor(name) {
            this.name = name;
        }
        hello(){
            alert("hello")
        }
    }
    class Pupil extends Student{
        constructor(name,age,grade) {
            super();
            this.age = age;
            this.grade = grade;
        }
        hello() {
            console.log("我是一个小学生,我叫"+name+"我"+this.age+"岁了,正在上"+this.grade+"年级")
        }
    }
    let xl = new Pupil("xiaoli",6,1);
    let tom = new Pupil("tom");
xl.age
6
xl.hello()
我是一个小学生,我叫我6岁了,正在上1年级

tom.age

tom.hello()
我是一个小学生,我叫我undefined岁了,正在上undefined年级

原型链

无限套娃

javascript——原型与原型链 - 雅昕 - 博客园 (cnblogs.com)

7. 操作BOM

浏览器介绍

JavaScript 和 浏览器 的关系?

浏览器中有JavaScript引擎???????????????

DOM是一套操作HTML标签的API(接口/方法/属性)
BOM是一套操作浏览器的API(接口/方法/属性)

常见的BOM对象

  • window:代表整个浏览器窗口(window是BOM中的一个对象,并且是顶级的对象)
  • Navigator :代表浏览器当前的信息,通过Navigator我们可以获取用户当前使用的是什么浏览器
  • Location: 代表浏览器当前的地址信息,通过Location我们可以获取或者设置当前的地址信息
  • History:代表浏览器的历史信息,通过History我们可以实现上一步/刷新/下一步操作(出于
    对用户的隐私考虑,我们只能拿到当前的浏览记录,不能拿到所有的历史记录)
  • Screen:代表用户的屏幕信息
    来源:https://www.jianshu.com/p/eac7f9dc3b17

BOM:浏览器对象模型

  • IE 6~11
  • Chrome
  • Safari
  • FireFox Linux默认浏览器
  • Opera

三方浏览器

  • QQ浏览器
  • 360浏览器

window对象(重要)

window 代表 浏览器窗口

window.innerWidth
459
window.outerWidth
1440
window.innerHeight
789
window.outerHeight
860
window.innerWidth
627
window.innerWidth
970
window.innerWidth
1189
//内外部高度和宽度,可以调整浏览器窗口再测试,看看有什么变化

Navigator

Navigator,封装了浏览器的信息

navigator.appName
'Netscape'
navigator.appVersion
'5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Edg/94.0.992.38'
navigator.cookieEnabled
true
navigator.userAgent
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Edg/94.0.992.38'
navigator.platform
'Win32'
navigator.usb
USB {onconnect: null, ondisconnect: null}

大多数时候,我们不会使用navigator对象,因为会被人为修改!

不建议使用这些属性来编写代码,因为会被修改!!!!!

screen

screen.width
1440
screen.height
900
screen.availHeight
860

screen.colorDepth
24
screen.constructor
ƒ Screen() { [native code] }
screen.orientation
ScreenOrientation {angle: 0, type: 'landscape-primary', onchange: null}
screen.pixelDepth
24

location(重要)

location代表当前页面的URL信息

location.host//主机
'www.baidu.com'
location.hostname
'www.baidu.com'
location.protocol//协议
'https:'
location.reload()//刷新网页
//设置新地址
location.assign('https://www.bilibili.com/')

location
Location {ancestorOrigins: DOMStringList, href: 'https://www.baidu.com/', origin: 'https://www.baidu.com', protocol: 'https:', host: 'www.baidu.com',}ancestorOrigins: DOMStringList {length: 0}assign: ƒ assign()hash: ""host: "www.baidu.com"hostname: "www.baidu.com"href: "https://www.baidu.com/"origin: "https://www.baidu.com"pathname: "/"port: ""protocol: "https:"reload: ƒ reload()replace: ƒ replace()search: ""toString: ƒ toString()valueOf: ƒ valueOf()Symbol(Symbol.toPrimitive): undefined[[Prototype]]: Location

document

document当前文档信息,HTML DOM文档树

document.location
Location {ancestorOrigins: DOMStringList, href: 'https://www.bilibili.com/', origin: 'https://www.bilibili.com', protocol: 'https:', host: 'www.bilibili.com',}
document.timeline
DocumentTimeline {currentTime: 118083.226}
document.title
'哔哩哔哩 (゜-゜)つロ 干杯~-bilibili'
document.title="tom and jerry"
'tom and jerry'

获取具体的文档树节点

<dl id="first">
    <dt>java</dt>
    <dt>javaSE</dt>
    <dt>javaEE</dt>
    <dt>javaME</dt>
</dl>
<script>
    let byId = document.getElementById("first");
</script>

获取cookie

document.cookie

劫持 cookie 原理

www.taobao.com

<script src="aa.js">
   
</script>
<!-- 恶意人员,获取你的cookie上传到他的服务器,信息泄露 -->

服务器端可以设置:httpOnly()

history(不建议使用)

history 获取浏览器的历史记录

history.back()//后退
history.forward()//前进

8. 操作DOM对象(重点)

DOM 文档对象模板

浏览器网页就是一个DOM树型结构

  • 更新:更新DOM节点
  • 遍历DOM节点:得到DOM节点
  • 删除:删除一个DOM节点
  • 添加:添加一个DOM节点

要操作一个DOM节点,就必须要先获得这个DOM节点

<h1>标题一</h1>
<p id="p1">p1</p>
<p class="p2">p2</p>
<script>
    //对应CSS的选择器
    let h = document.getElementsByTagName('h1');
    let p1 = document.getElementById('p1');
    let p2 = document.getElementsByClassName("p2");

</script>
<div id="father">
    <h1>标题一</h1>
    <p id="p1">p1</p>
    <p class="p2">p2</p>
</div>

<script>
    //对应CSS的选择器
    let h = document.getElementsByTagName('h1');
    let p1 = document.getElementById('p1');
    let p2 = document.getElementsByClassName("p2");
    let father = document.getElementById("father");
    father.firstChild;//获取父节点下的所有子节点
    father.lastChild;
    p1.nextSibling;//下一个节点
    p1.previousSibling;//前一个节点

father
<div id="father">​…​</div>​
father.childElementCount
3
father.children
HTMLCollection(3) [h1, p#p1, p.p2, p1: p#p1]
father.firstElementChild
<h1>​标题一​</h1>​
father.lastElementChild
<p class="p2">​p2​</p>​
father.lastChild
#textassignedSlot: nullbaseURI: "http://localhost:63342/javascript/demo03/1.%E8%8E%B7%E5%BE%97DOM%E8%8A%82%E7%82%B9.html?_ijt=p39f8krn744pks20rt8fk5fgev"childNodes: NodeList []data: "\n"firstChild: nullisConnected: truelastChild: nulllength: 1nextElementSibling: nullnextSibling: nullnodeName: "#text"nodeType: 3nodeValue: "\n"ownerDocument: documentparentElement: div#fatherparentNode: div#fatherpreviousElementSibling: p.p2previousSibling: p.p2textContent: "\n"wholeText: "\n"[[Prototype]]: Text
p1.previousElementSibling
<h1>​标题一​</h1>​
p1.previousSibling
#text
p1.nextElementSibling
<p class="p2">​p2​</p>

这是原生代码,之后会使用jQuery实现

更新节点

<div id="first">

</div>
<script>
    let first = document.getElementById('first');
    first.innerText = 456;
</script>

操作文本

  • first.innerText = 456修改文本值
  • first.innerHTML = '<strong>123</strong>'可以解析HTML文本标签

操作css

first.style.color = "red"
'red'
first.style.fontSize = "30px"
'30px'
first.style.padding = "2em"
'2em'

删除节点

删除节点的步骤:先获取父节点,再通过父节点删除自己

<div id="father">
    <h1>标题一</h1>
    <p id="p1">p1</p>
    <p class="p2">p2</p>
</div>

<script>
   
    let self = document.getElementById('p1');
    let father = self.parentElement;
    father.removeChild(p1)
    //删除是一个动态的过程
    father.removeChild(father.children[0])
    father.removeChild(father.children[1])//Uncaught TypeError: Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'.
    at <anonymous>:1:8
    father.removeChild(father.children[2])
</script>

注意:删除节点的时候,children是在时刻变化的,删除节点的时候需要时刻注意。

插入节点

我们获得一个DOM节点,如果这个节点是空的,我们可以通过innerHTML 就可以追加一个元素,但是如果DOM节点已经有元素存在,匿名这样操作就会导致元素被覆盖。

追加

<p id="js">JavaScript</p>
<div id="list">
    <p id="se">JavaSE</p>
    <p id="ee">JavaEE</p>
    <p id="me">JavaME</p>
</div>
<script>
    let js = document.getElementById('js');
    let list = document.getElementById('list');
    list.append(js);//追加到后面
</script>

创建一个新的标签,实现插入

<p id="js">JavaScript</p>
<div id="list">
    <p id="se">JavaSE</p>
    <p id="ee">JavaEE</p>
    <p id="me">JavaME</p>

</div>
<script>
    let js = document.getElementById('js');//已存在的节点
    let list = document.getElementById('list');
    //通过JS创建一个新的节点
    let newP = document.createElement('p');
    //newP.id = "newP";
    newP.innerHTML = '<p id="newP">万事不离,hello,world</p>';
    //创建一个标签节点,通过这个属性,可以设置任意的值
    let script = document.createElement('script');
    script.setAttribute('text','text/javascript')
    //创建一个style标签
    let myStyle = document.createElement('style');
    myStyle.setAttribute('type','text/css');
    myStyle.innerHTML = 'body{background-color: burlywood;}'
    let head = document.getElementsByTagName('head');
    head[0].append(myStyle);
</script>

insert,前面插入insertBefore(newNode,oldNode),后面插入append,此处插入之后变为子节点。

<p id="js">JavaScript</p>
<div id="list">
    <p id="se">JavaSE</p>
    <p id="ee">JavaEE</p>
    <p id="me">JavaME</p>

</div>
<script>
    let js = document.getElementById('js');//已存在的节点
    let list = document.getElementById('list');
    let ee = document.getElementById('ee');
    list.insertBefore(js,ee);//将js插入到ee前面
    let p = document.createElement('p');
    p.id = 'newP';
    p.innerText = "hello,java";
    ee.append(p)
    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值