JavaScript对象与继承教程之内置对象(上)。

Mr-Jee 2011-01-23 03:26:28
加精
离职了,过年这段时间可以把很长时间来的一个愿望实现,我将总结出一套简易教程和一套常用问题集。能力有限,欢迎仅就技术问题拍砖。
更好排版请访问博客:http://blog.csdn.net/cj205/archive/2011/01/23/6159709.aspx
一、 类与对象

在 JavaScript 世界里,关于面向对象第一个要澄清的概念就是类。对象都是有类来定义的,通过类来创建对象就是我们所熟悉的实例化。然而,在 JavaScript 中别没有真正的类,对象的定义就是对象自身。而 ECMA-262 干脆把这种妥协的方式称作为对象的调和剂。为了方便理解,我通常把这个发挥类的作用的调和剂称为类。

二、 内置对象

1、 Array类

数组在 js 中是是否常用的一种数据结构,由于其灵活性和易用性,合理的使用数组可以帮助我们更好的实现相应的功能。

让我们先看 Array 对象的创建吧

第一种:var arr = new Array(10);

该方法在实际的使用当中并不那么的实用,与很多编译型语言不同, js 数组的长度是可变的,不但增强了灵活性,还给我们有了更多好的选择。

第二种:var arr = new Array("one","two","three");

使用 new 方式创建数组的方法一般多为这两者,当然也可以使用 new Array() 创建一个空的数组对象。通常情况下,我推荐如下的方法

第三种:var arr = ["one","two","three"];

使用数组的字面量方式创建一个数组对象,不但简洁易读,而且几乎完全等价于使用 new 方式创建数组对象的效果。数组对象有很多好用的方法,接下来我们就一起看看这个数组对象的强大功能吧。

首先要介绍的是 push 方法,学过数据结构的朋友都知道 push 意味着什么,没错,他的出现让数组能够实现栈的数据结构(同时需要配合 pop 方法)。 push 方法帮助我们紧凑的添加数组元素。前面提到js中的数组是长度是可变的,则我们可以添加元素。既然可以通过 arr[length] = newValue; 来给 arr 添加一个新元素并放置于数组尾。更好的办法就是使用 push 方法。 arr.push(newValue); 怎么样,使用他比你还要通过数组长度来赋新值方便多了吧。在这里有一点需要注意。请看下面的代码:

var arr = [];

arr[4] = 5;

alert(arr.length == 5);

alert(arr); //alert : ,,,,5

当我们需要给指定数组位置赋予指定的值的时候,这种赋值就显得十分有用了,比如在用于装箱排序的时候。

pop 方法则是实现与 push 相反的作用,返回数组的最后一个元素,并出栈。

var arr = [1,2,3,4,5];

var ele = arr.pop();

alert(ele == 5);

alert(arr.length == 4);

数组对象的 toString 和 valueOf 方法比较人性化的重写了,它的实现是把每一项都调用 toString 方法,然后用半角逗号(,)连接每一项。那么:

var arr = [1,2,3,4,5];

alert(arr);//output:1,2,3,4,5

toLocateString 方法在这里不做详细说明了,他的效果与 toString 方法类似,只是每项调用 toLocateString 方法。

如果你想使用个性化的分隔符来显示数组元素,那么 join 方法可能会更加的适合。比如:

var city = ["上海","北京","天津","重庆","深圳"];

alert(city.join("|");//output:上海|北京|天津|重庆|深圳

由此可见 join 是把数组元素转换为一个字符串。在介绍字符串的时候我们将再次看到 join 方法的使用。

concat 方法和 slice 方法是又一对好用的方法,这两个方法的特殊之处在于 String 对象也拥有他们。当我们希望给一个数组添加多个数组元素的时候,使用 push 可能就显得有些冗余和复杂了,而且也会让 coding 变得不那么有意思了。好在我们有 concat 方法,该方法将其参数们按序加入数组元素中。如:

var arr = [1,2,3,4,5];

arr = arr.concat(6,7,8,9);

alert(arr.length == 9);

注意, concat 并不修改数组对象本身,而是将数组元素与 concat 方法的数组元素合并后返回。所以需要给数组元素进行赋值运算才行。

slice 方法则是从数组对象中返回一个子数组。该子数组是从 slice 方法的第一个参数所指位置至第二个参数所指的位置。这是一个半开半闭区间 [a,b) 。如:

var arr = [1,2,3,4,5];

var arr1 = arr.slice(1,3);

alert(arr1); //output:2,3

alert(arr); //output:1,2,3,4,5

好了, slice 和 concat 方法一样不是修改数组对象本身。同时参数1,3表示从位置1到位置3的半开半闭区间的子数组。

刚才讨论了后进先出的栈操作,现在我们来看看先进先出的队列操作吧。进列使用 push 方法没有问题,那么出列呢。是 shift ,他删除数组对象的第一个元素并返回:

var arr = [1,2,3,4,5];

var ele = arr.shift();

alert(ele); //output:1

alert(arr.length);//output:4

另外一个还有一个方法,叫 unshift ,他将新元素插入数组对象的第一项,究其功能与 shift 是相反的操作。

sort 方法很灵活,使用好了,他可以给数组元素以任意你想要的排序方式来进行排序。因为 sort 方法接收一个匿名函数(其实,它同样可以接收一个非匿名的函数,但是通常不推荐为此而创建一个这样的命名函数,除非该函数可重用)作为自己的排序的条件。比如:

Object.prototype.toString = function(){

var str = '';

for(var item in this) {

str += item + ":" + this[item] + ",";

}

return str.length?str.substr(0,str.length-1):str;

};

var arr = [{key:3,value:"three"},{key:1,value:"one"},{key:2,value:"two"}];

arr.sort(function(a,b){

return a.key - b.key;

});

alert(arr);//output:key:1,value:one,key:2,value:two,key:3,value:three


我们先不去纠结 Object.prototype.toString 方法,他的左右就是将对象遍历使之可以输出为键值对格式字符串,在介绍原型链的时候会再次提到。我们可以看到 sort 方法通过这个匿名方法让我们可以根据 key 属性来进行排序。那就让我们来看看这个匿名方法吧。

function(a,b) {

return a.key - b.key;

};

可以看到,这个方法接收2个参数,然后对参数的自身或某个属性进行比较,然后返回比较结果,他们的比较结果与排序对应关系如下:

如果 paramA - paramB > 0,return 正数 ,则 a 排在 b 的前面

如果 paramA - paramB < 0,return 负数 ,则 a 排在 b 的后面

如果 paramA - paramB = 0,return 0 ,则顺序不变。

上面的实现是顺序排序,那么 倒序 呢?对, return paramB - paramA;

reverse 方法可以将数组对象反转。他和 sort 方法一样是修改数组对象内部元素顺序的。

最后我们看看 splice 方法,他是替换和删除数组对象元素的方法。根据参数的改变而拥有不同的实现结果。 splice(pos,count[,insertParams]);pos 参数是删除元素的第一个项的位置, count 参数是删除元素的个数,当为0时则不删除(不删除还要这个方法干嘛,别着急,往下看), insertParams 则是参数列表,这些参数是即将插入的元素集合。插入的位置为 pos 。那么就出现了以下几种情况了。

1、 insertParams 忽略时,该方法就是删除数组元素

2、 当 count 参数为0时,该方法将只是将 insertParams 插入到 pos 位置

3、 当 count 参数不为0且 insertParams 不忽略时,该方法就是删除 pos 位置开始的 count 个元素,并替换 insertParams 参数集合。

2、 Math类

我们花了很大的篇幅来介绍数组类,我要再次强调一点,这个类只是为了介绍方便强加于它的一个名字,实际上他们也只是对象。而非真正的类。

Math 类的使用范围相对狭窄,因为他作为一个数学计算的类,而非一个数据结构类,但是我们也看到了 Math.random 以及各种取整等常用方法。因此我们不妨花些时间来看看他们,但是如果你对此兴趣不大,那么看完 random 方法之后就可以跳到下一节去,以后用到的时候再翻手册就可以了。

Math 通常是一个“静态”类,因为没有人会实例化一个 Math 对象,而是直接使用其“静态”方法,有些资料直接称它为 Math 对象,在这里我们不妨称它为“静态”类吧。

首先我必须介绍 random 方法,因为他常用且太有用了。在制造随机事件的时候他总是不可或缺,同样在防止缓存上他也显得很有用处。 Math.random 方法返回的是一个 0到1 之间的开区间浮点数,即 (0,1) ,他的使用非常简单,唯一需要注意的是,当我们取整的时候对 floor 和 ceil 方法的筛选时需要谨慎,前者使得 random 间接转换为前闭后开区间,而后者则是前开后闭区间。假如我们现在需要一个取1-100的随机数,那么有如下的两种常用解决方案

方法一:Math.ceil(Math.random*100);

方法二:Math.floor(Math.random*100)+1;

ceil 方法和 floor 方法都是用来取整的数学方法,根据单词含义我们可以理解,前者是向上取整,而后者则是向下取整。

当我们从一个连续的数组对象中随机选择一个数组元素时,我们可以借助 random 轻松的来帮我们挑选:

["ipad","iphone","ipod touch","ipod nano","macbook"][Math.ceil(Math.random()*4)];

这个例子中,我直接使用的是数组字面量,一开始你可能会觉得费解或者不易理解,当你深入以后你会发现原来 JavaScript 是如此的方便、简洁、灵活。

前面我们介绍了 ceil 和 floor 方法的取整,那么当我们想要接近舍入时呢,我们可以使用 Math.round 方法,他在取整时根据数值进行靠近取整。比如 Math.round(5.4) 返回的是 5 。那么如果 Math.round(5.5) 呢,答案是 6 而不是 5 。关于这点需要有所了解。好吧我承认我较真了,但是知道了他有什么坏处呢。

当我们想从 2 个数中取得较小或者较大的数的时候怎么做呢?

if(a>b) {

return a;

} else {

return b;

}

我们多虑了。 Math 提供了 Math.max 和 Math.min 方法来帮助我们解决这个问题。

Math 还有一大堆的“静态”方法和属性。在这里我就不一一列举了,当我们要进行数学计算的时候不妨去查查手册。


...全文
4933 116 打赏 收藏 转发到动态 举报
写回复
用AI写文章
116 条回复
切换为时间正序
请发表友善的回复…
发表回复
foxlovw0813 2012-07-03
  • 打赏
  • 举报
回复
我现在才看这文章估计有点晚了,但是有个问题想咨询下,
这段代码:
var conf = {
syslang : 'cn'
};
Date.prototype.toFormatString = function(format) {
var weeks = {};
weeks['cn'] = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
weeks['en'] = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var self = this;
var fix = {
'yyyy' : self.getFullYear(),
'MM' : self.getMonth() + 1,
'dd' : self.getDate(),
'wk' : weeks[conf.syslang][self.getDay()],
'hh' : self.getHours(),
'min' : self.getMinutes(),
'ss' : self.getSeconds()
};
return format.replace(/[a-zA-Z]+/g, function(m) {
return fix[m];
});
};
有几个问题没有看懂,1.这段代码如何调用。2.return format.replace(/[a-zA-Z]+/g, function(m) {
return fix[m]; 这里面有个参数m,这个参数是放在了fix这个表里面,那么这个m参数如何使用啊?返回的值是什么呢?3.把this保存在self这儿变量里面的意义是指向调用这个函数的对象么?4.那个全局变量除了可以在fix里面使用,还有什么功能呢?
蓝色小棉袄 2012-06-04
  • 打赏
  • 举报
回复
新手,学习了,感谢楼主,这个太有用了!!!
a871084484 2012-03-16
  • 打赏
  • 举报
回复
楼主是个好人!!!
koumingjie 2011-02-15
  • 打赏
  • 举报
回复
真好!!!
peng115 2011-02-08
  • 打赏
  • 举报
回复
总结的不错!多谢分享!
kaifadi 2011-02-08
  • 打赏
  • 举报
回复
尽管以前也看过不少国产和国外的JS教材,但是精练中的经典,这个应该算是一个!
ljw159357789 2011-02-05
  • 打赏
  • 举报
回复
佩服!!
jackingod 2011-02-04
  • 打赏
  • 举报
回复
顶起来 ,好东西~
  • 打赏
  • 举报
回复
好东西,看看来了,极品
peter20091001 2011-01-29
  • 打赏
  • 举报
回复
楼主是强人啊。太牛了。
hongfarge 2011-01-29
  • 打赏
  • 举报
回复
看看也好事啦
wcfboy1 2011-01-29
  • 打赏
  • 举报
回复
不错,不错,基础的东西还是很常用的
DeathSteps 2011-01-28
  • 打赏
  • 举报
回复
这东西确实给力啊
ybb99 2011-01-28
  • 打赏
  • 举报
回复
到了 substring 方法, substring(from[,to]); 从定义上就可以看到,后一个参数是一个位置,而非长度,因此他更像 slice ,但是与之有一点重要的区别,那就是 substring 方法不包含 to 位置。即是一个半开半闭区间。
-----------------
其实slice 跟数组的slice方式一样 , to位置也是开区间,javascript:"iloveyou".slice(0,2) 返回“il”
xlg3030 2011-01-27
  • 打赏
  • 举报
回复
看看也好事啦
alsamsung 2011-01-26
  • 打赏
  • 举报
回复
“这里我们必须要弄明白 JavaScript 是 unicode 编码,那么汉字和英文都当作一个字符长度来处理”,哈哈,我一直没弄明白
谢谢楼主
csleo200x 2011-01-26
  • 打赏
  • 举报
回复
离职快乐,明年会有更好的发展
b11ght 2011-01-26
  • 打赏
  • 举报
回复
alert(arr1.valueOf() === arr2.valueOf());
为什么是false呢?想不明白。哪位高手给解答一下?
wangzexy391963822 2011-01-26
  • 打赏
  • 举报
回复
最近正在学Script,挺好!
风颜笑雪 2011-01-26
  • 打赏
  • 举报
回复
看看也好事啦
加载更多回复(48)
提供典型应用案例,剖析JSP/Servret技术与Struts 2技术在Web开发中的不同 提供完整的应用案例,使读者可以深入体会SSH开发模式的精髓 所有开发工具和框架均使用目前的最新版本,紧跟技术发展的趋势 提供230个实例和4个综合案例,可以作为案头必备的查询手册 一线开发人员全力打造,分享技术盛宴! 重点内容及特色 《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》介绍了Web开发中客户端技术的基础知识,包括JavaScript、CSS、AJAX等,这些技术都是Web应用中常用的客户端技术。 《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax+》讲解了JSP/S rvlet技术的基础知识,并提供了一个综合案例展示其具体应用,它们是Java Web服务端技术的基石,也是学习Java Web开发所要必须掌握的技术。 《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》重点讲解了Struts 2、Speing和HIbernate框架的基础知识和高级技术,如Sruts 2中的*、类型转换、国际化和标签等,HIbe rna{e的会话、0/R映射和事务管理等,Spring中的数据库技术与AOP等。 《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》特别介绍了Struts 2对AjAX的支持,还重点剖析了SSH框架的整合开发,并给出了两个综合案例来展示整合SSH框架开发Web应用。 和已经出版的同类图书相比,《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》讲解由浅入深,涵盖更多内容,列举了大量典型实例具有超强的实用性,另外,《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》各篇独立,适合读者全面学习或对部分内容重点学习。 读者对象 有Java基础,想进一步学习SSH框架整合开发的人员 了解SSH整合开发,想进一步提高开发技术的人员 正在使用SSH整合技术开发项目,想查阅资料的人员 大中专院校的学生和老师,以及Java培训班的学员和讲师 需要一本案头必备查询手册的程序员 光盘内容 6小时多媒体体视频讲解 《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》所涉及的源代码 布衣暖,菜根香,好书滋味长!清华大学出版社长期以来一直秉承为读者多出好书的宗旨,多年来为读者奉献了大量脍炙人口的精品图书。尤其在计算机图书出版领域更是形成了鲜明特色,所出版的各类计算机图书受到了广大读者的好评。本次出版的“原创经典,程序员典藏”系列图书是清华大学出版社的重点精品计算机图书,旨在帮助读者全面学习各类程序设计语言和开发工具,提高开发水平。同时也为广大程序员提供良好的技术参考,以便作为案头必备的查询手册。 内容提要 -------------------------------------------------------------------------------- 《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》通过对SSH中的各种技术循序渐进地讲解,使读者尽快掌握开发基于SSH的Web程序的方法。《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》内容包括Web客户端技术、JSP/Servlet技术、Struts 2(*、类型转换、输入校验、上传和下载文件、Struts 2的各种标签、对 AJAX的支持等)、Spring(Ioc容器、装配Java Bean、Jdbc和Hibernate模板、事务管理、Spring AOP等)以及 Hibernate(会话、映射、标准查询API、HQL、事务管理、锁等)。除此之外,《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》还提供了两个完整的实例来讲解开发SSH的详细步骤和方法。通过对这两个实例的学习,读者可以对SSH开发模式有更透彻地理解和认识。SSH是目前最流行的Java Web开发技术。 《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》适合广大从事Java Web开发工作的技术人员、对SSH开发感兴趣的人员以及大专院校学生阅读,尤其是具有一定的Web开发经验的技术人员。 目录 -------------------------------------------------------------------------------- 第1篇 web开发基础篇 第1章 搭建开发环境 1.1 本书使用的软件和框架的版本 1.2 JDK6的下载与安装 1.3 Eclipse3.4 的下载与安装 1.4 MyEclipse6.5 的下载与安装 1.5 Eclipse:IDEforJavaEEDevelopers的下载与安装 1.6 Tomcat6的下载与安装 1.7 在MyEclipse中配置。Tomcat 1.8 在EclipseIDEforJavaEEDevelopers中配置Tomcat 1.9 小结 第2章 JavaWeb应用开发基础 2.1 Web技术的发展 2.2 JavaWeb技术 2.2.1 Java.Welb程序的基本组成 2.2.2 Java,Web程序的目录结构 2.2.3 JavaWeb程序的配置文件 2.3 MVC模式与MvC框架 2.3.1 JSP模型1和JSP模型2 2.3.2 Web应用程序需要的基础服务 2.3.3 MVC模式概述 2.3.4 常用的MvC框架 2.4 小结 第3章 Web开发中的客户端技术 3.1 常用的JavaScriptIDE简介 3.1.1 在MyEclipse中使用JavaScript 3.1.2 在EclipseIDEforJavaEE中使用JavaScript 3.1.3 在NetBeans中使用JavaScript 3.1.4 其他的JavaScriptIDE 3.2.1 avaScdpt语法基础 3.2.1 实例:编写第一个JavaScript程序:Greet 3.2.2 变量 3.2.3 原始类型 3.2.4 类型转换 3.2.5 函数与函数调用 3.2.6 类和对象 3.3 JavaScript高级技术 3.3.1 DOM技术概述 3.3.2 获得HTML元素的3种方法 3.3.3 实例:图像自动切换 3.3.4 正则表达式 3.3.5 实例:表格排序 3.4 CSS基础 3.4.1 CSS的基本语法 3.4.2 在Style属性中定义样式 3.4.3 在HTML中定义样式 3.4.4 在外部文件中定义样式 3.4.5 样式的继承 3.5 AJAX.基础 3.5.1 AJAX概述 3.5.2 实例:使用XMLHttpRequest获得Web资源 3.5.3 实例:使用XMLHttpRequest跨域访问Web资源 3.5.4 实例:AJAX的3种交换数据方法 3.6 小结 第4章 Servlet技术 4.1 Servlet的Helloworld程序 4.1.1 实例:在My Eclipse中编写Helloworld程序 4.1.2 实例:手工编写:Helloworld程序 4.2 Servlet基础 4.2.1 配置数据库连接池 4.2.2 数据库连接池的应用 4.2 -3实例:用doGet方法处理客户端请求 4.2.4 实例:用doPost方法处理客户端请求 4.2.5 实例:用service方法处理客户端请求 4.2.6 实例:初始化(init)和销毁(destroy)Servlet 4.2.7 实例:使用PrintWriter输出响应消息 4.2.8 实例:用ServletOutputStream显示图像 4.2.9 实例:使用RequestDispatcher包含Web资源 4.2.10 实例:使用RequestDispatcher转发Web资源 4.3 HttpServletResponse类的其他功能 4.3.1 产生状态响应码 4.3.2 设置响应消息头 4.3.3 实例:验证响应头设置情况 4.4 使用:HttpServletRequest获得请求消息 4.4.1 获取请求行消息 4.4.2 获取网络连接消息 4.4.3 获取请求头消息 4.5 处理Cookie 4.5.1 什么是Cookie 4.5.2 Cookie类中的方法 4.5.3 实例:用Cookie读写客户端信息 4.5.4 实例:用Cookie读写复杂数据 4.6 处理Session 4.6.1 什么是Session 4.6.2 HttpSession接口中的方法 4.6.3 HttpServletRequest接口中的Session方法 4.6.4 实例:通过Cookie跟踪Session 4.6.5 实例:通过重写uRL跟踪Session 4.7 Web开发的中文问题 4.7.1 Java的编码原理 4.7.2 实例:解决输出中文乱码问题 4.7.3 实例:解决服务端程序读取中文请求消息的乱码问题 4.7.4 实例:用AJAX技术发送和接收中文信息 4.7.5 实例:在请求消息头和响应消息头中转输中文 4.8 小结 第5章 JSP技术 5.1 用MyEclipse编写第一个JSP程序 5.1.1 实例:编写显示服务器当前时间的JSP程序 5.1.2 调试JSP程序 5.1.3 改变JSP的访问路径和扩展名 5.1.4 手动发布JSP程序 5.2 JSP的运行原理 5.2.1 Tomcat如何处理JSP页 5.2.2 分析由JSP生成的Servlet代码 5.3 JSP基本语法 5.3.1 JSP表达式 5.3.2 在JSP中嵌入Java代码 5.3.3.JSP声明 5.3.4.JSP表达式语言(EL) 5.3.5 实例:用EL函数替换HTML中的特殊字符 5.3.6 JSP页面中的注释 5.4 JSP指令 5.4.1 JSP指令简介 5.4.2 page页面指令 5.4.3 include加入指令 5.5.JSP的9个内置对象 5.5.1 out输出对象 5.5.2 pageContext封装对象 5.5.3 其他的JSP内置对象 5.6 JSP标签 5.6.1 插入标签 5.6.2 转发标签 5.6.3 传参标签 5.6.4 创建:Bean标签 5.6.5 设置属性值标签 5.6.6 获取属性值标签 5.7 JSP的标准标签库(JSTL) 5.7.1 如何使用JSTL 5.7.2 条件标签 5.7.3 循环标签 5.8 小结 第6章 用Servlet和JSP实现注册登录系统 第2篇 Struts 2篇 第7章 编写Struts 2的第一个程序 第8章 Struts 2进阶 第9章 Struts 2的* 第10章 Struts 2的类型转换 第11章 Struts 2的输入校验 第12章 文件的上传和下载 第13章 国际化 第14章 Struts 2的标签库 第15章 Struts 2对AJAX的支持 第16章 用Struts 2实现注册登录系统 第3篇 Hibernate篇 第17章 Hibernate的Helloworld程序 第18章 配置Hibernate 第19章 Hibernate的会话与O/R映射 第20章 Hibernate的查询与更新技术 第21章 Hibernate的高级技术 第4篇 Spring篇 第22章 Spring的Helloworld程序 第23章 反向控制(Ioc)与装配JavaBean 第24章 Spring中的数据库技术 第25章 Spring的其他高级技术 第5篇 综合实例篇 第26章 Struts 2与Hibernate、Spring的整合 第27章 网络硬盘 第28章 论坛系统

87,907

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧