JavaScript基础2

8. 语句

8.1 表达式和语句

  • 表达式:一组代码的集合,JS解释器会计算出一个结果

    x = 7
    3 + 4
    num++
    
  • 语句:JS整句或命令,js语句是以分号结束(可以省略)

    比如:if语句 for语句

表达式与语句的区别:

​ 表达式:计算一个值,但语句是用来自行以某件事情发生(做什么事)

​ 如alert() 是一个语句,弹出一个对话框。如prompt弹出一个对话框

​ 如 3+4 最后计算出了一个结果

8.2 分支语句

JS中的三大流程控制语句:顺序结构(自上而下执行),分支结构,循环结构

8.2.1 if分支语句

if语句有三种使用:单分支,双分支,多分支

  1. 单分支语句的使用语法:

    if (条件){
        满足条件要执行的代码
    }
    
    • 括号内的条件为true时,进入大括号里执行代码。
    • 小括号内的结果若不是boolean型,会发生隐式转换为布尔型。
    • 5个false数据类型:(false , 0 ,undefined , null , " " 均为false)
    <script>
        if (true) {
            alert(11)
        }
    
        if (3 > 5) {
            console.log('真的')
        }
    
        if ('pink') {
            console.log('真的')
        }
    </script>
    

案例:单分支课堂案例1:用户输入高考成绩,如果分数大于700分数,则提示考入黑马程序员

<script>
    let score = prompt('请输入高考成绩')
    if (score > 700) {
        document.write(`<h3>提示</h3>
        <div>恭喜考入黑马程序员</div>`)
    }
</script>
  1. 双分支语句

​ 语法:

if ( 条件 ) {
    满足条件要执行的代码
} else {
    不满足条件要执行的代码
}

案例:

用户输入,如果工龄大于1年,年底奖金 + 2000,否则年底没有奖金

<script>
    let years = prompt('请输入工龄:')
	let money = 10000
    if (years > 1) {
        document.write(`奖金为:${money + 2000}`)
    } else {
        document.write(`奖金为:${money}`)
    }
</script>

案例:

让用户输入年份,判断这一年是闰年还是平年,并输出

​ 闰年:能被4整除但是不能被100整除,或者被400整除的年份是闰年,否则都是平年

<script>
    let year = prompt("请输入年份:")
	if (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0){
        document.write('闰年')
    } else {
        document.write('平年')
    }
</script>
  1. 多分支语句

    语法:自上而下执行,当发现有满足条件的,就会跳出if多分支

    if (条件1) {
        代码1
    } else if (条件2) {
        代码2
    } else if (条件3) {
        代码3
    } else {
        代码n
    }
    

    案例:输入不同时间,输出不同的问候语

    • 12点以前,输出上午好
    • 18点以前,输出下午好
    • 20点以前,输出晚上好
    <script>
        let time = prompt('请输入小时:')
        if (time < 12 ) {
            document.write('上午好')
        } else if (time <=18) {
            document.write('下午好')
        } else if (time <20 ) {
            document.write('晚上好')
        } else {
            document.write('夜深了')
        }
    </script>
    

8.2.2 三元运算符

语法:自上而下执行,当发现有满足条件的,就会跳出if多分支

  • 其实是比if 双分支更简单的写法,有时候也叫做三元表达式

  • 符号:?与:配合使用

  • 语法:

    条件? 满足条件执行的代码 : 不满足条件执行的代码
    
    // 如果判断为false,则不做任何操作
    条件? 满足条件执行的代码 : undefined
    条件? 满足条件执行的代码 : null
    

    三元表达式一般用来取值

    <script>
        console.log(true ? 1 : 2)
        console.log(false ? 1 : 2)
    	3 > 5 ? alert('第一个') : alert('第二个')
    </script>
    

    案例:

    需求:用户输入2个数,控制台输出最大值

<script>
    let num1 = +prompt('请输入第一个数字:')
    let num2 = +prompt("请输入第二个数字:")
    let result = num1 > num2 ? num1 : num2
    document.write(`最大的数字为${result}`)
</script>

案例:数字补0案例

​ 需求:用户输入1个数字,如果小于10,就在前面补充一个0

<script>
    let num = prompt('请输入一个数字:')
    let num_str = num<10 ? `0${num}`:num
    document.write(num_str)
</script>

8.2.3 switch语句

语法:
语法:

  • 用数据逐一对所有的值进行全等===判断

  • default 可以不用

  • switch不是自上而下,而是直接就匹配到对应的值上

  • 一定要注意数据的类型,因为要求的是全等匹配

  • 一定要使用break,否则switch会穿透

switch (数据) {
    case1:
        代码1
        break
    case2:
        代码2
        break
    default:
        代码n
        break
}
<script>
	switch (2) {
        case 1:
            alert(1)
            break
        case 2:
            alert(2)
            break
        case 3:
        	alert(3)
        	break
        default:
        	alert('没有数据')
    }
</script>

案例:简单计算器

​需求:用户输入2个数字,然后输入 = - * /任何一个,可以计算结果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let num1 = + prompt("请输入第一个数字:")
    let num2 = + prompt("请输入第二个数字:")
    let method = prompt("请输入计算方式:")
    let result
    switch (method){
        case "+":
            result = num1 + num2
            break
        case "-":
            result = num1 - num2
            break
        case "*":
            result = num1 * num2
            break
        case "/":
            num2=0?alert("除数等于0"):result=num1/num2
            break
        default:
        	alert('输入错误')
    }
    alert(`结果为${result}`)
</script>
</body>
</html>

8.3 while循环

while循环的语法:

while (循环条件) {
    要重复执行的代码(循环体)
}
<script>
    while (true){
        console.log('我死了')
    }
</script>

循环需要具备3个要素

  • 变量初始值
  • 终止条件
  • 计数器
// i=1 为变量初始值
let i = 1
// i<=3为终止条件
while (i <= 3) {
    document.write(`我会循环3次<br>`)
    // i的累加为计数器
    i++
}

案例:计算1到100,所有偶数的和

<script>
    let i = 0
    let sum = 0
    while (i <= 100) {
        if (!(i%2)) {
            sum += i
        }
        i++
    }
    document.write(sum)
</script>
<script>
    let i = 0
    let sum = 0
    while (i <= 100) {
        sum += (i % 2 ? 0 : i)
        i++
    }
    document.write(sum)
</script>

8.4 循环的退出

continue 和 break

continue是进行下一次循环;break是跳出循环

<script>
    let i = 1
	while (i<=6) {
        if (i===3){
            // 注意i++一定要写在continue的前面
            i++
            continue
        }
        document.write(`我再吃第${i}个包子<br>`)
        i++
    }
</script>

★重点案例

​ 需求:用户可以选择存钱,取钱,查看余额和退出

<script>
    let money = 0
    while (true) {
        let str = prompt(`请选择操作:
        1. 存钱
        2. 取钱
        3. 查看余额
        4. 退出`)
        if (str === '4') {
            alert('再见')
            break
        } else if (str === '1') {
            let num = +prompt(`请输入存入金额:`)
            money += num
        } else if (str === '2') {
            let num = +prompt(`请输入取钱金额:`)
            money -= num
        } else if (str === '3') {
            alert(`您的账户余额为${money}`)
        }
    }
</script>

8.5 for循环

8.5.1 for循环基本使用

while循环有3个循环要素,起始值,计数器,终止条件。

for循环:将循环的三要素写在一起,开发中一般都是使用for循环

for循环的语法:

for (声明记录循环次数的变量;循环条件;变化值) {
    循环体
}
<script>
    for (let i = 1;i<=10;i++) {
        document.write(`月薪过万<br>`)
    }
</script>

案例:计算0~100的偶数和

<script>
    let sum = 0
    for (let num=0;num<=100;num++) {
        sum += num % 2 ? 0 : num
    }
    document.write(`sum:${sum}`)
</script>

for循环最大的价值是循环数组

let arr = ['马超','赵云','张飞','关羽','黄忠']
// arr.length 数组的长度
for (let i = 0 ; i< arr.length ; i++) {
    document.write(`${arr[i]}<br>`)
}

8.5.1 退出循环

continue和break<详见while循环的continue和break>

8.5.2 循环嵌套

语法:

for (外部声明记录循环次数的变量;循环条件;变化值) {
 	for (内部声明记录循环次数的变量;循环条件;变化值) {
        
        循环体
        
    }
}

★**重点案例:九九乘法表**

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        span{
            display:inline-block;
            padding:5px 10px;
            border:1px solid black;
            margin:2px;
            border-radius: 5px;

        }
    </style>
</head>
<body>
<script>
    for (i = 1; i <= 9; i++) {
        for (j = 1; j <= i; j++) {
            result = i * j < 10 ? '0' + (i * j) : i * j
            document.write(`<span>${i}×${j}=${result}</span>`)
        }
        document.write(`<br>`)
    }

</script>
</body>
</html>

display: inline-block; :允许元素既具有内联元素的特性(如与其他元素保持在同一行内),又具有块级元素的特性(如能够设置宽度、高度和其他盒模型属性)。

9 数组

9.1 数组是什么

array:是一种可以按照顺序保存数据的数据类型

9.2 数组的基本使用

  1. 申明数组

    方式1:

    let arr = [数据1,数据2... ,数据3]
    

    方式2:构造函数的方式

    let arr = new Array(数据1,数据2... ,数据3)
    

    数组中,数据的编号叫索引或下标

  2. 术语:

    • 元素
    • 下标
    • 长度:arr.length
  3. 遍历数组:使用for循环

    for (let i = 0; i<arr.length; i++) {
        arr[i]
    }
    

    案例1:数组求和,求[2,6,1,7,4]里面所有元素的和与平均值

    <script>
        let arr = [2,6,1,7,4]
        let sum = 0
        for (let i = 0; i<arr.length;i++) {
            sum += arr[i]
        }
        document.write(`sum=${sum}<br>aver=${sum/arr.length}`)
    </script>
    

    案例2:求数组中最大值 [2,6,1,77,52,25,7]

    <script>
        let arr = [2,6,1,77,52,25,7]
        max_num = arr[0]
        for (let i =1 ; i< arr.length;i++){
            max_num = arr[i]>max_num? arr[i]:max_num
        }
        document.write(max_num)
    </script>
    

9.3 操作数组

类型位置关键字
添加开始unshift
添加末尾push
删除开始shift
删除末尾pop
删除指定位置,并且指定删除个数splice(start,deletecount)

数组的增删改查:

  1. 数据的修改

    arr[0]='lightpink'
    
  2. 数据的增加

    • push:将一个或多个元素添加到数组的末尾,并返回数组的新长度

      arr.push(元素1,元素2...,元素n)
      
      <script>
          let arr = ['red', 'green']
          let new_length = arr.push('pink')
          document.write(arr)
          document.write(new_length)
      </script>
      
    • unshift:与push基本相同,就是将元素放置在数组的开头

    案例:将数组[2,0,6,1,77,0,52,6,19,7,92,9,10]中大于等于10的元素选出来,放入新数组

    <script>
        let arr = [2,0,6,1,77,0,52,6,19,7,92,9,10]
        let brr = []
        for (let i = 0;i<arr.length;i++) {
            if (arr[i]>=10) {
                brr.push(arr[i])
            }
        }
        document.write(brr)
    </script>
    
  3. 删除数组中的数据

    • arr.pop()

      从数组中删除最后一个元素,并返回删除的值

    • arr.shift()

      从数组中删除第一个元素

    • arr.splice(start,deletecount)

      从start位置开始,删除deletecount个数,如果不指定,就是从start开始,后面全部删除。

10 函数

10.1 函数使用

  • 函数声明的基本语法

    函数名的命名规范与变量名的命名方式一样

    function 函数名(){
        函数体
    }
    

    例如:

    <script>
        function sayHi(){
            document.write('say,hi')
        }
    	// 函数的调用
        sayHi()
    </script>
    
  • 函数的调用

​ 正常写法为先声明后调用

10.3 函数传参

语法:

function 函数名(参数列表) {
    函数体
}

例如:求两个数的和

<script>
  function getSum(num1,num2){
    let sum = 0
    sum = num1 + num2
    document.write(sum)
  }
  getSum(1,2)
</script>

形参与实参:函数声明中的参数为形参。实参为调用函数时,传入的参数

注意:函数的形参与实参的个数尽量相同,但如果不同,javascript也不会报错。这种情景一般分为3种情况

  1. 形参个数大于实参个数

    function fn(x,y){
        console.log(x+y)
    }
    fn(1)
    

    这种情况返回的时Nan。因为x被赋值为1,y没有被赋值,y就是一个undefined。因此相加之后不是一个数字

  2. 形参个数小于实参个数

    function fn(x,y){
        console.log(x+y)
    }
    fn(1,2,3)
    

    这种情况返回3,因为fn中只有2个变量可以接受1,2.

​ 对于这种情况有一个不推荐的方式就是在函数体内调用arguments

<script>
    function fn(){
    console.log(arguments)
}
fn(1,2,3)
</script>

网页的控制台中,arguments返回的时一个伪数组arguments(3)

它与一般的数组的区别是没有push pop等操作。但是也可以进行遍历

案例:传入一个学生的分数的数组,求总分

<script>
    let scores = [60,60,70,80,90,100];
    function add(arr){
        let ttl = 0;
        for(i=0;i<arr.length;i++){
            ttl += arr[i]
        }
        console.log(ttl)
    }
    add(scores);
</script>

10.3 函数返回值

关键字:return

语法:return 数据

function 函数名(参数列表) {
    函数体
    return ...
}

例如

<script>
    function getSum(x,y){
    return x + y
}
</script>

let num = getSum(10,30)
document.write(sum)
  • return有退出函数的作用
  • 函数没有return或者只写一个return,默认返回的时undefined

10.3.1 turn返回多个值

如果需要返回多个值,可以return一个数组

<script>
    function fn(x,y) {
    let jia = x+y
    let jian = x-y
    return [jia,jian]
}
</script>

10.3.2 return 与三元表达式

例如:输入2个数字,就最大值

以下代码是正确的:

<script>
    let num1 = +prompt('请输入第一个数字:')
	let num2 = +prompt('请输入第二个数字:')
    function getMax(x,y) {
        return x>y? x:y
    }
</script>

以下代码是错误的,因为短接的问题

<script>
    let num1 = +prompt('请输入第一个数字:')
	let num2 = +prompt('请输入第二个数字:')
    function getMax(x,y) {
        x>y ? return x:return y
    }
</script>

错误的原因是return具有短路性,只要执行了第一个return x,后面的所有代码就不会再执行,因此电脑会认为是语法错误,写错了。

10.4 作用域

例如下面的代码

for(let i = 0;i<3;i++){
    document.write('怎么回事呢?')
}
console.log(i)

控制台会显示Uncaught ReferenceError: i is not defined

或者如下代码

function fun(){
    let num2 = 20
}
fun()
console.log(num2)

控制台会显示Uncaught ReferenceError: num2 is not defined

10.4.1 作用域的概述

通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字的冲突。

作用域的分类:

  • 全局有效:整个script标签内部
  • 局部有效:函数内有效
  • 块级有效:{}内,比如if for 内部。

10.4.2 变量的作用域

内部可以访问外部作用域的变量,但是外部不能直接访问内部的变量

  • 全局变量:scirpt范围内

    <script>
        // 1.全局变量 全局能用
        let num = 10
    	console.log(num)
    	function fn() {
            console.log(num)
        }
    	fn()
    	if (true){
            console.log(num)
        }
    </script>
    
  • 局部变量:函数范围内

    <script>
        function fn(){
        	let num=10
            function fn1(){
                console.log(num)	//可以调用
                let num2 = 20
            }
        	fn1()
        	console.log(num2) //会报错:num is not defined
    	}
    	fn()
    	console.log(num) //会报错:num is not defined
    </script>
    
  • 块级变量:语句范围内

    <script>
        if (true) {
            let num =10
        }
    	console.log(num) //会报错:num is not defined
    </script>
    

例外的情况

在函数与块级作用域内,如果变量没有声明,直接进行赋值。这个变量就是全局变量。但是强烈不推荐

<script>
    function fn(){
    num = 10
}
console.log(num) //这个可以访问到
</script>

10.4.3 作用域链

就近原则:调用变量时,先在当前作用域进行查找。如果当前作用域里面没有,就找上一层作用域。逐层向上查找。如果都找不到,就显示undefined

<script>
    let num =10
    function fn(){
    	let num = 20
        console.log(num)
	}
</script>

10.5 匿名函数

匿名函数就是没有名字的函数。 匿名函数也称为函数表达式

javascript的函数分类

  • 具名函数

    function fn(){}
    
  • 匿名函数:也称作为函数表达式

    function (){}
    

匿名函数的语法规范:

let fn = function (x,y) {
    // 函数体
    console.log(x+y)
}

调用

fn(1,2)

注意:如果function(){}前面不用变量接收,则会直接报错

10.6 立即执行函数

不需要调用,直接可以执行

立即执行函数的优点:由于作用域的关系,写在立即执行函数中的变量,不会与外面的变量存在重复声明的问题。变量不会被污染。

立即执行函数有2种语法,以下2种方式在运行的效果上没有什么区别。

  • 第一种:

    (function(){})()
    
  • 第二种

    	(function(){代码体}())
    

注意:多个立即执行函数之间必须使用分号进行分隔

(function () {console.log(11)}()); //不加这个分号会报错
(function () {console.log(22)}())

11 对象

11.1 什么是对象

  • 对象:object是javascript里的一种数据类型

  • 可以理解为一种无序的数据类型

  • 用来详细的描述一个【实体】

  • 一个对象可以有静态特征(属性)和动态行为(方法)

11.2 对象使用

  1. 对象声明语法

    let 对象名 = {}
    

    例如:

    let person = {}
    
  2. 对象有属性和方法组成

    let 对象名 = {
        属性名:属性
        方法名:函数 // 函数使用匿名函数
    }
    
  3. 属性

    属性名可以使用""'',一般情况下省略,除非名称遇到特殊符号,如空格,中横线等。json就必须添加引号了。

    let person = {
        name:'刘德华',
        age:18,
        sex:'男'
    }
    
  4. 对象属性的2种访问方法

    方式1

    console.log(person.name)
    

    方式2

    console.log(person['name'])
    

    注意第二种方式2,中括号中的属性名需要追加单引号

  5. 对象的方法

    对象的方法需要使用匿名函数

    let person = {
        name : 'andy',
        sayHi : function(){			//匿名函数
            document.write('hi~~~')
        }
    }
    

    例如:

        <script>
            let person = {
                'name':'刘德华',
                age:18,
                sex:'男',
                sayHi:function (){
                    console.log('hi')
                },
                mtv:function (mtv_name){
                    person.age++				//在方法中,可以对自己的属性进行修改
                    return `出演了${mtv_name}`
                }
            }
            console.log(person.name)
            person.sayHi()
            str = person.mtv('无间道')
            document.write(str)
            document.write(`<br>`)
            document.write(person.age)
        </script>
    
  6. 对象方法的调用

    person.sayHi()	// 注意要加小括号
    str = person.mtv('无间道')
    document.write(str)
    

11.3 操作对象

对象的操作也是增删改查

  • 增:

    增的方法与改的方法是一样的。直接使用对象.新属性的方法进行增加

  • 修改:

    使用对象.属性的方法进行修改

  • 查:<详见之前对象属性的访问方法>注意有2种方法

    第二种方法更加常用,后面遍历对象时,使用第二种方法。

  • 删除:(很少使用,了解就好,最新的语法其实是不允许的)

    关键字:delete

    delete obj.uname
    console.dir(obj)
    

11.4 遍历对象(for in 语句)

假如我们需要获取对象的所有属性

问题:

  1. 对象没有length属性。
  2. 对象是无序的。
    因此为了遍历对象,我们有了新的遍历对象的语句for in结构的语句

语法:

for (let i in obj) {
    循环体
}

例如下面的代码

let obj = {
    uname : 'andy',
    age:'18',
    sex:'男'
}

for (let k in obj) {		// 开发一般使用k,是key的缩写
    console.log(k)			// 打印属性名
    console.log(obj[k])		// 打印属性,注意一定使用中括号
}

注意:打印属性的时候一定要使用中括号,否则会提示undefined。

案例:学生信息表
在这里插入图片描述

11.5 内置对象

11.5.1 内置对象是什么

JavaScript内部提供的对象,包含各种属性和方法给开发者调用

11.5.2 内置对象Math

随机数:0~1之间取随机数

Math.random()

取整函数

Math.ceil(1.5)	// 2 向上取整
Math.floor(1.5)	// 2 向下取整
Math.round(1.5)	// 2 四舍五入,往大取整

最大值与最小值

Math.max(1,5,9,45) 	// 注意:数组不能求最大值
Math.min(1,5,9,45) 	// 注意:数组不能求最大值

11.5.3 随机数

// 生成0~10的随机数
Math.floor(Math.random()*(10+1))

// 生成N~M之间的随机数
Math.floor(Math.random()*(M-N+1)) + N

将N~M之间的随机数封装成函数

<script>
    function  getRandomInt(min,max){
    let result = Math.floor(Math.random()*(max - min + 1)) + min
    return result
}
console.log(getRandomInt(5,10))
</script>

案例:随机点名案例

需求:请把[‘赵云’,‘黄忠’,‘关羽’,‘张飞’,‘马超’,‘刘备’,‘曹操’]随机显示一个名字到页面上

<script>
    function getRandomInt(min,max) {
        return Math.floor(Math.random()*(max-min+1)) + min
    }

    function getRandomName(name_list) {
        let counter = name_list.length
        let random_num = getRandomInt(0,counter-1)
        return name_list[random_num]
    }
    let name_array = ['赵云','黄忠','关羽','张飞','马超','刘备','曹操']
    let name = getRandomName(name_array)
    document.write(name)
</script>

关键案例:数组重新排列
关键点:深复制与浅复制

<script>
    function shuffer(array){
        /*如果是let temparr = array,这不是赋值,而是将temparr指向array的内存
        最后的结果就是name_array 与 newArr是一样的
        数组前面加三个... 就是浅拷贝的意思
         */
        let temparr = [...array]
        for(let i=temparr.length-1;i>0;i--) {
            const j = Math.floor(Math.random()*(i+1))
            let temp = temparr[i]
            temparr[i] = temparr[j]
            temparr[j] = temp
        }
        return temparr
    }
    let name_array = ['赵云', '黄忠', '关羽', '张飞', '马超', '刘备', '曹操']
    newArr = shuffer(name_array)
    document.write(`${name_array}<br>${newArr}`)
</script>

拓展

术语解释

术语解释举例
关键字在js中有特殊意义的词汇let、var、function、if、else、for、switch等
保留字将来可能会变为关键字的词汇int,short,long,char
标识(标识符)变量名,函数名的另一种叫法
表达式可以产生value的代码
语句一句代码也称为一条语句,一般按用途还会分类:
输出语句,声明语句,分支语句,循环语句

基本数据类型和引用数据类型

以下以及堆与栈的区别复听为百度网板中 js中的《简单和引用数据类型及作业》

  • 基本数据类型:值类型

    如string,number,boolean,undefined,null

    基本数据类型存放的是值

  • 引用类型:复杂数据类型,在存储时,变量中存储的仅仅是地址(引用),因此叫做引用数据类型

    通过new关键字创建的对象,如object,array,Date等

堆与栈的区别

  • 栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;

    简单的数据存放在栈中

  • 堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。

    引用数据类型存放在堆里面

简单数据类型与引用数据类型的存放机制

  • 简单数据类型就是在栈中存放了一个值

  • 引用数据类型是在堆中存放数据,在栈中存放了一个指向堆的一个地址

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值