第一课 初识javascript

概述

JavaScript是世界上最流行的脚本语言,是一种运行在浏览器中的解释型的编程语言,能够实现跨平台、跨浏览器。虽然只是十多天时间的产物,并且有很多的缺陷和陷阱,但也造就了JavaScript的灵活和强大。随着Node.js的兴起,JavaScript已经从单纯实现前端互动,发展到可以全栈实现整个应用。尤其是在移动互联网蓬勃发展以及应用追求极致用户体验的今天,JavaScript更是必须要重视和掌握的。

变量

使用var关键字进行变量的声明,声明的同时也可以进行赋值。变量的声明只能有一次,但赋值可以有多次。如果只声明变量,但是变量没有被赋值,此时变量的值为undefined。

JavaScript变量的类型取决于右侧的对象。

var variable_name1 = 5;
var variable_name2 = 5.3;
var variable_name3 = false;
var variable_name4 = 'zhangsan';

变量的作用域

JavaScript没有块级作用域

java:

if(true) {
    int a = 1;
}
System.out.println(a); // 编译错误,超出作用域

javascript:

if(true){
    var a = 1;
}
console.log(a); // 1 JavaScript没有块级作用域

JS中的六大数据类型

js中有六种数据类型,包括五种基本数据类型(Number,String,Boolean,Undefined,Null),和3种引用数据类型(Object,Function,Array)。

基本数据类型

1.Number类型

Number类型包含整数和浮点数(浮点数数值必须包含一个小数点,且小数点后面至少有一位数字)两种值。

2.String类型

单引号或双引号扩起来的字符集合

3.Boolean类型

该类型只有两个值,true和false

4.Undefined类型

只有一个值,即undefined值。使用var声明了变量,但未给变量初始化值,那么这个变量的值就是undefined。

5.Null类型

Null类型被看做空对象指针,Null类型也是空的对象引用。

三大引用类型

1.Object类型

我们看到的大多数类型值都是Object类型的实例,创建Object实例的方式有两种。

第一种是使用new操作符后跟Object构造函数,如下所示


var person = new Object();

person.name = "Micheal";

person.age = 24;

第二种方式是使用对象字面量表示法,如下所示


var person = {

name : "Micheal",

age : 24

};

alert(person.name);
2.Array类型

数组的每一项可以用来保存任何类型的数据,也就是说,可以用数组的第一个位置来保存字符串,第二个位置保存数值,第三个位置保存对象....另外,数组的大小是可以动态调整的。

创建数组的基本方式有两种

第一种是使用Array构造函数,如下所示


var colors = new Array("red","blue","yellow");

第二种是使用数组字面量表示法,如下所示


var colors = ["red","blue","yellow"];
3 Function类型

每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。函数通常是使用函数声明语法定义的,如下所示


function sum(num1,num2){

return num1 + num2;

};

这和使用函数表达式定义函数的方式相差无几。


var sum = function (num1,num2){

return num1 + num2;

};


var result = sum(5,8);
alert(result);

typeof 操作符

由于js中的变量是弱类型的,所以它提供了一种检测当前变量的数据类型的方法,也就是typeof关键字.


typeof 123   //Number

typeof 'abc'  //String

typeof true //Boolean

typeof undefined //Undefined

typeof null //Object

typeof { } //Object

typeof [ ] //Object

js的三种输出方式

/*  
             * 控制浏览器弹出一个提示框  
             */  
            alert("Hello JavaScript");  

            /*  
             * 控制浏览器在页面中输出一个内容  
             * document.write()向body中写一个内容  
             */  
            document.write("看我出来不???");  

            /*  
                向控制台输出一个内容  
             * */  
            console.log("你看我在哪出来~~~");  

js编写的位置

<!DOCTYPE html>  
<html>  
    <head>  
        <meta charset="UTF-8">  
        <title></title>  
        <!--可以将JS代码编写到script标签中-->  
        <!--<script type="text/javascript">  

            alert("hello");  

        </script>-->  

        <!--  
            还可以将JS代码编写到外部的js文件中,然后通过script标签来引入外部的文件  
            将JS代码编写到外部文件中,可以在不同的页面中引入相同的JS代码,  
                方便后期的维护,并且写在外部文件中可以使用浏览器的缓存,加快访问速度提高用户体验  

            如果使用script来引入外部文件,则它就不能在编写任何的JS代码了  ,  
                如果还需要编写则需要创建一个新的script标签  
        -->  

        <script type="text/javascript" src="js/script.js"></script>  
        <script type="text/javascript">  
            alert("我是内部的JS代码");  
        </script>  
    </head>  
    <body>  

        <!-- 
            将JS代码编写到标签的属性中,属于结构与行为耦合,不方便后期的维护,不推荐使用 
        -->  

        <!-- 
            可以将JS代码编写到标签的指定属性中 
        -->  
        <button onclick="alert('你点我干嘛~~~~');">点我一下</button>  

        <!-- 
            可以将JS代码编写到超链接的href中 
        -->  
        <a href="javascript:alert('讨厌!!!');">你也点我一下</a>  
        <br /><br />  
        <a href="javascript:;">你也点我一下</a>  

    </body>  
</html>  

练习

求100以内的偶数和

js字符串

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">

        /*
         * 
         * 在解析器的底层,保存字符串时,实际上是以字符数组的形式保存的
         *  所以字符串的操作方法和数组都是非常相似的
         * 
         */

        var str = "Hello neusoft";

        //console.log(str.length);
        //console.log(str[6]);
        /*
         * length可以用来获取一个字符串的长度
         */

        /*
         * charAt()
         *  - 可以根据索引来获取指定位置的字符
         * 
         * charCodeAt()
         *  - 可以根据索引来获取指定位置的字符的字符编码
         * 
         * String.fromCharCode()
         *  - 可以根据字符编码来获取字符
         */
        str = "中AaHello neusoft";

        var result = str.charAt(0);

        result = str.charCodeAt(0);

        result = String.fromCharCode(20013);

        //console.log(result);

        /*
         * concat()
         *  - 可以用来连接两个或多个字符串
         *  - 作用+ 一样
         */
        str = "hello";
        var str2 = "world";

        result = str.concat(str2,"你好","天气好","吃的好");

        /*
         * indexOf()
         *  - 检索指定字符串在当前字符串中的位置
         *  - 参数:
         *      第一个参数,要查询的字符串
         *      第二个参数,查找开始的位置
         * 
         *  - 返回值:
         *      默认会返回字符串第一次出现的位置的索引
         *      如果没有找到该内容,则返回-1
         * 
         * lastIndexOf()
         *  - 检索指定字符串在当前字符串中的位置
         *  - 该方法和indexOf()一样,不同的是indexOf()是从前往后找
         *      而lastIndexOf()是从后往前找
         */
        str = "Helo neusoft";

        //result = str.indexOf("a");
        //result = str.indexOf("l",3);
        result = str.lastIndexOf("l",5);

        /*
         * slice()
         *  - 可以用来截取一个字符中的内容
         *  - 参数:
         *      第一个参数,截取开始位置的索引(包括开始位置)
         *      第二个参数,截取结束位置的索引(不包括结束位置)
         *      - 可以接收一个负值作为参数,如果是负值,则从后往前数
         *      - 也可以省略第二个参数,如果省略则一直截取到最后
         */

        str = "Hello neusoft";

        result = str.slice(0,5);

        result = str.slice(5);

        /*
         * substring()
         *  - 用来截取字符串的
         *  - 参数:
         *      第一个参数,截取开始位置的索引(包括开始位置)
         *      第二个参数,截取结束位置的索引(不包括结束位置)
         *      - 该方法不接收负值,如果传递了一个负值,则默认会设置为0
         *      - 该方法中如果第二个参数小于第一个,则会调整参数的位置
         *  
         */
        str = "Hello neusoft";
        result = str.substring(6,0);

        /*
         * substr()
         *  - 用来截取字符串
         *  - 参数:
         *      第一个参数,截取开始位置的索引
         *          - 可以是负值,如果是负值从后往前数
         *      第二个参数,截取的个数
         */

        str = "Hello neusoft";
        result = str.substr(-3,2);

        //console.log(result);

        /*
         * split()
         *  - 可以将一个字符串拆分为一个数组
         *  - 它需要一个字符串作为参数,将会根据该字符串对字符串进行拆分
         *      并且将拆分的后的值保存到一个数组中返回
         */

        str = "孙悟空@猪八戒@沙和尚@唐僧";

        result = str.split("@");

        //console.log(Array.isArray(result));
        //console.log(result);

        /*
         * toLowerCase()
         *  - 将一个字符串转换为小写
         * toUpperCase()
         *  - 将一个字符串转换为大写
         */
        str = "abcdefg";

        result = str.toUpperCase();

        str = "ABCDEFG";

        result = str.toLowerCase();

        console.log(result);

        var myStr = "I,love,you,Do,you,love,me";
        var replacedStr = myStr.replace("love","hate");//"I,hate,you,Do,you,love,me";

        //replace默认只替换第一次查找到的,想要全局替换,需要置上正则全局标识,如
        var myStr = "I,love,you,Do,you,love,me";
        var replacedStr = myStr.replace(/love/g,"hate");//"I,hate,you,Do,you,hate,me"
    </script>
</head>
<body>
</body>
</html>

字符串练习

编写一个程序,将某个字符串反转

数组

数组简介

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script type="text/javascript">
            /*
             * 数组(Array)
             *  - 数组也是一个对象,功能和普通对象(Object)的功能类似的
             *  - 数组中也可以保存不同的元素,不同的是普通对象是通过一个字符串作为属性名来操作属性的,
             *      而数组是通过索引来操作元素的。
             *  - 索引(index)
             *      - 索引就是从0开始的整数
             *  - 数组比普通对象的存储效率要高,在开发中我们经常使用数组来存储一些数据
             */

            //创建一个数组对象
            var arr = new Array();

            //使用typeof检查一个数组对象时会返回object
            //console.log(typeof arr);

            /*
             * 向数组中添加元素
             *  - 语法:
             *      数组[索引] = 值;
             */
            arr[0] = 10;
            arr[1] = 20;
            arr[2] = 30;
            arr[3] = 40;
            arr[4] = 30;

            /*
             * 读取数组中的元素
             *  - 语法:
             *      数组[索引]
             */

            //如果读取一个数组中没有的元素,会返回undefined
            //console.log(arr[4]);

            //获取数组的长度
            /*
             * length
             *  - length属性可以获取或设置数组的长度
             *  - 对于连续的数组通过length属性获取到的就是数组中元素的个数
             */
            //console.log(arr.length);//获取数组的长度

            //修改数组的length属性
            //如果将长度修改为小于之前的长度的值,则多余的部分会被删除
            arr.length = 5;

            //如果将长度修改为大于之前的长度的值,则会数组中会创建出空的元素
            //arr.length = 10;

            //向数组的最后添加一个元素
            //语法:数组[数组.length] = 值;
            arr[arr.length] = 55;
            arr[arr.length] = 75;
            arr[arr.length] = 85;

            console.log(arr);

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

数组字面量表达方式(推荐)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script type="text/javascript">
            /*
             * 数组的字面量
             */
            //var arr = new Arry();
            var arr = [] ;

            /*
             * 使用字面量,可以在创建数组的同时,向数组中添加元素
             * 语法:
             *  var 数组 = [元素1,元素2...元素N];
             */
            arr = [1,2,3,4,5,6,7];

            //console.log(arr[6]);

            arr = new Array(1,2,3,4,5,6,7);

            arr = [10];//创建一个数组并向数组中添加一个元素

            arr = new Array(10);//创建一个长度为10的数组

            //console.log(arr.length);

            /*
             * 在数组中可以保存任意类型的元素
             */
            arr = [1,"hello",true,null,undefined,{name:"孙悟空"},function(){}];

            //console.log(arr[5].name);
            //console.log(arr[6]);

            //数组中也可以保存数组,如果数组中保存的依然是数组,则我们称这个数组为二维数组
            arr = [
                    [1,2,3],
                    [4,5,6],
                    [5,6,7]
                ];

            console.log(arr[0][1]); 

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

数组的常用方法

push(),pop(),unshift(),shift()

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script type="text/javascript">

            /*
             * 创建一个数组
             */
            var arr = ["孙悟空","猪八戒","沙和尚"];

            /*
             * push()
             *  - 该方法可以用来向数组的末尾添加新的元素,并返回数组的新的长度
             */

            //console.log(arr);

            var result = arr.push("唐僧","白骨精","蜘蛛精");

            //console.log(arr);
            //console.log("result = "+result);

            /*
             * pop()
             *  - 用来删除并返回数组的最后一个元素
             *  - 元素删除以后,会自动修正数组的长度
             */
            result = arr.pop();
            result = arr.pop();

            //console.log(arr);
            //console.log("result = "+result);

            /*
             * unshift()
             *  - 向数组的最前边添加元素,并返回新的长度
             */
            result = arr.unshift("牛魔王","铁扇公主");

            console.log(arr);
            //console.log("result = "+result);

            /*
             * shift()
             *  - 删除数组最前边的元素,并返回被删除的元素
             *  - 删除完元素以后,会自动调整数组的长度
             */
            result = arr.shift();
            result = arr.shift();

            console.log(arr);
            console.log("result = "+result);
            console.log(arr.length);

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

遍历数组方式一

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script type="text/javascript">

            /*
             * 创建一个数组
             */

            var arr = ["孙悟空","猪八戒","沙和尚","唐僧","白骨精","蜘蛛精"];

            /*
             * 遍历数组
             *  - 遍历数组就是指将数组中的每一个元素都获取到
             *  - 一般情况下遍历数组都是使用for循环来遍历
             */

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

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

遍历数组方式二:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script type="text/javascript">

            var arr = ["孙悟空","猪八戒","沙和尚","唐僧"];

            /*
             * 也可以使用forEach()来遍历数组
             *  forEach()中需要一个函数作为参数
             *  - 像这种由我们定义而不由我们调用的函数,我们称为回调函数
             *  - forEach()中的回调函数,由浏览器调用,
             *      数组中有几个元素函数就会被调用几次,
             *      每次遍历到一个元素都会调用一次函数,浏览器会通过实参的形式来将遍历到内容传递进函数
             *  - 浏览器在调用回调函数传递了三个实参:
             *      第一个参数:正在遍历的元素
             *      第二个参数:正在遍历的元素的索引
             *      第三个参数:正在遍历的数组对象
             * 
             *  - forEach()方法不支持IE8及以下的浏览器,所以如果需要兼容IE8则不要使用
             *      
             */
            arr.forEach(function(value , index , obj){

                console.log("value = "+value + "  index = "+index+" obj = "+obj);

            });

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

数组方法:slice(),splice():

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script type="text/javascript">

            var arr = ["孙悟空","猪八戒","沙和尚","唐僧"];

            /*
             * slice()
             *  - 可以用来截取数组中的指定元素
             *  - 参数:
             *      第一个参数,截取开始的位置(包括开始的位置)
             *      第二个参数,截取结束的位置(不包括结束的位置)
             *  - 该方法不会影响到原数组,而是将截取到的内容封装为一个新的数组返回
             *  - 可以传递一个负数作为参数,如果是负数,则从后往前数
             *      -1 表示 倒数第一 
             *      -2 表示 倒数第二
             *  - 如果省略第二个参数,则从开始位置一直截取到最后
             */

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

            result = arr.slice(1,-2);

            result = arr.slice(1);

            //console.log(result);

            /*
             * splice()
             *  - 可以用来删除数组中的元素,并添加新元素
             *  - 它会影响到原数组,一旦执行原数组中的元素将会被删除
             *  - 参数:
             *      第一个参数,开始位置的索引
             *      第二个参数,表示删除的个数
             *      第三个参数,这个方法还可以传递多个参数
             *          在第三个参数以后,可以跟多个元素作为参数,
             *          这些元素将会被插入到开始位置之前的位置
             *  - 它会将被删除的元素作为返回值返回
             *      
             */

            arr = ["孙悟空","猪八戒","沙和尚","唐僧"];

            //result = arr.splice(0,1);

            //牛魔王替换 索引为0的元素
            //result = arr.splice(0,1,"牛魔王");

            //arr.splice(2,1,"牛魔王","红孩儿","二郎神");

            arr.splice(2,0,"牛魔王","红孩儿","二郎神");

            console.log(arr);

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

练习 去除调用数组中重复的数字


<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script type="text/javascript">

            //创建一个数组
            var arr = [1,2,3,1,1,1,4,2,3,5];

            //去除调用数组中重复的数字
            //获取数组中的数字
            for(var i=0 ; i<arr.length ; i++){
                //console.log(arr[i]);
                //再次遍历数组
                for(var j=i+1 ; j<arr.length ; j++){
                    //console.log("----->" + arr[j]);
                    //比较两个数字是否相等
                    if(arr[i] == arr[j]){
                        //进入判断,证明两个数字重复,则删除arr[j]
                        arr.splice(j,1);
                        //需要在此位置在比较一次
                        j--;
                    }
                }
            }

            console.log(arr);

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

数组的其他方法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script type="text/javascript">

            var arr = ["孙悟空","猪八戒"];
            var arr2 = ["白骨精","蜘蛛精"];
            var arr3 = ["太上老君","如来佛祖"];

            /*
             * concat()
             *  - 可以用来连接两个或多个数组
             *  - 不会影响原数组,而是将新的数组的返回
             *  - 可以将多个数组作为concat参数传递,也可以传递单个的元素
             */
            var result = arr.concat(arr2 , arr3 , "唐僧");

            //console.log(result);

            /*
             * join()
             *  - 可以将数组中的所有的元素连接为一个字符串
             *  - 该方法可以接收一个字符串作为参数,这个字符串将会将会作为连接符来连接元素
             *      如果不传,默认使用,
             */
            arr = ["孙悟空","猪八戒","沙和尚"];

            result = arr.join("@-@");

            //console.log(result);

            /*
             * reverse()
             *  - 该方法可以用来反转数组
             *  - 前边的去后边,后边的去前边
             *  - 它会影响到原数组,直接在原数组上反转
             */

            //arr.reverse();

            //console.log(arr);

            /*
             * sort()
             *  - 可以用来对数组中的元素进行排序
             *  - sort()会影响到原数组
             *  - 默认它会按照元素的Unicode编码进行排序
             *  - 如果希望使用sort对一个数字型的数组进行排序可能会得到不可预期的结果
             *      因为它同样也会按照数字的Unicode编码进行排序
             *  - 我们也可以自己来指定排序的规则
             * 
             */
            var arr4 = ["a","c","b","e","d","f"];

            arr4.sort();

            //arr4 = [2,3,10,5,4,6];

            /*
             * 如果需要自定义排序规则,需要将一个函数作为参数传递给sort()方法
             *  函数的结构:function(a , b){}
             *  
             * 浏览器会多次以数组中的元素作为实参来调用该函数,
             *  a和b具体是谁不确定,但是a一定是在b前边
             * 浏览器将会根据函数的返回值,来决定两个元素是否交互位置
             *  如果返回一个大于0的值,则两个元素互相交换位置
             *  如果返回一个等于0的值,则证明两个元素相等,位置不变
             *  如果返回一个小于0的值,两个元素的位置也不变
             * 
             */

            arr4 = [10,4,3,5,2];

            arr4.sort(function(a,b){

                /*//升序  小 ---> 大
                if(a > b){
                    //交换位置
                    return 1;
                }else if(a == b){
                    return 0;
                }else{
                    return -1;
                }*/

                //降序 大 ---> 小
                /*if(a > b){
                    //交换位置
                    return -1;
                }else if(a == b){
                    return 0;
                }else{
                    return 1;
                }*/

                //如果希望升序排列,则 返回 a-b
                //return a - b;

                //如果希望降序排列,则 返回 b-a
                return b - a;

            });

            console.log(arr4);

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271