关于js的面试题,前段js面试题,送你43道JS面试题(收藏)

关于js的面试题,前段js面试题,送你43道JS面试题(收藏)

本文主要介绍送你43个JS面试问题。边肖认为这很好。现在分享给大家,给大家一个参考。来和边肖一起看看吧。

导读

两天前,GitHub Trending repositories由一个名为javascript-questions的项目主导,其中记录了一些javascript主题。

大概从头到尾看了一遍,都是基础题。我大概花了半个小时(有些题比较简单,可以一扫而光)做完这些题。虽然题很简单,但是每道题都对应一个知识点。如果你没接触过这个知识点,肯定会做错。如果你接触过这些知识点,那么这些题对你来说就很容易了。

我建议你也花半个小时做,以便查漏补缺。

为了方便大家更快的做题,又不浪费翻译时间,我花了几个小时翻译成中文,当然已经得到作者授权。

文中有些观点作者解释不全。为了更好的理解,我在文中补充了一些个人的解释。

仓库地址:https://github.com/lydiahallie/javascript-questions

JavaScript 进阶问题列表

我把日常的JavaScript选择题贴在我的Instagram上了,我也会贴在这里!

从基础到高级:测试你的JavaScript知识,刷新你的知识,或者准备你的编码面试!我每周都会用新问题更新这个项目。

答案在问题下方的折叠部分,只需点击即可展开。祝您好运

1. 下面代码的输出是什么?

函数sayHi() {

console.log(名称);

console.log(年龄);

var name=' Lydia

设年龄=21;

}

say hi();

答:莉迪亚和未定义

莉迪亚和参考错误

c:参考错误和21

d:未定义和引用错误

答案: D

在函数中,我们首先用var关键字声明name变量。这意味着变量会在创建阶段被提升(JavaScript会在创建变量的创建阶段为其分配内存空间),默认值是未定义的,直到我们实际执行到使用变量的那一行。我们还没有给name变量赋值,所以它仍然保存未定义的值。

用let关键字(和const)声明的变量也会有变量提升,但与var不同的是,初始化没有提升。在我们声明(初始化)它们之前,它们是不可访问的。这就是所谓的“临时死区”。当我们试图在声明变量之前访问它时,JavaScript抛出一个ReferenceError。

译者注:

关于let的变量提升的存在性,为什么我们用下面的例子来验证:

let name='ConardLi '

{

console.log(name) //未捕获的引用错误:未定义名称

Let name='代码秘密花园'

}

如果let中没有变量promotion,console.log(name)会输出ConardLi,只会抛出一个ReferenceError,很好的说明了这一点。let中也有变量提升,但它有一个“临时死区”,在变量初始化或赋值之前不允许访问。

变量的分配可以分为三个阶段:

创建变量以在内存中腾出空间。

初始化变量,将变量初始化为未定义

真实赋值

关于字母、变量和函数:

let的“创建”过程得到了提升,但初始化却没有。

推动了var的“创建”和“初始化”。

功能的“创建”、“初始化”和“赋值”都被提升。

2.以下代码的输出是什么?

for(var I=0;i3;i ) {

setTimeout(()=console.log(i),1);

}

for(设I=0;i3;i ) {

setTimeout(()=console.log(i),1);

}

答:0 1 2和0 1 2

乙:0 1 2和3 3 3

丙:3 3 3和0 1 2

答案: C

由于JavaScript中的事件执行机制,实际执行setTimeout函数时,循环已经结束。因为第一个循环中的变量I是用var关键字声明的,所以该值是全局的。在循环过程中,我们将在每次使用一元运算符时将I的值增加1。所以在第一个例子中,当调用setTimeout函数时,I已经被赋值为3。

在第二个循环中,变量I是用let关键字声明的:用let(和const)关键字声明的变量有一个块范围(块是{}之间的任何东西)。在每次迭代中,I将被创建为一个新值,每个值将存在于循环内的块级范围内。

3. 下面代码的输出是什么?

常量形状={

半径:10,

直径(){

返回this . radius * 2;

},

周长:()=2 *数学。PI * this.radius

};

shape . diameter();

shape . perimeter();

二十岁和六十二岁。38860.68686868686

乙:20和南

丙:二十和六十三

南和63

答案: B

注意直径是常用函数,周长是箭头函数。

对于arrow函数来说,这个关键字指向它所在上下文的环境(定义它的地方),和普通函数不一样!这意味着当我们调用perimeter时,它并不指向shape对象,而是指定义它时的环境(窗口)。没有值radius属性,返回undefined。

4. 下面代码的输出是什么?

真实;

!莉迪亚';

答:1和假

假的和难的

丙:假的,假的

答案: A

一元加号试图将布尔类型转换为数字类型。True转换为1,false转换为0。

字符串“Lydia”是一个真值。我们实际上问的是“这个真值是假的吗?”。这将返回false。

5. 哪个选项是不正确的?

常数鸟={

尺寸:“小”

};

常量鼠标={

名字:“米奇”,

小:真的

};

老鼠。鸟。大小

老鼠[鸟.大小]

丙:老鼠[鸟['大小']]

d:所有的都有效

答案: A

在JavaScript中,所有对象键都是字符串(除了Symbol)。虽然有时我们可能没有给出字符串类型,但它们总是被转换成字符串。

解释JavaScript语句。当我们使用方括号符号时,它将看到第一个左括号[,然后继续,直到找到右括号]。只有这样,它才会评价这种说法。

Mouse [bird.size]:首先它会评估bird.size,然后变小。Mouse ["small"]返回true。

然而,使用点符号,这种情况不会发生。Mouse没有名为bird的键,这意味着mouse.bird是未定义的。然后,我们用点符号询问size:mouse.bird.size既然mouse.bird是未定义的,我们实际上是在询问undefined.size这是无效的,无法读取undefined的属性' size '会被抛出。

6. 下面代码的输出是什么?

让c={问候语:'嘿!'};

设d;

d=c;

c.greeting=' Hello

console . log(d . greeting);

你好

b:未定义

c:参考错误

d:类型错误

答案: A

在JavaScript中,当它们被设置为彼此相等时,所有对象通过引用进行交互。

首先,变量C保存对象的值。之后,我们把D指定为C的同一个引用作为宾语。

当您更改一个对象时,您可以更改所有对象。

7. 下面代码的输出是什么?

设a=3;

设b=新数(3);

设c=3;

console . log(a==b);

console . log(a===b);

console . log(b===c);

答:真的假的真的

假的假的真的

真的假的假的

假的真的真的

答案:c。

New Number()是一个内置的函数构造函数。虽然它看起来像一个数字,但它不是一个真正的数字:它有一堆额外的功能,是一个对象。

当我们使用==操作符时,它只检查是否有相同的值。它们的值都是3,所以它返回true。

译者注:==会触发隐式类型转换,右边的对象类型会自动解装箱为数字类型。

然而,当我们使用===操作符时,类型和值需要相等。new Number()不是一个数字,而是一个对象类型。两者都返回false。

8. 下面代码的输出是什么?

变色龙级{

静态颜色变化(新颜色){

this . new color=new color;

}

构造函数({ newColor='green' }={}) {

this . new color=new color;

}

}

const freddie=新变色龙({ newColor:'紫色' });

freddie.colorChange('橙色');

甲:橙色

紫色

c:绿色

d:类型错误

答案: D

颜色方法是静态的。静态方法仅存在于创建它们的构造函数中,不能传递给任何子方法。由于freddie是子对象,所以不会传递函数,所以freddie实例上没有freddie方法:throw TypeError。

9. 下面代码的输出是什么?

让问候;

greet ign={ };//错别字!

console . log(greet ign);

答:{}

B: ReferenceError:未定义greetign

c:未定义

答案: A

控制台将输出一个空对象,因为我们刚刚在全局对象上创建了一个空对象!当我们误将greeting输入为greeting时,JS解释器在浏览器中实际上将其视为global.greeting={}(或window.greeting={})。

要避免这种情况,可以用“用严”。这确保了变量必须在赋值前声明。

10. 当我们这样做时会发生什么?

函数bark() {

console.log('汪!');

}

bark.animal=' dog

没什么,这完全没问题!

b:语法错误。不能以这种方式向函数添加属性。

c:未定义

d:参考错误

答案: A

这在JavaScript中是可能的,因为函数也是对象!(除了原始类型以外的所有内容都是对象)

函数是一种特殊类型的对象。你自己写的代码不是一个实际的函数。该函数是一个具有属性的对象,该属性是可调用的。

11. 下面代码的输出是什么?

职能人员(名字,姓氏){

this . first name=first name;

this.lastName=姓氏;

}

const member=新人(' Lydia ',' Hallie ');

person . get full name=()=this . first name this . last name;

console . log(member . get full name());

答:类型错误

语法错误

丽迪雅海莉

d:未定义

答案: A

您不能像处理常规对象一样向构造函数添加属性。如果你想一次给所有对象添加功能,你必须使用原型。所以在这种情况下应该这样写:

person . prototype . get full name=function(){

返回“{ this . first name } { this . last name } ”;

}

这将使member.getFullName()可用。为什么这是正确的做法?假设我们将这个方法添加到构造函数本身。也许不是每个Person实例都需要这个方法。这就浪费了大量的内存空间,因为它们还有这个属性,占用了每个实例的内存空间。相反,如果我们只把它添加到原型中,我们只需要把它放在内存中的一个位置,但是它们都可以访问它!

12.以下代码的输出是什么?

职能人员(名字,姓氏){

this . first name=first name;

this.lastName=姓氏;

}

const lydia=新人(' lydia ',' Hallie ');

const sarah=Person('Sarah ',' Smith ');

console . log(Lydia);

console.log(莎拉);

答:人{名:'莉迪亚',姓:'哈里' }且未定义

B: Person {firstName: 'Lydia ',last name:' Hallie ' } and Person { first name:' Sarah ',lastName: 'Smith'}

c:Person {名字:' Lydia ',姓氏:' Hallie'}和{}

d:Person {名字:' Lydia ',姓氏:' Hallie'}和ReferenceError

答案: A

对于莎拉,我们没有使用新的关键字。当使用new时,它指的是我们创建的新的空对象。但是,如果不添加new,它指的是全局对象!

我们指定this.firstName等于Sarah,this.lastName等于Smith。我们实际做的是定义global.firstName='Sarah '和global.lastName='Smith。莎拉自己的返回值是未定义的。

12. 事件传播的三个阶段是什么??

答:目标捕获冒泡

b:气泡目标捕捉

c:目标气泡捕捉

捕获目标冒泡

答案: D

在捕获阶段,事件通过父元素传递给目标元素。然后到达目标元素,开始冒泡。

13. 所有对象都有原型.

甲:是的

乙:错了。

答案: B

除了基本对象,所有对象都有原型。对象可以访问某些方法和属性,如。托斯特林。这就是为什么你可以使用内置的JavaScript方法!所有这些方法都可以在原型上找到。虽然JavaScript不能直接在你的对象上找到它,但是它会沿着原型链往下看,在那里找到它,这就允许你访问它。

译者注:基本对象是指原型链末端的对象。基础对象的原型为空。

14. 下面代码的输出是什么?

函数sum(a,b) {

返回a b;

}

sum(1,' 2 ');

b:类型错误

丙:“12”

D: 3

答案: C

JavaScript是一种动态类型语言:我们不指定某些变量的类型。在您不知情的情况下,该值可以自动转换为另一种类型,这称为隐式类型转换。强制从一种类型转换到另一种类型。

在本例中,JavaScript将数字1转换为字符串,以使函数有意义并返回值。当数字类型(1)和字符串类型(' 2 ')相加时,数字被视为字符串。我们可以将“hello”和“world”这样的字符串串联起来,所以这里发生的是“1”和“2”返回“12”。

15.以下代码的输出是什么?

让数字=0;

console.log(数字);

console.log(数字);

console.log(数字);

甲:1 1 2

乙:一二二

丙:0 2 2

D: 0 1 2

答案: C

后缀一元运算符:

返回值(返回0)

附加值(数字现在是1)

前缀一元运算符:

附加值(数字现在是2)

返回值(return 2)

所以返回0 ^ 2 ^ 2。

16. 下面代码的输出是什么?

函数getPersonInfo(一,二,三){

console.log(一个);

console.log(两个);

console.log(三个);

}

const person=' Lydia

const age=21

getPersonInfo`${person}今年${age}岁`;

答:莉迪亚21岁[' ','是','岁']

B: [' ','是','岁']莉迪亚21岁

c:莉迪亚[' ','是','岁'] 21岁

答案: B

如果使用标记的模板字符串,第一个参数的值总是字符串值的数组。rest参数获取传递给模板字符串的表达式的值!

17. 下面代码的输出是什么?

函数检查(数据){

if (data==={ age: 18 }) {

console.log('你是成年人了!');

} else if (data=={ age: 18 }) {

console.log('你还是个成年人。');

}否则{

console.log(`嗯.我猜你没有年龄`);

}

}

checkAge({年龄:18 });

答:你是成年人了!

乙:你还是个成年人。

列车员:嗯.我猜你没有年龄

答案: C

在比较等式中,基元类型通过它们的值进行比较,而对象通过它们的引用进行比较。检查JavaScript对象是否引用了内存中的相同位置。

我们作为参数传递的对象和我们用来检查相等性的对象在内存中的不同位置,所以它们的引用是不同的。

这就是为什么{age: 18}=={age: 18}和{age: 18}=={age: 18}返回false。

18. 下面代码的输出是什么?

函数获取(.args) {

console.log(参数类型);

}

赫塔奇(21);

答:“数字”

b:“数组”

c:“对象”

丁:‘南’

答案: C

扩展运算符(.args)返回一个带参数的数组。该数组是一个对象,因此typeof args返回一个对象。

20. 下面代码的输出是什么?

函数getAge() {

使用严格的';

年龄=21;

console.log(年龄);

}

getAge();

答:21

b:未定义

c:参考错误

d:类型错误

答案: C

使用strict确保不会意外声明全局变量。我们从未声明变量age,因为我们使用use strict ',它会抛出ReferenceError。如果我们不使用“使用严格的”,它将工作,因为属性年龄将被添加到全局对象。

21. 下面代码的输出是什么?

const sum=eval(' 10 * 10 5 ');

甲:105

乙:“105”

c:类型错误

丁:“10 * 10 ^ 5”

答案: A

Eval计算字符串传递的代码。如果它是一个表达式,就像在这种情况下,它将计算表达式。表达式10 * 10 ^ 5的计算结果为10 5。

22. cool_secret可以访问多长时间?

session storage . setitem(' cool _ secret ',123);

答:永远,数据永远不会丢失。

b:当用户关闭标签时。

c:当用户关闭整个浏览器时,不仅仅是标签页。

d:当用户关闭电脑时。

答案: B

关闭选项卡后,存储在sessionStorage中的数据将被删除。

如果使用localStorage,则数据将一直存在,除非调用了localStorage.clear()。

23. 下面代码的输出是什么?

var num=8;

var num=10

console . log(num);

答:8

乙:10个

c:语法错误

d:参考错误

答案: B

使用var关键字,可以用相同的名称声明多个变量。然后,变量将保存最新的值。

您不能使用let或const来做到这一点,因为它们是块范围的。

24. 下面代码的输出是什么?

const obj={ 1: 'a ',2: 'b ',3:' c ' };

const set=新集([1,2,3,4,5]);

obj . hasownproperty(“1”);

obj . hasownproperty(1);

set . has(' 1 ');

set . has(1);

假的真的假的真的

假的真的真的真的

真的假的真的

真的真的真的真的

答案: C

所有对象键(不包括符号)都将存储为字符串,即使您没有给定字符串类型的键。这就是obj.hasOwnProperty('1 ')也返回true的原因。

上述陈述不适用于Set。我们的集合中没有“1”:Set . has(' 1 ')返回false。它的数值类型为1,set.has(1)返回true。

25. 下面代码的输出是什么?

const obj={ a:'一',b:'二',a:'三' };

console . log(obj);

A: { a:'一',b:'二' }

B: { b:'二',a:'三' }

C: { a:'三',b:'二' }

d:语法错误

答案: C

如果一个对象有两个同名的键,前一个键将被替换。它仍将位于第一个位置,但具有最后指定的值。

26. JavaScript全局执行上下文为你创建了两个东西:全局对象和this关键字.

甲:是的

乙:错了。

列车员:这要看情况。

答案: A

基本的执行上下文是全局执行上下文:它是代码中任何地方都可以访问的内容。

27. 下面代码的输出是什么?

for(设I=1;i5;i ) {

if (i===3)继续;

console.log(一);

}

甲:1 2个

乙:一二三

丙:1 2 4

D: 1 3 4

答案: C

如果条件返回true,continue语句将跳过迭代。

28. 下面代码的输出是什么?

string . prototype . givelydiapizza=()={

回敬“已经给莉迪亚披萨了!”;

};

const name=' Lydia

name . givelydiapizza();

甲:“快给莉迪亚披萨吧!”

B: TypeError:不是函数

c:语法错误

d:未定义

答案: A

String是一个内置的构造函数,我们可以给它添加属性。我只是在它的原型上添加了一个方法。类型的原始字符串自动转换为string对象,该对象由string prototype函数生成。所以所有的字符串(string对象)都可以访问这个方法!

译者注:

当使用基本类型的字符串调用giveLydiaPizza时,实际上会发生以下过程:

创建字符串包装类型的实例

在实例上调用substring方法。

销毁实例

29. 下面代码的输出是什么?

const a={ };

const b={ key:' b ' };

const c={ key:' c ' };

a[b]=123;

a[c]=456;

console . log(a[b]);

甲:123

乙:456

c:未定义

d:参考错误

答案: B

对象自动转换为字符串。我们试图将一个对象设置为对象A的键,其值为123。

但是,当对象自动转换为字符串时,它就变成了[Object object]。所以我们这里说的是一个['Object object']=123。然后,我们可以再次尝试做同样的事情。c对象也将经历隐式类型转换。那么,a['Object object']=456。

然后,我们打印一个[b],实际上是一个['Object object']。我们将其设置为456,因此返回456。

30. 下面代码的输出是什么?

const foo=()=console . log(' First ');

const bar=()=setTimeout(()=console . log('秒'));

const baz=()=console . log(' Third ');

bar();

foo();

巴兹();

答:第一第二第三

乙:第一第三第二

丙:第二第一第三

d:第二第三第一

答案: B

我们有一个setTimeout函数,先调用它。但是,最后还是印出来了。

这是因为在浏览器中,我们不仅有运行时引擎,我们还有一个叫做WebAPI的东西。WebAPI为我们提供了setTimeout函数,比如DOM。

将回调推送到WebAPI后,setTimeout函数本身(但不是回调!)从堆栈中弹出。

现在,先调用foo并打印。

O FO弹出栈,baz被调用,Third被打印。

WebAPI不能只是在准备好的时候将内容添加到堆栈中。相反,它将回调函数推到一个叫做任务队列的地方。

这是事件循环开始工作的地方。事件在堆栈和任务队列中循环。如果堆栈为空,队列中的第一个内容将被占用并被推送到堆栈。

Bar被调用,Second被打印,并从堆栈中弹出。

31. 单击按钮时event.target是什么?

div onclick=' console . log(' first div ')'

div onclick=' console . log(' second div ')'

button onclick=' console . log(' button ')'

咔嚓!

/按钮

/div

/div

答:外部分区

b:内部分区

按钮

d:所有嵌套元素的数组。

答案: C

导致事件的最深嵌套元素是事件的目标。您可以通过event.stopPropagation停止冒泡

32.点击下面的html片段会打印出什么?

div onclick='console.log('div ')'

p onclick='console.log('p ')'

点击这里!

/div

答:p部门

乙:警队

列车员:p

D: div

答案: A

如果我们单击p,我们将看到两个日志:p和div。在一个事件的传播过程中,有三个阶段:捕捉、瞄准和冒泡。默认情况下,事件处理程序在冒泡阶段执行(除非将useCapture设置为true)。它从最深的嵌套元素向外延伸。

33. 下面代码的输出是什么?

const person={ name:' Lydia ' };

函数sayHi(年龄){

console.log(`${this.name}是$ { age } `);

}

sayHi.call(人,21);

sayHi.bind(人,21);

答:undefined 21岁,Lydia 21岁

功能功能

莉迪亚21岁了

莉迪亚是21函数

答案: D

使用这两者,我们可以传递我们希望这个关键字引用的对象。然而。调用方法将被立即执行!

的。bind方法返回函数的拷贝值,但是带有绑定的上下文!它不会被立即执行。

34. 下面代码的输出是什么?

函数sayHi() {

return(()=0)();

}

type of say hi();

答:“对象”

乙:“数字”

c:“功能”

d:“未定义”

答案: B

SayHi函数返回直接调用的函数(IIFE)的返回值。该函数返回0,这是一个数字。

仅供参考:只有7种内置类型:null、undefined、boolean、number、string、object和symbol。函数不是类型,因为函数是对象,它的类型是对象。

35. 下面这些值哪些是假值?

0;

新号码(0);

('');

(' ');

new Boolean(false);

未定义;

A: 0 ' ',未定义

B: 0,新数字(0),“”,新布尔值(假),未定义

C: 0,'',新布尔值(false),未定义

d:都是假值。

答案: A

JavaScript中只有6个错误值:

不明确的

圆盘烤饼

0

“”(空字符串)

错误的

函数构造器,比如new Number,new Boolean,都是真值。

36.以下代码的输出是什么?

console . log(type of type of 1);

答:“数字”

乙:“字符串”

c:“对象”

d:“未定义”

答案: B

Type1返回“数字”。

Typeof 'number '返回' string '

37. 下面代码的输出是什么?

常数numbers=[1,2,3];

数字[10]=11;

console.log(数字);

答:[1,2,3,7 x null,11]

乙:[1,2,3,11]

C: [1,2,3,7 x空,11]

d:语法错误

答案: C

当你给数组中的一个元素设置一个超过数组长度的值时,JavaScript会创建一个叫做“空槽”的东西。这些实际上具有未定义的值,但是您会看到类似于:

当你为数组中的一个元素设置的值超过数组的长度时,JavaScript会创建一个叫做“空槽”的东西。这些位置的值实际上是未定义的,但您会看到类似的内容:

[1,2,3,7 x空,11]

这取决于你在哪里运行它(每个浏览器可能不同)。

38.以下代码的输出是什么?

(()={

设x,y;

尝试{

抛出新错误();

} catch (x) {

(x=1),(y=2);

console . log(x);

}

console . log(x);

console . log(y);

})();

答:1未定义2

b:未定义未定义未定义

丙:1 1 2

D: 1未定义未定义

答案: A

catch块接收参数X.当我们传递参数时,这与变量x不同,这个变量x属于catch的范围。

之后,我们将这个块级作用域的变量设置为1,并设置变量y的值,现在,我们打印块级作用域的变量x,它等于1。

在catch块之外,x仍然是未定义的,而y是2。当我们想在catch块外console.log(x)时,它返回undefined,而y返回2。

39.JavaScript中的一切都是…

a:原创还是客体

b:功能还是对象

c:技能问题!仅对象

数字还是物体

答案: A

JavaScript只有基本类型和对象。

原始类型有布尔、空、未定义、bigint、数字、字符串和符号。

40. 下面代码的输出是什么?

[[0, 1], [2, 3]].减少(

(acc,cur)={

返回ACC . concat(cur);

},

[1, 2]

);

答:[0,1,2,3,1,2]

乙:[六,一,二]

丙:[1,2,0,1,2,3]

丁:[1,2,6]

答案: C

[1,2]是我们的初始值。这是我们reduce函数的初始值,也是第一个acc的值。第一轮,acc是[1,2],cur是[0,1]。我们把它们连接起来,结果是[1,2,0,1]。

那么,acc的值是[1,2,0,1],cur的值是[2,3]。我们把它们连接起来,得到[1,2,0,1,2,3]。

41.以下代码的输出是什么?

!null

!'';

!1;

答:假的真的假的

假的假的真的

假的真的真的

d:真的真的假的

答案: B

Null是一个假值。将null返回为true。True返回false。

是一个错误的值。 '返回true。True返回false。

1是真值。1返回false。True返回true。

42.“setInterval”方法的返回值是什么?

setInterval(()=console.log('Hi '),1000);

答:唯一的id

b:指定的毫秒数

c:传递的函数

d:未定义

答案: A

它返回一个唯一的id。这个id可以用来通过clearInterval()函数清除这个定时器。

43.这个回报是什么?

[.莉迪亚'];

答:['L ',' y ',' d ',' I ',' a']

乙:['莉迪亚']

C: [[],'莉迪亚']

D: [['L ',' y ',' d ',' I ',' a']]

答:答

字符串是迭代的。扩展操作符将迭代中的每个字符映射到一个元素。

这就是本文的全部内容。希望对大家的学习有帮助,支持我们。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: