数据类型、运算符、流程控制语句

1、JavaScript 定义了几种数据类型? 哪些是原始类型?哪些是复杂类型?原始类型(或基本数据类型)和复杂类型的区别是什么?

最新的 ECMAScript 标准定义了 7 种数据类型:

  • 6种原始类型(也称基本数据类型):
    • Number:整数和浮点数值(所谓浮点数值,就是该数值中必须包含一个小数点,并且小数点后面必须至少有一位数字)。
    • String:String类型用于表示由零或多个16位Unicode字符组成的字符序列,即字符串。字符串可以由双引号或单引号表示。
    • Boolean:Boolean类型只有两个字面值:true和false。
    • Undefined:Undefined类型只有一个值,即特殊的undefined。在使用var声明变量但未对其初值化时,这个变量的值就是undefined。对未声明的变量执行typeof操作符同样也会返回undefined值。
    • Null:Null类型是第二个只有一个值的数据类型,这个特殊的值
      是null。null值表示通常有意地指向不存在或无效的对象或地址的引用,从逻辑角度看,null值表示一个空对象指针,而这也正是使用typeof操作符检测null值时会返回“object”的原因。如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null而不是其他值。
    • Symbol :(ECMAScript 6 新定义)
  • 1种复杂数据类型:
    • Object:ECMAScript中的对象其实就是一组数据功能的集合。对象可以通过执行new操作符后跟要创建的对象类型的名称来创建。Object有三个子类型狭义的对象- 正则表达式(regexp),数组(array),函数(function)。

原始类型(或基本数据类型)和复杂类型的区别:

  1. 在内存中的存储方式:
    基本数据类型把数据名和值直接存储在栈当中。
    复杂数据类型在栈中存储数据名和一个堆的地址,在堆中存储属性及值。访问时先从栈获取地址,再到堆中拿出相应的值。

  2. 不同数据类型作为参数时,函数内部对参数的修改是否改变外部变量的值
    (1)基本数据类型作为参数时,函数内部对参数值的修改不会改变外部变量的值

function a(s){//定义以s为参数的函数,返回s的值


    s=100;


    return s;


    }


    var y=1;


    a(y);//y作为参数调用函数a


    console.log(y);//y还是为1

结果还是1因为把y的值给s时是简单的复制了一份,y和s可以单独操作不相互影响

(2)复杂数据类型作为参数时,函数内部对参数值的修改会改变外部变量的值

因为复杂数据类型赋值是把栈中对象的地址赋给变量,函数内外两个变量指向同一个对象,所以只要对象的属性值改变,两个变量值都会改变

function student(age,name,agrde){


    this.age=age;


    this.name=name;


    this.score=agrde;


    }




    var s1=new student(18,"wjq",2);//创建一个student对象

    function a(s){


    s.name=”xxx”;


    }


    a(s1)//把s1赋给s


    console.log(s1.name);//输出xxx

原始类型和对象的区别主要还是在内存中的保存形式,要弄懂js中简单数据类型和复杂数据类型的区别,关键还要搞懂两个在内存中的存储过程。

2.typeof和instanceof的作用和区别?

JavaScript有三种方法,可以确定一个值到底是什么类型。

  • typeof 运算符
  • instanceof 运算符
  • Object.prototype.toString.call() 方法

typeof 运算符

最常用的是 typeof 运算符,返回一个值的数据类型有以下几种结果:

  • "undefined" : 如果一个变量没有声明,或声明了而没有初始化;
// 变量声明了,但没有赋值
var i;
i // undefined

// 调用函数时,应该提供的参数没有提供,该参数等于undefined
function f(x) {
  return x;
}
f() // undefined

// 对象没有赋值的属性
var  o = new Object();
o.p // undefined

// 函数没有返回值时,默认返回undefined
function f() {}
f() // undefined
  • "boolean" : 如果这个值是布尔值;
typeof false // "boolean"
typeof true // "boolean"
  • "string" : 如果这个值是字符串;
typeof '345' // "string"
  • "number" : 如果这个值是数值;
typeof 345 // "number"
  • "object" : 如果这个值是对象(包括数组、正则表达式)或null;
var s1=new Object();
typeof s1 //"object"

var arr1=[1,2,3];
typeof arr1 //"object"

var pattern= /at/g;
typeof pattern //"object"

typeof null // "object"
  • "function" : 如果这个值是函数。
var f= function() {};
typeof f //"function"

注意:

  • null的返回值是object,这是由于历史原因造成的,1995年JavaScript语言的第一版,所有值都设计成32位,其中最低的3位用来表述数据类型,object对应的值是000。当时,只设计了五种数据类型(对象、整数、浮点数、字符串和布尔值),完全没考虑null,只把它当作object的一种特殊值,32位全部为0。这是typeof null返回object的根本原因。
    为了兼容以前的代码,后来就没法修改了。这并不是说null就属于对象,本质上null是一个类似于undefined的特殊值。

instanceof 运算符

instanceof是判断指定对象是否为某个构造函数的实例,返回值是truefalse

var v = new Object();
v instanceof Object // true

上面代码中,对象v是构造函数Object的实例,所以返回true。

instanceof运算符的左边是实例对象,右边是构造函数。它会检查右边构建函数的原型对象,是否在左边对象的原型链上。因此,下面两种写法是等价的。

v instanceof Object
// 等同于
Object.prototype.isPrototypeOf(v)

由于instanceof对整个原型链上的对象都有效,因此同一个实例对象,可能会对多个构造函数都返回true。

var d = new Date();
d instanceof Date // true
d instanceof Object // true

上面代码中,d同时是Date和Object的实例,因此对这两个构造函数都返回true。
instanceof的原理是检查原型链,对于那些不存在原型链的对象,就无法判断。

null instanceof Object // false

由于null 没有 prototype,即不存在原型,因此instanceof就认为该对象不是Object的实例。

JavaScript 之中,只要是对象,就有对应的构造函数。因此,instanceof运算符的一个用处,是判断值的类型。

var x = [1, 2, 3];
var y = {};
x instanceof Array // true
y instanceof Object // true

上面代码中,instanceof运算符判断,变量x是数组,变量y是对象。

注意,instanceof运算符只能用于对象,不适用原始类型的值。

var s = 'hello';
s instanceof String // false

上面代码中,字符串不是String对象的实例(因为字符串不是对象),所以返回false。

此外,对于undefined和null,instanceOf运算符总是返回false。

undefined instanceof Object // false
null instanceof Object // false

用法上的区别:

typeof 对数组 [] 和对象 {} 的返回值都是Object,无法区分数组和对象,但是instanceof可以区分。

var a = {};
var b=[];
typeof a // "object"
typeof b // "object"
a instanceof Array // false
a instanceof Object // true
b instanceof Array // true
b instanceof Object // true

3、如何判断一个变量是否是数字、字符串、布尔、函数

使用typeof 运算符可以判断一个变量是否是数字、字符串、布尔、函数。

数字

var a=1;
typeof a // 'number'

字符串

var b="string";
typeof b // "string"

布尔

var c=true;
typeof c //true

函数

var f=function() {};
typeof f // "function"

4.NaN是什么? 有什么特别之处?

(1)含义

NaN是 JavaScript 的特殊值,表示“非数字”(Not a Number),主要出现在将字符串解析成数字出错的场合。

100 - 'a' // NaN

上面代码运行时,会自动将字符串a转为数值,但是由于a不是数值,所以最后得到结果为NaN,表示它是“非数字”(NaN)。

需要注意的是,NaN不是一种独立的数据类型,而是一种特殊数值,它的数据类型依然属于Number,使用typeof运算符可以判断出来。

typeof NaN // 'number'

(2)特别之处

NaN不等于任何值,包括它本身。

NaN === NaN // false

由于数组的indexOf方法,内部使用的是严格相等运算符,所以该方法对NaN不成立。

[NaN].indexOf(NaN) // -1

NaN在布尔运算时被当作false。

Boolean(NaN) // false

NaN与任何数(包括它自己)的运算,得到的都是NaN。

NaN + 12 // NaN
NaN - 12 // NaN
NaN * 12 // NaN
NaN / 12 // NaN

(3)判断NaN的方法

isNaN方法可以用来判断一个值是否为NaN。isNaN()函数接受一个参数,该参数可以是任何类型,而函数会判断这个参数是否"不是数值"。isNaN()在接收到一个值之后,会尝试将这个值转换为数值。某些不是数值的值会直接转换为数值,例如"10"和"Boolean"。而任何不能被转换为数值的值都会导致这个函数返回true。

isNaN(NaN) // true
isNaN(123) // false
isNaN("123") // false
isNaN("123string") // true

isNaN只对数值有效,如果传入其他值,会被先转成数值。

出于同样的原因,对于对象和数组,isNaN也返回true。

isNaN({}) // true
// 等同于
isNaN(Number({})) // true

isNaN(['xzy']) // true
// 等同于
isNaN(Number(['xzy'])) // true

但是,对于空数组和只有一个数值成员的数组,isNaN返回false。

isNaN([]) // false
isNaN([123]) // false
isNaN([123,567]) // true
isNaN(['123']) // false

上面代码之所以返回false,原因是这些数组能被Number函数转成数值。

判断NaN更可靠的方法是,利用NaN是JavaScript之中唯一不等于自身的值这个特点,进行判断。

function IsNaN(value) {
  return value !== value;
}

5.如何把非数值转化为数值?

有三个函数可以把非数值转换为数值:

  • Number()
  • parseInt()
  • parseFloat()

Number()

转型函数Number()可以用于任何数据类型,而另外两个函数则专门用于把字符串转换成数值。

Number函数的转换规则:

  1. 如果是Boolean值,true 返回 1,false 返回 0 。
Number(true)    //1
Number(false)   //0
  1. 如果是数字值,就是原样。
Number(3.14)    //3.14
  1. 如果是null值,返回0。
Number(null) // 0
  1. 如果是undefined,返回NaN。
Number(undefined) // 0

5.如果是字符串,遵循下列规则:

  • 如果是字符串中只包含数字(包括前面带正号或负号的情况),则将其转化成十进制数值。
Number ('23')    // 23
Number ('+23')   // 23 
Number ('-23')   // -23
Number ('011')   // 11  前面的0会忽略
  • 如果字符串中包含的有效的浮点数,就会转化成对应的浮点数,前面的0会忽略。
Number ('3.14')    //3.14
Number ('03.14')   //3.14
  • 如果字符串中包含有效的十六进制格式,前两位为"0x..."的格式,会自动转化成相同大小的十进制数。
Number ('0x10')  // 16
  • 如果字符串是空字符串,则返回 0。
Number ('')  // 0
  • 如果字符串中包含除上述格式外的其他字符,则转化成NaN。
Number("123blue")  // NaN
Number(message)  // NaN,变量message未声明
  • 如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,然后再依照前面的规则转换字符串返回的字符串值。

parseInt()

  • parseInt方法用于将字符串转为整数。返回值只有两种可能,不是一个十进制整数,就是NaN。
parseInt ('120')       //120   整数转化成整数
parseInt ('3.14')    //3     浮点数转化前面的整数部分
parseInt ('    10')    //10    前面的空格会忽略
parseInt ('000010')    //10    前面的0会忽略
  • 如果parseInt的参数不是字符串,则会先转为字符串再转换。
parseInt(1.23) // 1
// 等同于
parseInt('1.23') // 1
  • 字符串转为整数的时候,是一个个字符依次转换,如果遇到不能转为数字的字符,就不再进行下去,返回已经转好的部分。
parseInt('8a') // 8
parseInt('12**') // 12
parseInt('12.34') // 12
parseInt('15e2') // 15
parseInt('15px') // 15
//上面代码中,parseInt的参数都是字符串,结果只返回字符串头部可以转为数字的部分。
  • 如果字符串的第一个字符不能转化为数字(后面跟着数字的正负号除外),返回NaN。
parseInt('abc')   // NaN
parseInt('.3')    // NaN
parseInt('')      // NaN
parseInt('+')     // NaN
parseInt('+1')    // 1
  • parseInt方法还可以接受第二个参数(2到36之间),表示被解析的值的进制,返回该值对应的十进制数。默认情况下,parseInt的第二个参数为10,即默认是十进制转十进制。
parseInt('1000', 10)    // 1000  以十进制解读(默认)
parseInt('1000', 2)     // 8    以二进制解读
parseInt('1000', 6)     // 216   以六进制解读
parseInt('1000', 8)     // 512   以八进制解读
parseInt('10', 37) // NaN   进制超出范围,就返回 NaN
parseInt('10', 1) // NaN  进制超出范围,就返回 NaN
parseInt('10', 0) // 10
parseInt('10', null) // 10
parseInt('10', undefined) // 10  第二个参数是0、null、undefined 则直接忽略

parseFloat ()

  • parseFloat用于将一个字符串转为浮点数。
parseFloat('3.14')         // 3.14  浮点数转浮点数
parseFloat('314e-2')       // 3.14  
parseFloat('0.0314E+2')    // 3.14  如果字符串符合科学计数法,则进行相应转换
parseFloat ('3.14abc')     // 3.14  如果字符串包含不能转换为浮点数的字符,则不再往后转换,返回已经转好的部分。
parseFloat ('    3.14')    // 3.14
parseFloat ('00003.14')    // 3.14  parseFloat方法会自动过滤字符串前面的空格
  • 如果参数不是字符串,或者字符串的第一个字符不能转换为浮点数,则返回NaN。
parseFloat([])     // NaN  空数组返回 NaN
parseFloat('FF2')  // NaN  第一个字符不能转化浮点数
parseFloat('')     // NaN  空字符串转化为 NaN

parseFloat () 和 Number () 的区别

parseFloat(true)       // NaN
Number(true)           // 1

parseFloat(null)       // NaN
Number(null)           // 0

parseFloat('')         // NaN
Number('')             // 0

parseFloat('123.45#')  // 123.45
Number('123.45#')      // NaN

parseInt()与parseFloat()的区别

区别(1):parseFloat()转换时,第一个小数点有效,小数点对parseInt()无效

parseFloat("22.34.5") //22.34
parseInt("22.34.5") //22

区别(2):parseFloat()始终会忽略前导的0

parseFloat()可以识别前面讨论过的所有浮点数值格式,也包括十进制整数格式。但十六进制格式的字符串则始终会被转换成0。由于parseFloat()直解析十进制值,因此它没有用第二个参数指定基数的用法。最后还要注意一点,如果字符串包含的是一个可解析为整数的数(没有小数点,或者小数点后都是0),parseFloat()会返回整数。

parseFloat("1234blue") //1234
parseFloat("0xA") //0
parseFloat("22.5") //22.5
parseFloat(22.34.5) //22.34
parseFloat("0908.5") //908.5
parseFloat("3.125e7") //31250000
parseFloat("4.0000") //4

6.==与===有什么区别

历史背景

确定两个变量是否相等是编程中的一个非常重要的操作。在比较字符串、数值和布尔值的相等性时,问题还比较简单。但在涉及到对象的比较时,问题就变得复杂了。最早的ECMAScript中的相等和不等操作符会在执行比较之前,先将对象转换成相似的类型。后来,有人提出了这种转换到底是否合理的质疑。最后,ECMAScript的解决方案就是提供两组操作数:相等不相等——先转换在比较,全等不全等——仅比较而不转换。

1.相等和不相等

这两个操作符都会先转换操作数,然后再比较它们的相等性。

在转换不同的数据类型时,相等和不相等操作符遵循下列基本规则:

  • 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false转换为0,而true转换为1;
false == 1 //false
false == 0 //true
true ==1 //true
true == 0 //false
  • 如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值;
"123" == 123 //true
  • 如果一个操作数是对象,另一个操作数不是,则调用对象的valueof()方法,用得到的基本类型值按照前面的规则进行比较;

这两个操作符在进行比较时则要遵循下列规则。

  • null和undefined是相等的。
null == undefined //true
  • 要比较相等性之前,不能将null和undefined转换成其他任何值
null +1 //1
undefined +1 //NaN
null == 0 //false
undefined == 0 //false
  • 如果有一个操作数是NaN,则相等操作符返回false,而不相等操作符返回true。
"NaN" == NaN //false
NaN == NaN //false
NaN != NaN //true
  • 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true;否则返回false。

2.全等和不全等

全等操作符只在两个操作数未经转换就相等的情况下返回true。

除了在比较之前不转换操作数之外,全等和不全等操作符与相等和不相等操作符没有什么区别。

"55" == 55 //true,因为转换后相等
"55" === 55 //false,因为在不转换的情况下,字符串不等于数值
null ==undefined //true
null === undefined //false

记住,null ==undefined会返回true,因为它们是类似的值;但null === undefined会返回false,因为它们是不同类型的值。

7.break与continue有什么区别

  • break语句立即退出循环,强制执行循环后面的语句(退出循环体)
var num = 0;
for (var i=1; i<10; i++) {
    if (i % 5 == 0) {
      break;
  }
  num++;
}
alert(num); //4
  • continue语句立即退出本次循环,执行下次循环(退出单次循环)
var num = 0;
for (var i=1; i<10; i++) {
    if (i % 5 == 0) {
      continue;
  }
  num++;
}
alert(num); //8

break和continue语句都可以与label语句联合使用,从而返回代码中特定的位置。这种联合使用的情况多发生在循环嵌套的情况下。

  • break语句与label语句联合使用
var num = 0;
outermost :
for (var i=0; i<10; i++) {
    for (var j=0; j<10; j++) {
        if (i ==5 && j == 5) {
            break outermost;
        }
        num++;
    }
}
alert(num);  //55

break语句后面带了一个参数:要返回到的标签。添加这个标签的结果将导致break语句不仅会退出内部的for语句(使用变量j的循环),而且也会退出外部的for语句(使用变量i的循环)。

var num = 0;
outermost :
for (var i=0; i<10; i++) {
    for (var j=0; j<10; j++) {
        if (i ==5 && j == 5) {
            break;
        }
        num++;
    }
}
alert(num);  //95
  • continue语句与label语句联合使用
var num = 0;
outermost :
for (var i=0; i<10; i++) {
    for (var j=0; j<10; j++) {
        if (i ==5 && j == 5) {
            continue outermost;
        }
        num++;
    }
}
alert(num);  //95

continue语句后面带了一个参数:要返回到的标签。添加这个标签的结果将导致continue语句会退出内部循环(这也就意味着内部循环少执行了5次),执行下一次外部循环(continue退出的是单次循环,继续执行下一次循环)。

var num = 0;
outermost :
for (var i=0; i<10; i++) {
    for (var j=0; j<10; j++) {
        if (i ==5 && j == 5) {
            continue; 
        }
        num++;
    }
}
alert(num);  //99

8.void 0 和 undefined在使用场景上有什么区别

undefined

  1. undefined 并不是保留词(reserved word),它只是全局对象的一个属性,在低版本 IE 中能被重写。
var undefined = 10;
 
// undefined -- chrome
// 弹出10 -- IE 8,低版本IE中
alert(undefined);
  1. 虽然undefined 在 ES5 中已经是全局对象的一个只读(read-only)属性,它不能被重写。但是在局部作用域中,还是可以被重写。
(function() {

  //局部作用域
  var undefined = 10;
 
  //弹出 10 -- chrome
  alert(undefined);
})();
 
(function() {

  //全局变量并赋值,因为在全局作用域undefiend不能被重写,所以赋值无效
  undefined = 10;
 
  // 弹出undefined -- chrome
  alert(undefined);
})();

void运算符

void 运算符能对给定的表达式进行求值,然后返回 undefined。

也就是说,void 后面你随便跟上一个表达式,返回的都是 undefined,都能完美代替 undefined。

那么,这其中最短的是什么呢?毫无疑问就是 void 0 了。其实用 void 1,void (1+1),void (0) 或者 void “hello”,void (new Date()) 等等,都是一样的效果。更重要的前提是,void 是不能被重写的(cannot be overidden)

ES5 大环境下,void 0 也有可以发挥作用的地方,用 void 0 代替 undefined 就能节省不少字节的大小。事实上,不少 JavaScript 压缩工具在压缩过程中,正是将 undefined 用 void 0 代替掉了。

9.代码练习

(1)以下代码的输出结果是?为什么?

console.log(1+1);//输出2,两个数字加法运算
console.log("2"+"4");//输出'24',两个字符串类型的做字符串拼接
console.log(2+"4");//输出'24',一个是数字一个是字符串,数字转化为字符串后拼接
console.log(+"4");//输出4,只有一个字符串会转换成数字输出
var a = 1;  
a+++a;  
// 3     等同于 (a++)+a,这里前面的(a++)为1,后面的a为2,++优先级高于+
typeof a+2;  
// 'number2'   等同于(typeof a)+2,前面为字符串‘number’,后面数值,拼接成字符串,typeof 优先级高于+
 var a = 1;
 var b = 3;
 console.log( a+++b );  
 // 4  括号里面等同于(a++)+b,前面的(a++)表达式值为1,先用a的值,用完后再给a自加1

(2)遍历数组,把数组里的打印数组每一项的平方

var arr = [3,4,5]

for (var i=0;i<3;i++){
  console.log(arr[i]*arr[i])
}
// 9  16  25

(3)遍历 JSON, 打印里面的值

var obj = {
 name: 'hunger', 
 sex: 'male', 
 age: 28 
}
for(a in obj){
console.log(a+":"+obj[a])
}
// name:hunger sex:male age:28

(4)下面代码的输出结果

var a = 1, b = 2, c = 3;
var val = typeof a + b ||  c >0    //  优先级顺序typeof   +  >   ||
console.log(val)    //  'number2' || true
// 输出‘number2’

var d = 5;
var data = d ==5 && console.log('bb')  
// console.log('bb') 输出了字符串bb,但它的返回值是undefined
console.log(data)  // data = true && undefined
//输出 undefined

var data2 = d = 0 || console.log('haha')  
    // console.log('haha') 输出了字符串haha,但它的返回值是undefined
console.log(data2)  // data2 = d = 0 || undefined
    //输出 undefined

var x = !!"Hello" + (!"world", !!"from here!!");  
    // true+(false, true),即true+true
console.log(x)  //  console.log (true+true)
    // 输出 2

补充:

逗号运算符用于对两个表达式求值,并返回后一个表达式的值。

'a', 'b' //返回"b"

var x = 0;
var y = (x++, 10);
x //1
y  //10

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

推荐阅读更多精彩内容