函数注脚的三种形式的界别,详解变量证明进步和函数评释进步

By admin in 4858美高梅 on 2019年4月2日

 大家知道根本字function用来定义函数;函数定义能够写成函数定义表达式,也足以写成语句的款式。例如上边包车型大巴两种写法

一. 变量证明升高

【修真院web小课堂】JS——预解析

  • 函数证明和函数表明式有啥样不同 (*)
    • 解析器会率先读取函数宣称,并使其在履行别的轮代理公司码从前能够访问;函数表明式则必须等到解析器执行到它所在的代码行才会被实践。
    • 函数评释:
var f = function(x){return x+1;}   //将表达式赋值给一个变量  函数表达式
function f(x){return x+1;}         //含有变量的语句        函数声明

1.1 变量定义

可以采纳var定义变量,变量若是未有赋值,那变量的伊始值为undefined。

世家好,小编是IT修真院达卡分院第一一期的学员,1枚正直纯洁善良的WEB程序员
前几日给大家享用一下,JS——预解析。

就算函数注解语句和函数定义表达式蕴含相同的函数名;但它们之间依旧有分别的。

一.二 变量成效域

变量功用域指变量起作用的范围。变量分为全局变量和1部分变量。全局变量在全局都抱有定义;而某些变量只可以在函数内卓有成效。
在函数体内,同名的一部分变量大概参数的优先级会高于全局变量。也正是说,要是函数内设有和全局变量同名的部分变量或许参数,那么全局变量将会被部分变量覆盖。
具有不使用var定义的变量都说是全局变量

1、背景介绍

console.log(sum(10,10));
function sum(num1, num2) {
      return num1 + num2;
}

相同点:两种艺术都成立了新的函数对象;两者都会被“提前”(函数语句中定义的函数被出示的超前到剧本或则函数的顶部,由此它们在方方面面脚本内可知);

壹.三 函数功能域和证明提前

JavaScript的函数效用是指在函数内评释的持有变量在函数体内始终是有定义的,也便是说变量在评释从前已经可用,全部那特色称为注脚提前(hoisting),即JavaScript函数里的兼具宣称(只是表明,但不关乎赋值)都被提前到函数体的顶部,而变量赋值操作留在原来的地点。如下边例子:
注释:声明提前是在JavaScript引擎的预编写翻译时实行,是在代码起始运维此前。

var scope = 'global';
function f(){
    console.log(scope);
    var scope = 'local';
    console.log(scope);
}

鉴于函数内证明提高,所以地方的代码实际上是如此的

var scope = 'global';
function f(){
    var scope;    //变量声明提升到函数顶部
    console.log(scope);
    scope = 'local';    //变量初始化依然保留在原来的位置
    console.log(scope);
}

4858美高梅 ,透过如此变形之后,答案就就可怜让人注目了。由于scope在率先个console.log(scope)语句在此以前就早已定义了,不过并未赋值,因而此时scope的指是undefined.次之个console.log(scope)语句以前,scope已经成功赋值为’local’,所以输出的结果是local。

JAVASC揽胜IPT解析机制是何等?

上述代码完全能够运作。因为在代码执行在此之前,解析器就已经通过多个名叫函数证明升高的进度,读取并将函数注脚添加到实践环境中。在履行sum(十,10)时JavaScript引擎会表明函数并将它们放到源代码树的顶部。等价于:

分歧点:函数评释语句中函数名是一个变量名,变量指向函数对象。和经过var注明变量1样,函数语句中定义的函数被展现的提前到剧本或则函数的顶部,因而它们在漫天脚本内可见;

二. 函数注明进步

JavaScript解析进度分成三个阶段,叁个是编写翻译阶段,其它三个正是执行等级。

function sum(num1, num2) {
      return num1 + num2;
}//函数放置在顶部被声明
console.log(sum(10,10));

1.选用var只有变量评释提前–变量的早先化任然在本来的职位,然则使用函数申明语句的话函数名称和函数体均提前

2.一 函数的三种成立格局

  • 函数注明
  • 函数表达式

编译阶段正是大家常说的JavaScript预解析(预处理)阶段,在那些等级JavaScript解释器将形成把JavaScript脚本代码转换成字节码。

  • 函数表明式:

总结:一句话来说函数表明式的主意(也正是var评释格局)函数唯有在var语句申明之后才能被调用;而函数注明(相当于function注脚情势)函数能够在函数表明以前调用。

二.2 函数宣称语法

f('superman');
function f(name){
    console.log(name);
}

运作方面包车型大巴主次,控制台能打字与印刷出supemran。

在编写翻译阶段JavaScript解释器借助执行环境把字节码生成机械码,并逐一执行。

这么些意况是 
 因为函数表明式是在函数运营的阶段才赋值给变量f;而函数注解在代码运营此前,约等于代码解析阶段就曾经赋值给了变量f

二.3 函数表明式语法

f('superman');
var f= function(name){
    console.log(name);
}

运维方面包车型客车代码,会报错Uncaught ReferenceError: f is not
defined(…),错误音讯展现说f未有被定义。
干什么同样的代码,函数申明和函数表明式存在着异样呢?
那是因为,函数评释有三个可怜重大的特色:函数注脚进步,函数注解语句将会被升高到表面脚本或然外部函数作用域的顶部(是否跟变量进步非凡周边)。便是因为那特性子,所以能够把函数表明放在调用它的言辞前边。如上边例子,最后的出口结果应当是怎样?:

var getName = function(){
    console.log(2);
}
function getName (){
    console.log(1);
}
getName();

唯恐会有人认为最终输出的结果是一。让我们来分析一下,那些事例涉及到了变量注明进步和函数注脚升高。正如前方谈到的函数评释提高,函数注明function
getName(){}的扬言会被提前到顶部。而函数表达式var getName =
function(){}则显示出变量证明升高。因而在那种景况下,getName也是三个变量,由此这么些变量的申明也将荣升到底层,而变量的赋值仍旧保存在本来的职位。因而位置的函数能够转换来上面包车型地铁样板:

var getName;    //变量声明提升
function getName(){    //函数声明提升到顶部
    console.log(1);
}
getName = function(){    //变量赋值依然保留在原来的位置
    console.log(2);
}
getName();    // 最终输出:2

据此最终的出口结果是:2。在本来的事例中,函数注脚即使是在函数表达式后边,但出于函数申明进步到顶部,由以前边getName又被函数表明式的赋值操作给覆盖了,所以输出二。

2.现实实践的操作

console.log(sum(10,10));
var sum = function(num1, num2) {
      return num1 + num2;
}

我们得以看上面包车型地铁代码

1.var , FUNCTION注明的变量进步

上述代码运营将会出错,因为函数处在三个var初阶化语句中,而不是三个函数注明。等价于

console.log(f,"函数前")
var f = function (x) {
      return x + 1;//函数表达式
 }
console.log(f,"函数后")

率先,创立一个当下履行环境下的运动目的,然后将用 VA奥迪Q5证明的变量设置为移动对象的天性(也正是将其添加到活动目的个中)并将其赋值为UNDEFINED,然后将
FUNCTION 定义的函数 也添加到移动对象当中。

var sum;
console.log(sum(10,10));
sum = function(num1, num2) {
      return num1 + num2;

而那段代码运转的结果

4858美高梅 1

在实践到函数所在的说话前,变量sum中不会保留有对函数的引用,那时var sum =
undefined;那么alert(undefined(10,10))是从未别的意义的,所以会出错。

4858美高梅 2

函数注脚的三种形式的界别,详解变量证明进步和函数评释进步。var定义的aa,bb以及function定义的AA(),BB()都会被变量提升到window对象上边

  • 怎样是变量的宣示前置?什么是函数的扬言前置 (**)
    • 变量的宣示前置:
      JavaScript引擎的工作章程是先分析代码,获取具有被声称的变量,然后再1行壹行地运作。全数的变量注脚语句都会被进步到代码顶部。
console.log(f,"函数前")
function f(x) {
   return x + 1;//函数声明
}
console.log(f,"函数后")

二. 函数评释与函数表达式在预解析的分别

结果

首先,大家领会解析器会对function定义的函数(约等于函数表明)在代码起先推行以前对其实施函数证明提高(function
declaration
hoisting),所以在函数表明在此以前调用该函数是不会在举行时期报错,可是函数表明式分歧,函数表明式用
var
证明,也正是说解析器会对其变量提高,并对其赋值为undefined,然后在执行时期,等到执行到该var
变量的时候再将其变量指向多少个function函数,所以在函数表明式此前实施该函数是会报错的。

console.log(a);
var a = 123;

4858美高梅 3

4858美高梅 4

上述代码输出为undefined,因为在进行时先分析了var
a,a评释后不曾赋值所以为undefined,然后再实施console语句,最终给a赋值为叁。能够写成:

 

3. function 覆盖

4858美高梅 5

若定义了多个同名的函数,则在预解析时期前面三个会覆盖签名一个。

var a;
console.log(a);
a = 123;

四. 预解析把变量或函数解析到其运作时的环境中

解析器将变量升高并不是将有着的变量都提高到window对象上面,其晋级的口径是进步到变量运转的环境中去。

4858美高梅 6

  • 函数的宣示前置:
    JavaScript引擎将函数名视同变量名,所以使用function
    一声令投注脚函数时,整个函数会像变量声圣元(Synutra)(Karicare)样,被升高到代码顶部。

伍. var 变量提高以及 function 函数申明提高

该点是对函数注脚以及函数表达式进一步的证实,其实前面函数注解和函数表明式在预解析的分化表现,其首要性的原故就是var 和 function
两者不一致的晋级。那个难点从剖析阶段到运行阶段来验证。首先,在条分缕析阶段 var
后面包车型客车 AA 会被升级然后 AA 被定义为undefined,BB
也会被升级,而BB被升级后的剧情就是一切 function
里面的始末,其实从浏览器的控制台大家得以看到一二。然后,整个解析过程完了就到了运转阶段,在运作阶段之间,当读到
AA() 的时候,其实就是将 AA
这些变量指向function(){}这么些函数然后调用,而到了 BB()
的时候,就会以前边扬言的函数中去摸索该早已经宣称的函数,然后径直调用。

4858美高梅 7

其一例子就很好注脚了 var 在运行阶段动态内建,而 function
在预解析阶段静态建立。

三、更加多研商

题材壹:下图分别收获到此值是怎么得来的?

4858美高梅 8

4858美高梅 9

答:第6个AA()是因为函数声音才会升级全部函数,所以首先个AA()执行的是函数申明function
AA(){};

第四个AA()是因为函数注明发出在预编译阶段;然后依照函数覆盖,所以进行函数表明式;

标题二、为何这么写,第四个AA()执行的依然函数表明式?

4858美高梅 10

变量在宣称它们的脚本或函数中都是有定义的,变量评释语句会被提前到剧本或函数的顶部。不过,变量开头化的操作还是在原来var语句的岗位执行,在宣称语句从前变量的值是undefined。

理由同题材壹,并不只是自上而下,产生了函数覆盖,而是因为预编写翻译的效用,函数证明提高到了最前方,在实践等级,函数评释已经编写翻译过了于是不会再编写翻译,然后被前边推行的函数表明式覆盖;

题材三、为啥第一个打字与印刷出来是undifined;而不是error;

4858美高梅 11

因为预编写翻译中的变量升高,此时首先个打字与印刷以前已经编译了var=undifined,只是var提高了,但值并不曾随着提高,此时还不曾对var赋值而已,但并不会报错。

如下图所示这么写就会报错;

4858美高梅 12

因此对于函数表明式,变量赋值是不会提早的,所以函数定义并未有被执行,所以函数表达式无法像函数评释那样进行函数表明提前。

fn();
function fn() {}

上述代码不会报错,因为在fn()执行前,函数function fn()
{}就被升级到代码的顶部,在履行fn()前就被声称了。能够写成:

function fn() {}
fn();

假诺使用赋值语句(函数表达式)定义函数就会报错:

fn();
var fn = function (){};
//error

上述代码在实施时变量fn只是被声称了并从未被赋值为函数,能够写成:

var fn;
fn();
fn = function (){}

那里的fn被声称后为undefined,执行到fn()时其实是undefined(),这些是从未意思的之所以会报错。

  • arguments 是什么 (*)
    • arguments对象:
      它与数组类似但不是Array实例。arguments能够使用类似数组的语法访问它每三个成分(第二个成分为arguments[0],第壹个成分为arguments[1]),也足以用length属性来鲜明传递了不怎么参数。

function say() {
      console.log("Hello " + arguments[0] + ", " + arguments[1]);
}
say("world", "morning"); //Hello world, morning
  • arguments对象的length属性:
    透过走访arguments对象的length属性能够领略有多少个参数字传送递给了函数。

function howManyArgs() {
      console.log(arguments.length);
}
howManyArgs("str", 123);//2
howManyArgs();//0
howManyArgs(123);//1
howManyArgs("str", 321, "str1");//3
  • 我们可以动用arguments对象的length属性让函数可以承受区别个数的参数并分别达成分化的作用。

function add() {
      if(arguments.length == 1) {
             console.log(arguments[0] + 10);
       }  else if (arguments.length == 2){
             console.log(arguments[0] + arguments[1]);
       }
}
add(10); //20
add(20, 30); //50
  • 上述代码中当只传递给函数三个参数时给这么些参数加上拾,当传递给函数三个参数时则那多个参数相加。arguments对象能够与命名的参数壹起行使,所以大家仍是能够写成上面那种样式

function add(num1, num2) {
      if(arguments.length == 1) {
             console.log(num1 + 10);
       }  else if (arguments.length == 2){
             console.log(arguments[0] +num2);
       }
}
add(10); //20
add(20, 30); //50
  • 此地大家能够领略num一与arguments[0]的值相同,它们能够调换。上例代码也告诉大家,不管您给函数命名了多少参数,JavaScript是不会管你给函数字传送递了不怎么参数的。
  • arguments的值与相应函数中命名参数的值保持同步:

function add(num1, num2) {
        arguments[1] = 10;
        console.log(arguments[0] + num2);
}
add(20, 30); //30
  • 上述代码每一回执行到add()函数都会重写第壹个参数,将第1个参数改写为10。arguments对象的值会对应到命名参数(arguments[1]与num二的值相同)所以修改了arguments[1]也就修改了num二,结果正是它们都改为了拾。那里arguments[1]与num二的值即便壹样,但它们的内部存款和储蓄器空间是不一样并且独自的,只是它们的值会同步。
  • 一旦大家在那边只传递了三个参数,那么arguments[1]设置的值不会反映到命名参数里。因为arguments对象的长短只是由传递到函数的参数个数控制(add(20,
    30)),不是由定义函数时命名的参数个数控制(function add(num一, num2)
    {})。
![](https://upload-images.jianshu.io/upload_images/2155778-a313c103bf6f16be.png)

只传递一个参数但赋值arguments\[1\]
  • 本条图里大家得以发现,执行函数时只传递了3个参数,在这么的气象下并未有传递值的命名参数(num二)被活动赋为undefined值。与只表明了变量但又不曾开头化赋值壹样。固然大家给arguments[1]赋值为十,num二的值如故还是undefined(只是值同步访问的上空是单身的)。

  • 函数的重载怎么样达成 (**)
    • 大家能够应用检查传入函数中参数的项目和数量来做出不相同的影响,用来模拟重载
    • 以通过拍卖传入的参数来完成类似重载的功力

function printPeopleInfo(name, age, sex) { 
if (name) { 
console.log(name); 
} 
if (age) { 
console.log(age); 
} 
if (sex) { 
console.log(sex); 
}
}
printPeopleInfo('Byron', 26);
printPeopleInfo('Byron', 26, 'male');
  • 经过遍历 arguments来落到实处类似重载的作用

function sum(){
var sum = 0;
for (var i = 0; i < arguments.length; i++) { 
sum = sum + arguments[i];
}
return sum;
}
console.log(sum(1,3,5));
  • 依据传入参数的两样门类来兑现重载

function addOrSay(num1, num2) {
      for (var i = 0; i < arguments.length; i++) {
              if(arguments.length == 1 && !isNaN(arguments[i])) {
                     console.log(num1 + 10);
               }  else if (arguments.length == 2 && !isNaN(arguments[i])) {
                     console.log(arguments[0] +num2);
               }  else {
                     console.log(arguments[i]) ;
               }
       }
}
addOrSay(10);//10
addOrSay(20, 30);//50
addOrSay("Hello");//Hello

4858美高梅 13

不等档次重载

  • 马上执行函数表明式是何许?有怎么着效益 (***)
    • 马上执行函数表明式(IIFE),是钦命义函数后随即实施函数;为了制止歧义,javascript规定,假设function关键字现身在行首,一律解释为语句,下边是三种立即实施函数表达式的写法,它们都以以圆括号开首的,javascript引擎就会以为后面是3个表明式而不是函数定义的言辞
    • 旋即执行函数的语法错误

function() {}()//这里出错是因为没把明确告诉圆括号运算符这里是一个表达式。
                      解析器把这段语句当成了一个函数声明。
                      函数声明又必须要有标识符作为函数名称。

function fn() {}()//加上标识符结果成了声明了函数fn  结果出错。                       
function fn() {}(1) //1   末尾的括号作为运算符,又必须要提供表达式做为参数。
  • 写成下列格局一贯调用时可以的

var fn = function() {}()//这样调用函数是可以的
  • 那么当要运用即时执行函数时得以利用括号来辅导解析器,指明括号运算符相近是3个表达式

 ( function() {}() );
 [ function() {}() ];//当括号出现在匿名函数的末尾想要调用函数时,
                          它会默认将函数当成是函数声明。 function fn() {}
 ( function() {} )();//默认为函数表达式 var fn = function() {}
  • 也足以动用1元运算符来写立即执行函数指点解析器

    ~ function() {}();
    ! function() {}();
    + function() {}();
    - function() {}();
  • 居然足以写成那样

delete function() {}();
typeof function() {}();
void function() {}();
new function() {}();
new function() {};
var f = function() {}();
--
1, function() {}();
1 ^ function() {}();
1 > function() {}();
  • 怎么样是函数的作用域链 (****)
    • 大局:在web浏览器中,全局执行环境就是window对象,全数的全局变量和函数都是作为window对象的习性(变量)和章程(函数)创设的。
    • 函数:各类函数都有温馨的实施环境,由{}与全局的window对象分别。
    • 效果域链:当代码在1个条件中施行时,会创造变量对象的三个意义域链保障对实施环境有权访问的具有变量和函数的稳步访问。

var color = "blue";
function changeColor() {
      if (color === "blue") {
          color = "red";
      }  else  {
          color = "blue";
      }
}
changeColor();
console.log("Color is now " + color);//Color is now red

在上述代码中,changeColor()函数的施用了大局环境下的变量color。函数能够在内部访问color正是因为能够在那一个作用域链中找到它。

var color = "blue";
function changeColor() {
         var anotherColor = "red";
         console.log(anotherColor, color);
         function swapColor() {
             var tempColor = anotherColor;
             anotherColor = color;
             color = tempColor;
             //这里可以访问color, anotherColor, tempColor
             console.log(tempColor, anotherColor, color);
          }
          //这里可以访问color, anotherColor,
          swapColor();
}
//这里只能访问color
console.log( color);
changeColor();

4858美高梅 14

运作效果

  • 如上代码共有多个执行环境:
    一 window全局环境:有二个变量color和二个函数changeColor()
    2changeColor()的局地环境:有2个变量anotherColor和三个swapColor()函数,但也能够访问全局环境中的变量color
    三swapColor()的有的环境:唯有3个变量tempColor,在那几个函数内得以访问到全局环境下的变量color,也足以访问changeColor()局地环境的anotherColor,因为别的多个条件是它的父执行环境。
![](https://upload-images.jianshu.io/upload_images/2155778-97546fc7609f9a09.png)

作用域链示意图
  • 参考:职能域链

  • 代码
    1 以下代码输出什么? (难度**)

  function getInfo(name, age, sex){
        console.log('name:',name);
        console.log('age:', age);
        console.log('sex:', sex);
        console.log(arguments);
        arguments[0] = 'valley';
        console.log('name', name);
    }

    getInfo('hunger', 28, '男');
    getInfo('hunger', 28);
    getInfo('男');
--
name: hunger
age: 28
sex: 男
["hunger", 28, "男"]
name valley
--
name: hunger
age: 28
sex: undefined
["hunger", 28]
name valley
--
name: 男
age: undefined
sex: undefined
["男"]
name valley

2 写三个函数,重临参数的平方和?如 (难度**)

function sumOfSquares(){
    var result = 0;
    for (var i = 0; i < arguments.length; i++) {
        result = result + arguments[i] * arguments[i];
    }
    return result;
   }
   sumOfSquares(2,3,4);   // 29
   sumOfSquares(1,3);   // 10

三 如下代码的出口?为啥 (难度*)

 console.log(a); 
 var a = 1;
 console.log(b);
//undefined   在浏览器中变量a被提升至顶部先被声明,执行到console.log(a)语句时变量a还没有被赋值。
//error   在整个全局中b并没有被赋值也没有被声明。

四 如下代码的输出?为何 (难度*)

    sayName('world');
    sayAge(10);
    function sayName(name){
        console.log('hello ', name);
    }
    var sayAge = function(age){
        console.log(age);
    };
//hello world  声明函数function sayName(name)被提升到顶部进行声明
所以执行sayName('world');时可以正常运行。
//error  函数表达式var sayAge = function(age){}中var sayAge被提升到顶部进行声明
这时候sayAge为undefined,执行到sayAge(10);时为undefined(10)没有意义。

5 如下代码的出口?为何 (难度**)

function fn(){}
    var fn = 3;
    console.log(fn);//3  声明完变量fn,又声明函数fn,最后赋值3给变量fn覆盖了

6 如下代码的输出?为啥 (难度**)

 function fn(fn2){
     console.log(fn2);
     var fn2 = 3;
     console.log(fn2);//3;
     console.log(fn);
     function fn2(){
        console.log('fnnn2');
    }
 }
fn(10);
/* function fn2(){
        console.log('fnnn2');
    } */  执行fn(10)时,参数10被传递到函数fn中并赋值给了fn2,
//在函数fn中提升声明变量fn2,并且提升声明函数fn2(){},这时候参数fn2的值被声明函数fn2覆盖,所以输出的是fn2函数
//3  执行完console.log(fn2); fn2变成变量并赋值为3
/* function fn(fn2){
   console.log(fn2);
   var fn2 = 3;
   console.log(fn2);//3;
   console.log(fn);
   function fn2(){
        console.log('fnnn2');
    }
 } */  执行console.log(fn);输出函数fn

七 如下代码的出口?为何 (难度***)

    var fn = 1;
    function fn(fn){
         console.log(fn);
    }
    console.log(fn(fn));//error  
    typeof(fn);//number 

在JavaScript中上述代码的变量和函数注脚会提升到最顶部开始表明,然后再赋值,所以能够写成:

    var fn;
     function fn(fn){
         console.log(fn);
    }
    fn = 1; 
    console.log(fn(fn));//这个时候fn是一个number,所以不能调用函数fn了。

捌 如下代码的出口?为何 (难度**)

    //作用域
    console.log(j);//undefined  //for循环不处在函数中声明的变量i和变量j仍然是全局变量,但是没赋值。
    console.log(i);//undefined  //同上
    for(var i=0; i<10; i++){
        var j = 100;
    }
    console.log(i);//10  //变量i在for循环中的i<10;i++递加到10。
    console.log(j);//100  //变量j在for循环中被赋值为100。

九 如下代码的输出?为啥 (难度****)

    fn();
    var i = 10;
    var fn = 20;
    console.log(i);
      function fn(){
        console.log(i);
        var i = 99;
        fn2();
        console.log(i);
        function fn2(){
            i = 100;
        }
    }
//undefined
//100
//10

上述代码能够写成下列方式

var i;
var fn;
function fn(){
/*statement*/
}
fn()//在这里执行fn(),下面看fn函数中是什么样的
    function fn(){
        var i;
        function fn2(){
            i = 100;
        }
    }
        console.log(i);//变量i只被声明输出undefined
        i = 99;
        fn2(); //这里执行函数fn2,变量i在函数fn2中赋值为100并返回
        console.log(i); // 输出100
    }
i = 10;
fn = 20;
console.log(i); //i被赋值为10,输出10

10 如下代码的出口?为何 (难度5*****)

    var say = 0;
    (function say(n){
        console.log(n);
        if(n<3) return;
        say(n-1);
    }( 10 ));
    console.log(say);
/* 10
     9
     8
     7
     6
     5
     4
     3
     2
     0 */

上述代码能够写成

    var say;
    (function say(n){
        console.log(n);
        if(n<3) return;
        say(n-1);
    }( 10 ));//立即执行函数,在声明时就开始给函数say传入参数10并执行say函数
当执行多次say(n-1)后n=2时被return返回并跳出函数say不在执行say(n-1)
    say = 0//say变量被赋值0并输出。
    console.log(say);
/* 10
     9
     8
     7
     6
     5
     4
     3
     2
     0 */

本博客版权归 本人和饥人谷所有,转载需说明来源

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有