2021-03-21

一、Let和Const

let声明变量,可变

const定义常量(实际指的是变量和的内存地址),不可变

只能在其声明或定义的代码块内有效

注:若区块中存在let或者const命令,则这个区块对这些变量和常量在一开始就行成封闭作用域,只要在声明之前使用就会报错(可能会出现暂时性死区)

不能重复声明,否则报错

(一)块级作用域

闭包:JS中的变量是没有作用域时的一个临时解决方案

块级作用域可以任意嵌套

外层作用域不能访问内层作用域的变量

内层作用域可以定义外层作用域的变量

函数中的块级作用域

es6中在块级作用域中可以声明函数

函数声明的语句和let的行为类似,在块级作用域外不能访问

函数声明也会提到块级作用域的头部

(二)ES6声明变量的6种方式

var

function

let

const

import

class

二、解构赋值

按照一定模式从数组和对象中提取值,然后赋值给变量

如果解构不成功,则变量的值为undefined

不完全解构:等号左边的模式值匹配一部分的等号右边的数组,仍然可以解构成功

解构赋值允指定默认值

默认值可以引起解构的其他变量,但是该变量必须已经声明

(一)对象的解构赋值

数组的元素是按照次序排列的,变量的取值是按照他的位置决定的,而对象没有次序,变量必须与属性同名才能取到正确的值

对象的解构也可以指定默认值,默认值生效的条件是,对象的属性严格的等于undefined

如果解构失败,变量的值就等于undefined

如果解构的模式是嵌套的对象,而且子对象所在的父属性不存在,则会报错

不会复制继承自原对象的属性

(二)字符串的解构赋值

字符串解构赋值时字符串被转换成了一个类似于数组的对象(类似于数组的对象还有一个length属性,也可对其赋值)

(三)数值和布尔的解构赋值

解构赋值时,如果等号右边是数值或者布尔值,则会先转换成为对象,在进行赋值

解构的规则:只要等号的右边不是对象或者数组,都会先将其转换成对象(注:undefined和null无法转换成对象,对其进行赋值时都会报错)

(四)函数的解构赋值

函数参数也可以进行解构,也可使用默认值

(五)圆括号问题

变量声明语句,模式不能使用圆括号(eg:函数的参数)

赋值语句的非模式部分可以使用圆括号

三、字符串的扩展

JS允许使用\uxxxx的形式表示一个字符,xxxx:字符的Unicode码点

在JS内部,字符以UTF-16的格式存储,每个字符固定为2个字节

codePointAt():能正确处理4个节点的字符,并返回一个字符的码点

参数:字符在字符串中的位置

String.fromCharCode():可以识别大于0xFFFF的字符

参数:大于0xFFFF的字符

at():可以识别Unicode编号大于0xFFFF的字符,返回正确的字符

参数:

normalize():将字符的不同表示方法表示为同样的形式

参数:可以接受一个参数来决定normalize的形式,有4个可选值

NFC(默认参数):标准等价合成,指视觉和语义上的等价

NFD:标准等价分解,在标准等价的前提下,返回合成字符分解出的多个简单字符

NFKC:兼容等价合成,返回合成字符。兼容等价 指语义上等价,直觉上不等价

NFKD:兼容等价分解:在兼容等价的前提下,返回合成字符分解出的多个简单字符

(一)除indexOf()外来确定一个字符串中是否包含灵感字符串的3中方法

includes():返回布尔值,表是否找到了参数字符串

参数:要查找的字符串

starsWith():返回布尔值,表参数字符串是否在源字符串的头部

参数:要查找的字符串

endsWith():返回布尔值,表参数字符串是否在源字符串的尾部

参数:要查找的字符串

其他一些方法

repeat():返回一个字符串,表示将原字符串重复n次

参数:次数n

注:

参数是小数,会被取整

参数是负数或者Infinity,会报错

参数在0-1之间,则等同于0

参数为NaN,则等同于0

padStar():头部补全 而 padEnd():尾部补全

参数1:指定字符串的最小长度

参数2:用于补全的字符串

注:

若原字符串的长度等于或大于指定的最小长度,返回原字符串

若用于补全的字符串与原字符串之和超出了指定的最小长度,则会截去超出位数的补全字符串

如果省略了第二个参数,会用空格补全

(二)模板字符串

``

可当做普通字符串使用

可定义多行字符串

可嵌套变量(需将变量写在${}中)

可调用函数

可嵌套模板字符串

String.raw():充当模板字符串的处理函数,返回一个反斜线都被转义的字符串,对应于替换变量后的模板字符串

也可当正常的函数使用,第一个从参数应该是一个具有raw属性的对象(应该是一个数组)

四、数值的扩展

ES6 中八进制要以前缀0o表示

(一)Number的扩展

Number.isFinite():检查一个数值是否为有限的

参数:要检查的数值

Number.isNaN():用于检查一个数值是否为NaN

参数:要检查的数值

Number.isInteger():判断一个数是否为整数

参数:要检查的数值

Number.isSafeInteger():判断一个数是否搂在这个范围之内,返回布尔值

参数:要检查的数值

(二)Math对象的扩展

Math.trunc():用于除去一个数的小数部分,返回整数部分

对于非数值,内部将其先转化为数值

对于空值和无法返回的值,返回NaN

参数:要检查的数值

Math.sign():判断一个数到底是正数,负数,还是0

参数有5中情况

参数为正数,返回+1

参数为负数,返回-1

参数为0,返回0

参数为-0,返回-0

其他值,返回NaN

注:对于非数值,会将其转换为数值

Math.cbrt():用于计算一个数的立方根(对于非数值,此案转换为数值)

Math.clz32():返回一个数的32位无符号整数形式有多少个前导0

参数:数值

对于小数,只考虑整数部分

对于空值和其他类型的值,先转换成为数值,在计算

Math.imul():返回两个数以32位带符号正数形式相乘的结果,返回的也是一个32位的带符号整数

Math.fround():返回一个数的单精度浮点数形式

Math.hypot():返回所有参数的平方和的平方根

若参数不是数值,会先转换成数值,在计算、

只要有一个参数无法转换为数值,就返回NaN

(1)对数

Math.expm1(x):返回e的x次方-1

Math.log1p(x):返回ln(1+x),如果x小于-1,返回NaN

Math.log10(x):返回以10 为底x的对数,如果小于0,返回NaN

Math.log2(x):返回以2 为底x的对数,如果小于0,返回NaN

(2)双曲函数

Math.sinh(x):返回x的双曲正弦

Math.cosh(x):返回x的双曲余弦

Math.tanh(x):返回x的双曲正切

Math.asinh(x):返回x的反双曲正弦

Math.acosh(x):返回x的反双曲余弦

Math.atanh(x):返回x的反双曲正切

(3)Math.signbit()

判断一个数的正负

参数是NaN,返回false

参数是-0,返回true

参数是负值,返回true

其他情况,返回false

(三)integer数据类型

必须要以后缀n来表示

二进制、八进制、十六进制都要以后缀n来表示

注:

几乎所有的Number运算都能用在integer中,除>>>和求证运算符+

Integer类型与Number类型不能混合运算,会报错

相等运算符(==)会改变数据类型,不能混合使用

精确相等运算符(===)不会改变数据类型,可以混合使用

五、函数的扩展

ES6允许为函数设置默认值,即直接写在参数定义的后面

使用参数默认值时,不能有同名的参数

注:参数默认值不是传值的,而是每次都重新计算默认值表达式的值(参数默认值是惰性求值)

通常情况下,定义了参数默认值的参数是函数的尾参数

有参数的默认值都是尾参数,除非显示输入undefined,如果传入的是undefined,将触发默认值,null不行

设置了默认值之后,或者默认值不是尾参数,函数的length不在计入后面的参数(length属性失真)

一旦设置了参数的默认值,函数在进行初始化的时候,参数会形成一个单独的作用域,等到初始化结束的时候,这个作用域消失(不设置参数默认值的时候不会出现)

利用参数默认值可以指定某一个参数不得省略,若省略则报错

可以将参数默认值设置为undefined,表示这个参可以省略

rest参数(形为“…变量名”),用于获取函数多余的参数

函数的name属性返回函数的函数名

箭头函数

ES6简明笔记中有

注:

箭头函数可以嵌套箭头函数

六、数组的扩展

扩展运算符 ( . . . )

主要用于函数调用

扩展运算符 后可以放表达式

如果扩展运算符后面是一个空数组,则不产生任何效果

可以合并数组

可以与结构赋值结合起来生成数组

若扩展运算符用于数组,只能放在参数的最后一位,否则报错

可以将字符串转为真正的数组

Array.from():将伪数组(两类对象:类似于数组的对象)转换为真正的数组

Array.of(一组值):将一组数转换为数组,若没有参数,则返回空数组

copyWithin():在当前数组内部将指定位置的成员复制到其他地方,然后返回数组(会修改数组)

接受3个参数

target(必选):从该位置开始替换数据

start(可选):从该位置开始读取数据,默认值为0,如果为负数,表示倒数

end(可选):到该位置停止读取数据,默认等于数组长度,若为负,表示倒数

fill():用于填充数组

参数1(必填):用于填充的给定值

参数2(可选):填充的起始位置

参数3(可选):填充的结束位置

entries()、keys()、value()用于遍历数组

entries():对键值对的遍历

keys():对键名的遍历

values():对键值的遍历

includes():表示某个数组是否包含给定的值,返回一个布尔值

参数1:给定值

参数2:搜索的起始位置,默认为0,若为负数,则表示倒数的位置,如果这时大于数组长度,则会重置为从0开始

数组的空位

数组的空位值数组的某一个位置没有任何值(空值不是undefined)

Array.from()会将数组的空位转换成为undefined

扩展运算符也会将空位转为undefined

copyWithin()会将空位一起复制

fill() 会将空位视为数组正常的位置

七、对象的扩展

ES6允许直接写入变量和函数作为对象的属性和方法

在对象中可只写属性名,不写属性值

可直接用标识符作为属性名,也可将表达式放在方括号内作为属性名(字面量定义)

Object.is():比较两个值是否严格相等,与严格相等运算符(===)的行为基本一致(注:有两个不同之处1:+0不等于 -0、2:NaN等于自身)

Object.assign():将源对象的所有可枚举属性复制到目标对象

第一个参数是目标对象,后面的参数是源对象

注:

只有一个参数,会返回改参数

若改参数不是对象,会先转换为对象,然后返回

由于undefined和null无法转换为对象,所以人工将它们作为参数就会报错

其他类似的值(数值、布尔)不在首参也不会报错,但是除了字符串会议数组的形式复制到目标对象,其他值都不会产生效果

Object.assign()是浅复制(即源对象的某个属性的值是对象,name目标对象复制得到的是这个对象的引用)

(一)对象的可枚举性

for…in循环:只遍历对象自身和继承的可枚举属性

Object.keys():返回对象自身的所有可枚举属性的键名

JSON.Stringify():只串化对象自身的可枚举属性

Object.assign():将源对象的所有可枚举属性复制到目标对象

注:所有class的原型的方法时不可枚举的

(二)属性的遍历

for…in:循环遍历对象自身和继承的可枚举属性(不包含Symbol属性)

Object.keys(obj):返回一个数组,包含对象自身的(不含继承的)所有可枚举属性(不包含symbol属性)

Object.getOwnPropertyNames(obj):返回一个数组,包含对象自身的所有属性(不含Symbol,但是含有不可枚举属性)

Object.getOwnPropertySymbols(obj):返回一个数组,包含对象自身的所有Symbol属性

Reflect.ownKeys(obj):返回一个数组,包含对象自身的所有属性,不管属性名是Symbol还是字符串,也不管是否可枚举

以上5中均遵循属性遍历次序规则

首先遍历所有属性名为数值的属性,按照数字排序

其次遍历所有属性名为字符串的属性,按照生成时间排序

最后遍历所有属性名为Symbol的属性,按照生成时间排序

(三)_ _ proto _ _属性

用于读取或者设置当前对象的prototype属性

缺点:兼容性和语义都不是很好

ES6使以下三种替换它

Object.setPrototypeOf(obj):用来设置一个对象的prototype属性,返回参数对象本身

参数:第一个参数若不是对象,则会自动转化为对象(undefined和null时会报错)

Object.getPrototypeOf():用于读取一个对象的prototype属性

参数:参数若不是对象,则会自动转化为对象(undefined和null时会报错)

Object.reate():生成对象

(四)对象的解构赋值和扩展运算符混用

对象的解构赋值会将所有的键值对都复制到新的对象上面

解构赋值必须是最后一个参数,否则会报错

解构赋值不会复制继承自原型对象的属性

扩展运算符可用于合并两个对象

若自定义的属性放在扩展运算符后面,则扩展运算符内部有同名属性会被覆盖

若把自定义属性放在扩展运算符前面,则变成了设置新对象的默认属性

若扩展运算符的参数是undefined或者null,则这两个值会被忽略,不会报错

若扩展运算符的参数对象之中有取值函数get,则这个函数会被执行

(四)Object.getOwnPropertyDescriptors(obj)

Object.getOwnPropertyDescriptor(obj):用于返回某个对象属性的描述对象

Object.getOwnPropertyDescriptors(obj):返回指定对象所有自身属性(非继承属性)的描述对象

主要是为了解决Object.assign()无法正确复制get属性和set属性

(五)Null传导运算符

四中用法

obj?.prop :读取对象属性

obj?.[expr]:读取对象属性

func.{…args}:函数或对象方法的调用

new C ?.{…args}:构造函数的调用

八、Symbol

新的数据类型,表示独一无二的值

通过symbol函数生成

let s=Symbol();


对象属性名的两种表示方法:1、原有字符串表示。2、Symbol表示

Symbol可接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了在控制台输出,或者是转为字符串时比较容易区分

如果Symbol的参数是一个对象,则会调用toString方法将其转换成为字符串,然后生成一个Symbol值

Symbol值不能与其他类型的值进行运算,否则会报错

Symbol值可以显式的转为字符串

let sym=Symbol('My Symbol');

String(sym); //'Symbol(My Symbol)'

sym.toString(); //'Symbol(My Symbol)'


Symbol值也可以转换成为布尔值,但是不能转换为数值

let sym=Symbol();

Boolean(sym); //true

!sym; //false

Number(sym); //TypeError


Symbol值作为对象的属性名时不能使用点运算符,只能用方括号

在对象内部使用Symbol值定义属性时,也只能用方括号

let sym=Symbol();

let a={};

a.sym='Hello';

a[sym]; //undefined

s['sym']; //'Hello'


Symbol类型的值还可以定义一组常量,保证这些常量都是不相等的

(一)属性名遍历

Object.getOwnPropertySymbols():返回一个数组,成员是当前对象的所有作用属性名的Symbol值

Reflect.ownKeys():以数组的形式返回所有键名,包括常规键名和S也Symbol键名

以Symbol值作为属性名的属性不会被常规方法遍历得到(可为对象定义一些非私有但又希望只用于内部的方法)

Symbol.for():可重新使用同一个Symbol值

参数:一个字符串

作用:搜索有没有以该参数作为名称的Symbol值,若有则返回这个Symbol值,否则就新建并返回一个以该字符串为名称的Symbol值

Symbol.for()与Symbol都可以生成新的Symbol

区别:前者会被登记在全局环境中供搜索,后者不会

Singleton模式:调用一个类,并且在任何时候都返回同一个实例

(二)内置的Symbol值

对象的Symbol.hasInstance属性指向一个内部方法,对象使用instanceof运算符是会调用这个方法,判断该对象是否为某个构造函数的实例

class Myclass{

    [Symbol.hanInstance](foo){

        return foo instanceof Array;

    }

}

[1,2,3] instanceof new Myclass; //true


对象的Symbo.isConcatSpreadable属性等于一个布尔值,表示该对象在使用Array.prototype.concat()时是否可以展开

let arr1=['c','d'];

['a','b'].concat(arr1,'e'); //['a','b','c','d','e']

arr1[Symvol.isConcatSpreadable] //undefined

let arr2=['c','d'];

arr2[Symbol.isConcatSpreadable]=false;

['a','b'].concat(arr2,'e'); //['a','b',['c','d'],'e']


数组的默认行为是可以展开的,Symbol.isConcatSpreadable属性等于undefined或者true,都可以

类似于数组的对象也可以展开,但它的Symbol.isConcatSpreadable属性默认为false,必须手动打开、

let obj={length:2,0:'c',1:'d'};

['a','b'].concat(obj,'e'); //['a','b',obj,'e']

obj[Symbol,isConcatSpreadable]=true;

['a','b'].concat(obj,'e'); //['a','b','c','d','e']


对于一个类而言,Symbol.isConcatSpreadable属性必须写成实例的属性

(1)Symbol.species

对象的Symbol.species属性指向当前对象的构造函数,使用这个函数返回的函数来创造新的实例对象

定义Symbol.species属性要用get读取数据

class Array extends Array{

    //覆盖父类Array的构造函数

    static get [Symbol.species](){return Array;}


(2)Symbol.match

对象的Symbol.match属性指向一个函数,当执行str.match(obj)时,如果该属性存在,则会调用它的返回值

(3)Symbol.replace

对象的Symbol.replace属性指向一个方法,当对象被String.prototype.replace方法调用时会返回改方法的返回值

(4)Symbol.split

对象的Symbol.split属性指向一个方法,当对象被String.prototype.split方法调用时会返回改方法的返回值

(5)Symbol.iterator

对象的Symbol.iterator属性指向该对象默认的遍历方法

(6)Symbol.toPrimitive

对象的Symbol.toPrimitive属性指向一个方法,对象在转化为原始数据类型时会调用这个方法,返回该对象的原始数据类型

参数:字符串,表示当前运算模式

Number:需要转化为数值

String:需要转化为字符串

Default:可转化为数组,也可转化为字符串

(7)Symbol.toStringTag

对象的Symbol.toStringTag属性指向一个方法,在对象上调用Object.prototype.toString()时,如果这个属性存在,其返回值会出现在toString方法返回值的字符串中,表示对象的类型

(8)Symbol.unscopables

对象的Symbol.unscopables属性指向一个对象,指定了使用with关键字时,那些属性会被with环境排除

九、Set和Map

(一)Set

类似于数组,其成员唯一,不重复

Set本身是一个构造函数,用于生产Set数据结构

let s=new Set();


Set函数可以接受一个数组,作为参数,用于初始化

向Set加入值时不会发生数据转换,即1和’1’为不同的值

在Set内部,两个NaN相等

(1)Set实例的属性

Set.prototype.Constructor():构造函数,就是Set()

Set.prototype.size():返回Set实例成员总数

add(value):添加值,返回Set本身

delete(value):删除值,返回一个布尔值,表删除是否成功

has(value):返回布尔值,表参数是否为Set成员

clear():清除所有成员,无返回值

(2)遍历

keys():返回键名的遍历器

values():返回键值的遍历器

entries():返回键值对的遍历器

forEach(function(){}):使用回调函数遍历每个成员,无返回值(可加参2,表示绑定的this对象)

Set的遍历顺序就是插入顺序

若想同步的改变原来的Set结构,可利用原Set映射出一个新的结构再复制给原Set结构,或者使用Array.from()

(二)WeaKSet

与Set类似,表不重复的集合

与Set的区别

WeakSet的成员只能是对象,不能是其他值

WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用

WeakSet的成员不能引用,因为其随时可能消失

WeakSet本生是一个构造函数,使用生成WeakSet数据结构

let w = new WeakSet();


可接受一个数组或者类似于数组的对象作为参数来初始化

WeakSet的方法

WeakSet.prototype.add(value ):添加新成员

WeakSet.prototype.delete(value):删除指定成员

WeakSet.prototype.has(value):返回布尔值,表指定值是否在WeakSet实例中

WeakSet无size属性,无法遍历其成员

(三)Map

类似于对象,也是键值组合

其键的范围不限于字符串,可为各种数据类型的值(包括对象)均可当做键

使用Map()构造函数生成

let m = new Map();


Map可接受一个数组作为参数,其数组成员为一个个表示键值对的数组

若一个键多次赋值,则后面的覆盖前面的值

若读取一个未知的键,则返回undefined

Map的键实际上绑定的是地址值,只要地址不同,即视为两个键(解决了同名属性碰撞的问题)

(1)Map实例的属性方法

1、size()

返回Map结构的成员总数

2、set(key,value)

设置key值所对应的键,然后返回Map结构

若key已经有值,则赋值更新,否则新生成该键值

3、get(key)

获取key对应的值,若找不到key则返回undefined

4、has(key)

返回一个布尔值,表示ley是否在Map结构中

5、delete(key)

删除某个键,删除成功则返回true,反之返回false

6、clear()

清除所有成员,无返回值

(2)遍历

keys():返回键名的遍历器

values():返回键值的遍历器

entries():返回键值对的遍历器

forEach(function(){}):遍历Map所有成员

Map的遍历顺序就是插入顺序

(四)Map与其他数据类型的转化

(1)Map转数组

Map转化为数组最快的方法时结合使用扩展运算符( . . . )

(2)数组转Map

将数组传入构造函数即可

(3)Map转对象

若Map所有键都是字符串,则可以转为对象

function strMapToObj(strMap){

    let obj = Object.create(null);

    for (let [k,v] of strMap){

        obj[k]=v;

    }

    return obj;

}


(4)对象转Map

function objToStrMap(obj){

    let strMap=new Map();

    for(let k of Object.keys(obj)){

        strMap.set(k.obj[k]);

    }

    return strMap;

}


(5)Map转JSON

情况一:Map键名都是字符串,可以转为对象JSON

function StrMapToJson(StrMap){

    reutrn JSON.stringify(strMapToObj(strMap));

}


情况二:Map键名中含有非字符串,转为数组JSON

function mapToArrayJson(map){

    return JSON.stringify(...map);

}


(6)JSON转Map

正常情况所有键名都是字符串

function jsonToStrMap(jsonStr){

    return objToStrMap(JSON.parse(jsonStr));

}


特殊情况:在整个JSON就是一个数组,且数组成员本身又是由一两个成员的数组,此时应该一一对应的转为Map(数组转为JSON的逆操作)

function jsonToMap(jsonStr){

    return new Map(JSON.parse(jsonStr));

}


(五)WeakMap

与Map结构类似,也用于生成键值对的集合

通过WeakMap函数生成

let wMap = new weakMap();


可使用set方法添加成员

可接受一个数组,作为构造函数的参数

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

推荐阅读更多精彩内容