JavaScript01_基础知识

一、基本语法

  1. 基本语法
  • JavaScript的每个语句以;结束,语句块在花括号内{...}
  • JavaScript并不强制要求在每个语句的结尾加 ;,浏览器中负责执行JavaScript代码的引擎会自动在每个语句的结尾补上 ;
  • 语句具有缩进,通常是4个空格。非必须,但可以增强可读性!
  • 请注意: JavaScript严格区分大小写!
  1. 注释:
    行注释://
    块注释: /*...*/

  2. 变量
    关键字: var
    变量名:

  • 大小写英文、数字、$和_(下划线)的组合。
  • 且不能用数字开头。
  • 不能是JavaScript的关键字。
  • 严格区分大小写
var a; // 申明了变量a,此时a的值为undefined类型
var $b = 1; // 申明了变量$b,同时给$b赋值,此时$b的值为1
var s_007 = '007'; // s_007是一个字符串
var Answer = true; // Answer是一个布尔值true
var t = null; // t的值是null
  1. 动态语言:
    在JavaScript中,使用等号=对变量进行赋值。可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量:
var a = 123; // a的值是整数123
a = 'ABC'; // a变为字符串
  1. strict模式:
    如果一个变量没有通过var申明就被使用,那么该变量就自动被申明为全局变量; 为了修补JavaScript这一严重设计缺陷,ECMA在后续规范中推出了strict模式('use strict'),在strict模式下运行的JavaScript代码,强制通过var申明变量,未使用var申明变量就使用的,将导致运行错误。

二、数据类型

基本数据类型:number, string, boolean, undefined (储存数据)
引用数据类型:Number, String, Boolean, Object, Array, Function, Date,null (储存数据和功能)

基本类型 & 引用类型的对比:
基本类型只是储存数据,在 栈 开辟内存;
引用类型即能储存数据也能储存功能(函数),变量内在在栈内,存储地址,指向在 堆 开辟内存存储的数据。

基本类型 vs 引用类型
基本类型 vs 引用类型

//基本类型有对应的引用类型:
//number--->Number  boolean--->Boolean  string--->String

var a = "abc";  //基本类型字符串:string类型
var s = new Sting("abc");  //引用类型的字符串:Object类型

//最大的区别是:
a.text = "呵呵"; //基本类型不能添加属性
s.text = "哈哈"; //引用类型能添加属性

//引用类型的空  null 

Number类型

JavaScript不区分整数和浮点数,统一用Number表示。

123; // 整数123
0.456; // 浮点数0.456
1.2345e3; // 科学计数法表示1.2345x1000,等同于1234.5
-99;    //负数

NaN;  //NaN表示Not a Number,不是一个数字
Infinity; // Infinity表示无限大,当数值超过了JavaScript的Number所能表示的最大值时,就表示为Infinity

进制

十进制:
八进制:0_
十六进制:0x_


对照表:
十进制(D) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
二进制(B) 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 
八进制(O) 0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 
十六进制(H) 0 1 2 3 4 5 6 7 8 9 A B C D E F     


二进制:电信号开关
1 byte = 8bit <比特位>
1k = 1024 byte
1M = 1024k


八进制由来:每三位bit表示一位数字  就产生的八进制!
三个bit最大数值是:111 即7;


十六进制:每四个bit表示一位数字  就产生了十六进制。
四个bit最大数值是:1111 即15;


进制转换:
十进制转成其他进制:反复除以进制值取余数!
其他进制转换十进制:进制幂数和

字符串String

字符串是以单引号'或双引号"括起来的任意文本, 字符串abc由a,b,c这3个字符。

"abc"
'abc'

连接符和转义字符

连接符: +  
- 字符串类型和任何类型相连接,最终都是字符串类型!
var name = '小明';
var age = 20;
var message = '你好, ' + name + ', 你今年' + age + '岁了!';


转义字符:\  <反斜杠>
\n  换行
\t  制表符tab健
\\  \
\"  "
//ASCII字符可以以` \x## `形式的十六进制表示:
'\x41';  //完全等同于 'A'

//还可以用` \u#### `表示一个Unicode字符:
'\u4e2d\u6587';  //完全等同于 '中文'


模板字符串: ${} 
var name = '小明';
var age = 20;
var message = `你好, ${name}, 你今年${age}岁了!`;

字符串的常用Api

//字符串长度:
var s = 'Hello, world!';
s.length; // 13 空格 符号都计算在内


//下标:获取字符串指定位置的字符,索引号从0开始:
var s = 'Hello, world!';
s[0];  // 'H'
s[13];  //undefined 超出范围的索引不会报错,但一律返回undefined


//charAt(index) 获取对应索引的字符
var ss = "abc0123def&#*";
 ss.charAt(ss.length-1); //*
 ss.charAt(-1); //不存在返回空“_”
//遍历字符串
 for (var i = 0; i < ss.length; i++) {
    document.write(ss.charAt(i));
    document.write("<br />");
 }

//charCodeAt(index) 获取索引对应的字符的ASCII编码
 ss.charCodeAt(3)  //48

//fromCharCode()  根据ASCII编码生成字符串
var str = String.fromCharCode(48,49,90);


//indexOf(str)  指定字符or字符串 第一次出现的位置
//indexOf(str,posotion) 从指定位置开始第一次出现的位置
//lastIndexOf(str) 最后一次出现的位置
var s = 'hello, world';
s.indexOf('world');  // 返回7
s.indexOf('World');  // 没有找到指定的子串,返回-1

 

//截取
//substr(index)  //截取index开始至末尾,返回截取的新字符串
//substr(index1,num)  //截取index开始截取 num 个字符串,返回截取的新字符串
//subString(index)
//subString(index1,index2) //截取index1 到 index2-1 之间的字符
var s = 'hello, world'
s.substring(0, 5);  //从索引0开始到5(不包括5),返回'hello'
s.substring(7); // 从索引7开始到结束,返回'world'


//match(str)  返回匹配的字符串,是一个数组(引用类型)
//search(str)  str第一次出现时的起始位置
//replace(str1,str2)  用str2替换第一次出现的str1;返回新字符串
//split(",")  //根据,切割字符串,返回一个数组


//toUpperCase(): 全部变为大写
//toLowerCase(): 全部变为小写
var s = 'Hello';
s.toUpperCase();  // 返回'HELLO'
s.toLowerCase();  // 返回'hello' 

布尔值boolean

一个布尔值只有truefalse两种值。

true; // 这是一个true值
false; // 这是一个false值
2 > 1; // 这是一个true值
2 >= 3; // 这是一个false值

null和undefined类型

null表示一个“空”的值,它和0以及空字符串''不同,0是一个数值,''表示长度为0的字符串,而null表示“空”的引用类型。

undefined表示值未定义类型。

var a;
typeof a   //获取变量a的类型(undefined)   

数组Array

数组是一组按顺序排列的集合,集合的每个值称为元素。JavaScript的数组可以包括任意数据类型。

//数组初始化

//数组用` [] `表示,元素之间用` , `分隔。
var arr1 = [1, 2, 3.14, 'Hello', null, true];  //字面量的方式

//另一种创建数组的方法是通过` Array() `函数实现:
var arr2 = new Array(1, 2, 3);  // 创建了数组[1, 2, 3]
var arr3 = new Array(10); //长度为10 的数据
var arr4 = new Array(); //长度为0的数据,可以添加数据

数组的常用Api

//数组的元素可以通过索引来访问,索引的起始值为0:
var arr = [1, 2, 3.14, 'Hello', null, true];
arr[0]; // 返回索引为0的元素,即1
arr[5]; // 返回索引为5的元素,即true
arr[6]; // 索引超出了范围,返回undefined

//可以通过索引把对应的元素修改为新的值:
var arr = ['A', 'B', 'C'];
arr[1] = 99;
arr; // arr现在变为['A', 99, 'C']

//通过索引赋值时,即使索引超过了范围,同样会引起Array大小的变化:
var arr = [1, 2, 3];
arr[5] = 'x';
arr; // arr变为[1, 2, 3, undefined, undefined, 'x']


// 要取得Array的长度,直接访问length属性:
var arr = [1, 2, 3.14, 'Hello', null, true];
arr.length; // 6

//注意: 直接给length赋一个新的值会导致Array大小的变化:
var arr = [1, 2, 3];
arr.length; // 3
arr.length = 6;
arr; // arr变为[1, 2, 3, undefined, undefined, undefined]
arr.length = 2;
arr; // arr变为[1, 2]


// indexOf() : 搜索指定的元素的位置
var arr = [10, 20, '30', 'xyz'];
arr.indexOf(10); // 元素10的索引为0
arr.indexOf(60); // 元素30没有找到,返回-1
arr.indexOf('30'); // 元素'30'的索引为2



// slice() : 截取Array的部分元素,返回一个新的Array;原有数组不变
var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
arr.slice(0, 3); // 从索引0开始,到索引3结束,但不包括索引3: ['A', 'B', 'C']
arr.slice(3); // 从索引3开始到结束: ['D', 'E', 'F', 'G']
arr.slice();  //如果不给slice()传递任何参数,它就会从头到尾截取所有元素。复制一个Array。




// push()  向Array的末尾添加若干元素,返回新数据长度
// pop()  把Array的最后一个元素删除掉,返回被删除值
var arr = [1, 2];
arr.push('A', 'B'); // 返回Array新的长度: 4
arr; // [1, 2, 'A', 'B']

arr.pop(); // pop()返回'B'
arr; // [1, 2, 'A']
arr.pop(); arr.pop(); arr.pop(); // 连续pop 3次
arr; // []
arr.pop(); // 空数组继续pop不会报错,而是返回undefined
arr; // []



//unshift()  往Array的头部添加若干元素,返回新数据长度
//shift()    把Array的第一个元素删掉,返回被删除值
var arr = [1, 2];
arr.unshift('A', 'B'); // 返回Array新的长度: 4
arr; // ['A', 'B', 1, 2]

arr.shift(); // 'A'
arr; // ['B', 1, 2]
arr.shift(); arr.shift(); arr.shift(); // 连续shift 3次
arr; // []
arr.shift(); // 空数组继续shift不会报错,而是返回undefined
arr; // []



// splice()  修改Array的“万能方法”,它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素
// 实现 删除 添加 替换 功能!
var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 替换:从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只删除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不删除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']



// sort()  对当前Array进行排序,它会直接修改当前Array的元素位置
var arr = [6,3,17,"a","B","你好"];
arr.sort(); //默认按照ASCII字符顺序排序 [17,3,6,B,a,你好]

//传参:定义排序规则的函数(函数的返回值:负值---前者比后者小  零---相等  正值---前者比后者大)
function paixu(m,n){
    if (m>n) {
        return 1;
    } else if (m==n) {
        return 0
    } else {
        return -1;
    } 
}
arr.sort(paixu);  //[B,a,你好,3,6,17]


// reverse() 把整个Array的元素反转
var arr = ['one', 'two', 'three'];
arr.reverse(); 
arr; // ['three', 'two', 'one']



// concat()  把当前的Array和另一个Array连接起来,返回一个新的Array  
var arr = ['A', 'B', 'C'];
var added = arr.concat([1, 2, 3]);
added; // ['A', 'B', 'C', 1, 2, 3]
arr; // ['A', 'B', 'C']

实际上,concat()方法可以接收任意个元素和Array,并且自动把Array拆开,然后全部添加到新的Array里:
var arr = ['A', 'B', 'C'];
arr.concat(1, 2, [3, 4]); // ['A', 'B', 'C', 1, 2, 3, 4]



// join()  把当前Array的每个元素都用指定的字符串连接起来,然后返回连接后的字符串:
var arr = ['A', 'B', 'C', 1, 2, 3];
arr.join('-'); // 'A-B-C-1-2-3'

//toString() 把数据转成字符串,逗号链接
var arr = ['A', 'B', 'C', 1, 2, 3];
arr.toString(); // 'A,B,C,1,2,3'


多维数组
如果数组的某个元素又是一个Array,则可以形成多维数组:
var arr = [[1, 2, 3], [400, 500, 600], '-'];
var x = arr[1][1]; //返回 500

对象Object

JavaScript的对象是一组由键-值组成的无序集合;

  • 键都是字符串类型(每个键又称为对象的属性),
  • 值可以是任意数据类型。
JavaScript用一个{...}表示一个对象,
键值对以xxx: xxx形式申明,用,隔开。

//创建对象:四种方式
var obj1 = new Object();
var obj2 = Object(); 
var obj3 = {} 
var xiaoming = {
    name: '小明',
    birth: 1990,
    school: 'No.1 Middle School',
    height: 1.70,
    weight: 65,
    score: null
    newfunc: function() { //可以直接赋值匿名函数
       alert("newfunc")
    }
};

//访问属性: 点语法:对象变量.属性名
xiaoming.name; // '小明'
xiaoming.birth; // 1990
xiaoming.age; // 访问不存在的属性,返回undefined



//JavaScript的对象是动态类型,可以自由地给一个对象添加或删除属性:
var xiaoming = {
    name: '小明'
};

xiaoming.age = 18; // 新增一个age属性
xiaoming.age; // 18

delete xiaoming.age; // 删除age属性
xiaoming.age; // undefined

delete xiaoming.school; // 删除一个不存在的school属性也不会报错



// in  检测是否拥有某一属性:
var xiaoming = {
    name: '小明',
    birth: 1990,
    school: 'No.1 Middle School',
    height: 1.70,
    weight: 65,
    score: null
};

'name' in xiaoming; // true
'grade' in xiaoming; // false


//不过要小心,如果in判断一个属性存在,这个属性不一定是xiaoming的,它可能是xiaoming继承得到的:
'toString' in xiaoming; // true 因为toString定义在object对象中,而所有对象最终都会在原型链上指向object,所以xiaoming也拥有toString属性。


要判断一个属性是否是xiaoming自身拥有的,而不是继承得到的,可以用hasOwnProperty()方法:
var xiaoming = {
    name: '小明'
};
xiaoming.hasOwnProperty('name'); // true
xiaoming.hasOwnProperty('toString'); // false

Map & Set

JavaScript的对象有个小问题,就是键必须是字符串。但实际上Number或者其他数据类型作为键也是非常合理的。
为了解决这个问题,最新的ES6规范引入了新的数据类型 Map 和 Set。

注意:Map和Set是ES6标准新增的数据类型,请根据浏览器的支持情况决定是否要使用。

Map:
Map是一组键值对的结构,具有极快的查找速度。

var m = new Map(); //初始化一个空Map
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);  //初始化Map

m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);

m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 获取key对应的值  67

m.delete('Adam'); // 删除key 'Adam'
m.get('Adam'); // undefined

//注意:一个key只能对应一个value
var m = new Map();
m.set('Adam', 67);
m.set('Adam', 88);
m.get('Adam'); // 88 会冲掉前面的赋值



Set:
Set是一组key的集合,但不存储value。key不能重复。

var s1 = new Set(); // 初始化一个空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3
var s = new Set([1, 2, 3, 3, '3']);  //重复元素在Set中自动被过滤:

s.add(4) //添加元素
s.delete(3); //删除元素

iterable类型

遍历Array可以采用下标循环,遍历Map和Set就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable类型,Array、Map和Set都属于iterable类型。具有iterable类型的集合可以通过新的for ... of循环来遍历。

注意:for ... of循环是ES6引入的新的语法,请测试你的浏览器是否支持!

用for ... of循环遍历集合,用法如下:

var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);

for (var x of a) { // 遍历Array
    alert(x);
}
for (var x of s) { // 遍历Set
    alert(x);
}
for (var x of m) { // 遍历Map
    alert(x[0] + '=' + x[1]);
}



然而,更好的方式是直接使用iterable内置的forEach方法,它接收一个函数,每次迭代就自动回调该函数:

var a = ['A', 'B', 'C'];
a.forEach(function (element, index, array) {
    // element: 指向当前元素的值
    // index: 指向当前索引
    // array: 指向Array对象本身
    alert(element);
});

var s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
    alert(element);
});

var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
    alert(value);
});

//如果对某些参数不感兴趣,由于JavaScript的函数调用不要求参数必须一致,因此可以忽略它们:
var a = ['A', 'B', 'C'];
a.forEach(function (element) {
    alert(element);
});


三、运算符


表达式:运算符和变量常量组合在一起就叫做表达式!表达式一定有值!


5.1 算术运算符
+  - * / %  ++  --

++ 前后的区别
-- 

5.2 赋值运算符
=  +=  -=  /= *=  %=


5.3 关系运算符
返回值:true false 
>  >=  <  <=  ==  ===  !=   !==

==   只比较数值,不比较类型  100 == ”100“(true)
===  比较数值和数据类型    100 == ”100“(fasle)
!=   只比较数值,不比较类型  100 == ”100“(fasle)
!==  比较数值和数据类型      100 == ”100“(true)


==: 它会自动转换数据类型再比较;
=== : 它不会自动转换数据类型,如果数据类型不一致,返回false

一个例外是NaN,这个特殊的Number与所有其他值都不相等,包括它自己:
NaN === NaN; // false

唯一能判断NaN的方法是通过isNaN()函数:
isNaN(NaN); // true


5.4 条件运算符
?:
(表达式):(值1)?(值2)


5.5 逻辑运算符
或与非: ||  &&  ! 
表达式值:true  false 

短路计算:
&&:当前面一个条件不满足即可返回,不再计算右边余下表达式的值。  
||:当前面一个条件为true可返回,不再计算右边余下表达式的值。  

3&&6  返回6-true
0&&6  返回0
“hello”&&“world”   返回值world (空字符串相当于false,非空字符串相当于true)
“”&&“hello”   返回值“”


5.6 typeof运算符
js是弱类型语言,var 变量可以存放各种类型;通过(typeof 变量名) 获取数据类型


四、流程控制

4.1 条件语句

  1. if&ife结果语句
if (true) { 
    ...
}

if (true) {
    ...
} else {
    ...
}

if ( ) {
    ...
} else if ( ) {
    ...
} else if ( ) {
    ...
} else {
    ...
}

//嵌套
if (true) {
    if (true) {

    }
} else {
    
}

注意1:单条语句 可以省略花括号。
注意2:else总是和离它最近的且没有对应的if对应。
注意3:JavaScript把null、undefined、0、NaN和空字符串'' 视为false`,其他值一概视为true。

  1. switch语句:
switch ()
{
    case 值1:语句; break;
    case 值2:语句; break;
    case 值3:语句; break;
    default:语句; break; <default可以放在任何位置>
}


//注意1:case后面可以是 常量 变量 表达式。
case 9: alert("常量"); break;
case a: alert("变量"); break;
case s>90: alert("表达式"); break; //比较表达式的值


注意2:如果没有`break`,代码会继续执行,向下贯穿, 且不会判断条件。

4.2 循环结构哦

  1. while
while (condition) 
{
    //循环体
}
  1. do...while
do {
    //循环体
}while (condition);
  1. for 循环
for (循环变量初始化语句; 循环条件; 循环变量的改变) {
      //循环体
}   

for (var i = Things.length - 1; i >= 0; i--) {
    Things[i]
}

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


var i = 0; //第一步可以写在外面
for (; i < Things.length; i++) {
    Things[i]
}

for (var i = 0; i < Things.length; ) {
    Things[i]
    i++  //第三步可以写在循环体内
}

  1. for...in...
var o = {
    name: 'Jack',
    age: 20,
    city: 'Beijing'
};

for (var key in o) {
    alert(key); // 'name', 'age', 'city'
}

//要过滤掉对象继承的属性,用hasOwnProperty()来实现:
for (var key in o) {
    if (o.hasOwnProperty(key)) {
        alert(key); // 'name', 'age', 'city'
    }
}


//Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。for ... in循环可以直接循环出Array的索引:
var a = ['A', 'B', 'C'];
for (var i in a) {
    alert(i); // '0', '1', '2'  //注意,for...in对Array的循环得到的是String而不是Number。
    alert(a[i]); // 'A', 'B', 'C'  
}
  1. break和continue
continue 结束本轮循环,继续下一轮循环。
break 结束所在的整个循环,不影响外部循环。


flag:
for (var i = Things.length - 1; i >= 0; i--) {
    Things[i]
    if (true) {
        break flag: //结束外部循环的方法,加标签flag。
    }
}


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

推荐阅读更多精彩内容