筆記三:ECMAScript新特性

文章內(nèi)容輸出來源:拉勾教育大前端高薪訓練營 和自我總結

ECMAScript 2015

1.ES2015共有三種作用域

作用域-某個成員能夠起作用的范圍

  • 全局作用域
  • 函數(shù)作用域
  • 塊級作用域(ES2015新增)

2.變量聲明:let企软、const

  • let和const都是塊級作用域驼壶,let是定義聲明變量的避咆,而const是定義聲明常量的
  • for點擊事件
var element = [{}, {}, {}]
for(var i = 0; i < element.length; i++) {
  element[i].onclick = function () {
    // i是全局變量稽犁,已經(jīng)變成了3
    console.log(i)
  }
}
element[1].onclick() // 3

var element = [{}, {}, {}]
for(var i = 0; i < element.length; i++) {
  element[i].onclick = (function (i) {
  // 閉包實現(xiàn)
    return function () {
      console.log(i)
    }
  })(i)
}
element[1].onclick() // 2

var element = [{}, {}, {}]
for(let i = 0; i < element.length; i++) {
  // let定義的變量是塊級作用域
  element[i].onclick = function () {
    console.log(i)
  }
}
element[1].onclick() // 2
  • for生成兩層塊級作用域
for(let i = 0; i < 3; i ++) {
  let i = 'foo'
  console.log(i)
}

let i = 0

if (i < 3) {
  let i = 'foo'
  console.log(i)
}

i++

if (i < 3) {
  let i = 'foo'
  console.log(i)
}

i++

if (i < 3) {
  let i = 'foo'
  console.log(i)
}

i++
  • let和const不會變量提升
console.log(foo) // undefined
var foo = 'jal'

console.log(foo1) // ReferenceError
let foo1 = 'jal'
  • 編碼建議:不用var,主用const丘薛,搭配let

3.數(shù)組的解構

方括號[]中的便變量按順序匹配數(shù)組元素

const arr = [1, 2, 3]
const a = arr[0]
const b = arr[1]
const c = arr[2]
console.log(a, b ,c) // 1 2 3

const [a, b, c] = arr
console.log(a, b ,c) // 1 2 3

const [, , c] = arr
console.log(c) // c

const [a, ...c] = arr // 三個點解構只能用于最后一個位置
console.log(c) // [ 2, 3 ]

const [a] = arr
console.log(a) // 1

const [a, b, c, d] = arr
console.log(d) // undefined

const [a, b, c = 123, d = 'defaultValue'] = arr
console.log(c, d) // 3 defaultValue

const path = 'a/b'
const [, b] = path.split('/')
console.log(b) // b

4.對象的解構

const obj = {name: 'yibo', age: 22}
const {name} = obj
console.log(name) // yibo

const name = 'jal'
const {name} = obj
console.log(name) // SyntaxError: Identifier 'name' has already been declared

const name = 'jal'
const {name: objName, sex = 'boy'} = obj
console.log(objName, sex) // yibo boy

5.模板字符串

反引號中間的${}為JS變量JS表達式

const name = 'jack'
const str = `this is ${name}`
console.log(str)  //this is jack

6.模板字符串標簽函數(shù)

const str = console.log`hello world` // [ 'hello world' ]

const name = 'tom'
const gender = true
function myTagFunc (str, name, gender) {
  console.log(str, name, gender)  // [ 'hey, ', ' is a ', '.' ] tom true
  return str[0] + name + str[1] + gender + str[2]
}

const result = myTagFunc`hey, ${name} is a ${gender}.`
console.log(result) // hey, tom is a true.

7.字符串方法

  • .includes()
  • .startsWith()
  • .endsWith()
const message = 'Error: foo is not undefined.'

console.log(
  message.startsWith('Error'),  //true
  message.endsWith('undefined.'), //true
  message.includes('foo') //true
)

8.函數(shù)默認值

// 帶有默認值的參數(shù)要放在最后
function foo(enable = true) {
  console.log(enable)
}
foo(true) //true
foo(false) //false
foo() // true

9.剩余參數(shù)

剩余參數(shù)只能出現(xiàn)在形參的最后一位腻暮,而且只能使用一次

// function foo(){
//   console.log(arguments)
// }
// foo(1, 2, 3) // [Arguments] { '0': 1, '1': 2, '2': 3 }


// ...args只能出現(xiàn)在形參的最后一位讥珍,而且只能使用一次
function foo(...args) {
  console.log(args)
}
foo(1, 2, 3) // [ 1, 2, 3 ]

10.展開數(shù)組

const arr = ['foo', 'bar', 'baz']

console.log.apply(console, arr) // foo bar baz
console.log(...arr) // foo bar baz

11.箭頭函數(shù)

const inc = n => n + 1
console.log(inc(1)) // 2

const sum = (a, b) => {
  return a + b
}
console.log(sum(1, 2)) // 3
  • 箭頭函數(shù)不會改變this的指向抖苦,this為上層作用域的this
const person = {
  name: 'tom',
  sayHi: function () {
    // this 是 person
    console.log(`hi, my name is ${this.name}`)
  },
  sayHiAync: function () {
    setTimeout(function () {
      //node.js: this 是 {}
      console.log(` sayHiAync: hi, my name is ${this.name}`)
    }, 1000);
  }
}
person.sayHi() // hi, my name is tom
person.sayHiAync() // sayHiAync: hi, my name is undefined
const person = {
  name: 'tom',
  sayHi:  () => {
    // node.js: this是{}
    console.log(`hi, my name is ${this.name}`)
  },
  sayHiAync: function () {
    setTimeout(() => {
      // this是person
      console.log(` sayHiAync: hi, my name is ${this.name}`)
    }, 1000);
  }
}
person.sayHi() // hi, my name is undefined
person.sayHiAync() // sayHiAync: hi, my name is tom

12.對象字面量增強

  • 屬性名和屬性值相同時可以省略哮奇,只寫屬性名
  • 對象方法可以直接寫函數(shù)形式:method(){}
  • 使用方括號[]的方式計算動態(tài)屬性名
const bar = 111
const obj = {
  foo: 123,
  // bar: bar,
  bar, // 同上一行效果
  // method1: function () {
  //   console.log(`method1: ${this}`)
  // },
  method2 () {
    // 直接寫一個方法,同上面的冒號屬性
    console.log(`method2: ${this}`)
  },
  [Math.random()]: 123, // 計算屬性名

}
console.log(obj) // { foo: 123, bar: 111, method2: [Function: method2], '0.13076137144987743': 123 }

13.對象擴展方法

  • Object.assign(target,source):將對各元對象中的屬性復制到一個目標對象中
// Object.assign 用第二個參數(shù)的對象屬性覆蓋第一個參數(shù)的對象睛约。返回結果為第一個對象
const source1 = {
  a: 123,
  b: 456
}
const source2 = {
  a: 333,
  c: 33
}
const target = {
  a: 11,
  b: 22
}

const result = Object.assign(target, source1, source2)
console.log(result) // { a: 333, b: 456, c: 33 }
console.log(result === target) // true
function fun(obj) {
  // obj.name = 'function.obj'
  // console.log(obj)
  const funObj = Object.assign({}, obj)
  funObj.name = 'function.obj'
  console.log(funObj)
}

const obj = {
  name: 'global obj'
}

fun(obj)
console.log(obj)
  • Object.is和===的比較,+0不等于-0哲身,NAN等于NAN
// Object.is 
console.log(
  0 === false, // false
  0 == false, // true
  +0 ===-0, // true
  NaN === NaN, // false
  Object.is(+0, -0), // false
  Object.is(NaN, NaN) // true
)

14.代理對象:Proxy

ES5中有一個Object.defineProperty,Vue2就是通過這個實現(xiàn)數(shù)數(shù)據(jù)雙向綁定
ES6中提供了Proxy辩涝,可以監(jiān)視對象的讀寫過程,Vue3.0通過Proxy實現(xiàn)數(shù)據(jù)綁定

// Proxy 
const person = {
  name: 'jal',
  age: 20
}

const personProxy = new Proxy(person, {
  // 參數(shù)為目標對象勘天、屬性名
  get (target, property) {
    return property in target ? target[property]: 'default'
    // console.log(target, property) // { name: 'jal', age: 20 } name
    // return 100
  },
  // 參數(shù)為目標對象怔揩、屬性名、屬性值
  set (target, property, value) {
    if(property === 'age') {
      if(!Number.isInteger(value)) {
        throw new TypeError(`${value} is not an int`)
      }
    }
    console.log(target, property, value) // { name: 'jal', age: 20 } gender true
  }
})

personProxy.gender = true
// personProxy.age = '11' // TypeError: 11 is not an int

personProxy.age = 11

// console.log(personProxy.name) // 100
console.log(personProxy.name) // jal
console.log(personProxy.xxx) // default

Proxy對比Object.definePrperty

  • Object.defineProperty只能監(jiān)聽屬性的讀寫
  • Proxy能監(jiān)視更多對象操作:delete
const person = {
  name: 'jal',
  age: 20
}
const personProxy = new Proxy(person, {
  deleteProperty(target, property) {
    console.log('delete', property) // delete age
    delete target[property]
  }
})
delete personProxy.age
  • Proxy更好的支持數(shù)組對象的監(jiān)視(Vue重寫數(shù)組的操作方法脯丝,劫持方法調(diào)用過程)
const list = []
const listProxy = new Proxy(list, {
  set(target, property, value) {
    console.log('set', property, value)
    target[property] = value
    return true // 表示設置成功
  }
})
listProxy.push(100)
// set 0 100
// set length 1

15.Reflect統(tǒng)一的對象操作API

Reflect屬于靜態(tài)類(如Math)商膊,不能通過new來實例化對象,只能調(diào)用類的靜態(tài)方法宠进,如Reflect.get().Reflect內(nèi)部封裝了一系列對對象的底層操作晕拆。Reflect成員方法就是Proxy處理對象的默認實現(xiàn)

const proxy = new Proxy(obj, {
  get(target, property) {
    // 不寫get邏輯,相當于調(diào)用Reflect.get(target, property)材蹬。
    return Reflect.get(target, property)
  }
})

Reflect統(tǒng)一提供一套用于操作對象的API

const obj = {
  foo: '111',
  bar: 'rrr',
  age: 18
}
// console.log("age" in obj)
// console.log(delete obj['bar'])
// console.log(Object.keys(obj))

console.log(Reflect.has(obj, 'name')) // false
console.log(Reflect.deleteProperty(obj, 'bar')) // true
console.log(Reflect.ownKeys(obj)) // [ 'foo', 'age' ]

16.Promise

一種更優(yōu)的異步編程解決方案实幕。解決了傳統(tǒng)異步編程中回調(diào)函數(shù)嵌套過深的問題

17.類 關鍵詞 Class

// function Person(name) {
//   this.name = name
// }
// Person.prototype.say = function() {
//   console.log(`hi, my name is ${this.name}`)
// }
// const p = new Person('jal')
// p.say() // hi, my name is jal

class Person {
  constructor(name) {
    this.name = name
  }
  say () {
  console.log(`hi, my name is ${this.name}`)
  }
}
const p = new Person('jal')
p.say() // hi, my name is jal
  • 靜態(tài)方法吝镣,this指向當前類型,而不是實例
class Person {
  constructor(name) {
    this.name = name
  }
  say () {
  console.log(`hi, my name is ${this.name}`)
  }
  static create(name) {
    // this 指向當前類型昆庇,而不是實例
    console.log(this) // [Function: Person]
    return new Person(name)
  }
}

const tom = Person.create('tom')
tom.say() // hi, my name is tom
  • 繼承末贾,關鍵詞 extends
class Student extends Person {
  constructor(name, number){
    super(name)
    this.number = number
  }

  hello () {
    super.say()
    console.log(`my school number is ${this.number}`)
  }
}

const s = new Student('jack', 100)
s.hello()
// hi, my name is jack
// my school number is 100

18.數(shù)據(jù)解構Set

// Set 數(shù)據(jù)結構
const s = new Set()
s.add(1).add(2).add(3).add(4).add(2)
console.log(s) // Set(4) { 1, 2, 3, 4 }

s.forEach(i => console.log(i)) // 1 2 3 4

for(let i of s) {
  console.log(i)
}
// 1 2 3 4

console.log(s.size) // 4

console.log(s.delete(3)) // true
console.log(s) // Set(3) { 1, 2, 4 }

const arr = [1, 2, 1, 3, 4 ,1]
const result = new Set(arr)
console.log(result) // Set(4) { 1, 2, 3, 4 }
const arr2 = Array.from(result)
console.log(arr2) // [ 1, 2, 3, 4 ]
const arr3 = [...result]
console.log(arr3) // [ 1, 2, 3, 4 ]

19.數(shù)據(jù)解構Map

Map映射任意類型之間的關系,Map可以用任意對象作為鍵整吆,而對象只能用字符串作為鍵

// Map 映射任意類型之間的關系. Map可以用任意對象作為鍵拱撵,而對象只能用字符串作為鍵
const obj = {}
obj[true] = 'value'
obj[1] = '11'
obj[{a: 1}] = '33'
console.log(Object.keys(obj)) // [ '1', 'true', '[object Object]' ]

const m = new Map()
const tom = {name: 'tom'}
m.set(tom, 90)
console.log(m) // Map(1) { { name: 'tom' } => 90 }
console.log(m.get(tom)) // 90

20.原始數(shù)據(jù)類型Symbol

最主要的作用就是為對象添加獨一無二的屬性名

const s = Symbol()
console.log(s) // Symbol()
console.log(typeof s) // symbol

console.log(Symbol() === Symbol()) // false

console.log(Symbol('foo')) // Symbol(foo)
console.log(Symbol('bar')) // Symbol(bar)
console.log(Symbol('baz')) // Symbol(baz)

const obj = {}
obj[Symbol()] = 111
obj[Symbol()] = 2
console.log(obj) // { [Symbol()]: 111, [Symbol()]: 2 }


const name = Symbol()
const person = {
  [name]: 'jal', // 作為私有成員防止被訪問
  say(){
    console.log(this[name])
  }
}
person.say()// jal
console.log(person[Symbol()]) // undefined
// console.log(person[name]) // jal

截止到ES2019一共定義了6種原始類型,和一個object類型表蝙,未來還會增加一個bigint的原始類型(stage-4階段)標準化過后就是8中數(shù)據(jù)類型
boolean(布爾)拴测、symbol、number()勇哗、string(字符串)昼扛、undefined(未定義)、null(空)欲诺、object(對象)抄谐、bigint

const s1 = Symbol.for('foo')
const s2 = Symbol.for('foo')
console.log(
  s1 === s2, // true
// Symbol.for的參數(shù)會被轉化為字符串
Symbol.for(true) === Symbol.for('true'), // true
)
const obj2 = {
  // 為對象實現(xiàn)迭代器時會用到
  [Symbol.toStringTag]: 'XObject'
}
console.log(obj2.toString()) // [object Object] [object XObject]

const obj3 = {
  [Symbol()]: 'symbol value',
  foo: 'normal value'
}
for(var key in obj3) {
  console.log(key)
}
// foo

console.log(Object.keys(obj3)) // [ 'foo' ]
console.log(JSON.stringify(obj3)) // {"foo":"normal value"}

console.log(Object.getOwnPropertySymbols(obj3)) // [ Symbol() ]

21.for...of作為遍歷所有數(shù)據(jù)解構的統(tǒng)一方式

// for ... of 循環(huán), 可以使用break
const arr = [1, 2, 3, 4]
for (const item of arr) { // item為每個對象實例
  console.log(item)
}
// 相當于
// arr.forEach(item => {
//   console.log(item)
// })

可以使用break終止循環(huán)

// arr.forEach ,但是這個方法不能終止遍歷
// 為了終止遍歷,我們之前扰法,我們曾使用
// arr.some() 返回true
// arr.every() 返回false

for(const item of arr) {
  console.log(item) 
  if(item > 1)break
}

遍歷集合Set

const s = new Set(['foo', 'bar'])
for(const item of s) {
  console.log(item)
}
// foo bar

遍歷集合Map

const m = new Map()
m.set('foo', '123')
m.set('bar', '34')

for(const item of m) {
  console.log(item)
}
// [ 'foo', '123' ]  [ 'bar', '34' ]

// 解構鍵和值
for(const [key, value] of m) {
  console.log(key,value)
}
// foo 123
// bar 34

遍歷對象蛹含,報錯:TypeError:obj is not iterable

const obj = {name: 'jal', age: 22}

for(const item of obj) {
  console.log(item) // TypeError: obj is not iterable
}

ES中能夠表示有結構的數(shù)據(jù)類型越來越多

22.Iterable接口(可迭代接口)

實現(xiàn)Iterable解構就是for...of的前提

  • 實現(xiàn)可迭代接口
// 迭代器 iterator 
const set = new Set(['foo', 'bar', 'baz'])

const iterator = set[Symbol.iterator]()

// 這就是for... of 循環(huán)實現(xiàn)的工作原理
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
// { value: 'foo', done: false }
// { value: 'bar', done: false }
// { value: 'baz', done: false }
// { value: undefined, done: true }
  • 實現(xiàn)迭代器原理
// obj 實現(xiàn)可迭代接口 Iterable
const obj = {
  // iterator 方法
  [Symbol.iterator]: function () {
    // 迭代器接口 iterator 
    return {
      // 必須要有next方法
      next: function () {
        // 迭代結果接口 IterationResult
        return {
          value: 1,
          done: true
        }
      }
    }
  }
}
  • 具體實現(xiàn)
const obj = {
  store: ['foo', 'bar', 'baz'],

  [Symbol.iterator]: function () {
    let index = 0
    const self = this

    return {
      next: function () {
        const result = {
          value: self.store[index],
          done: index >= self.store.length
        }
        index++
        return result
      }
    }
  }
}

for( const item of obj) {
  console.log(item)
}
// foo
// bar
// baz

上面就是涉及模式中的迭代器模式、
小案例:

const todos = {
  life: ['吃飯', '睡覺', '打豆豆'],
  learn: ['語文', '數(shù)學', '英語'],
  work: ['喝茶'],
  each: function (callback) {
    const all = [].concat(this.life, this.learn, this.work)
    for (const item of all) {
      callback (item)
    }
  },
  // 實現(xiàn)迭代器接口
  [Symbol.iterator]: function () {
    const all = [...this.life, ...this.learn, ...this.work]
    let index = 0
    return {
      next: function () {
        return {
          value: all[index],
          done: index++ >= all.length
        }
      }
    }
  }
}

todos.each(function (item) {
  console.log(item)
})
console.log('---------')
for(const item of todos) {
  console.log(item)
}
// 吃飯
// 睡覺
// 打豆豆
// 語文
// 數(shù)學
// 英語
// 喝茶
// ---------
// 吃飯
// 睡覺
// 打豆豆
// 語文
// 數(shù)學
// 英語
// 喝茶

22.生成器函數(shù)generator

避免異步編程中回調(diào)函數(shù)嵌套過深塞颁,提供更好的異步編程解決方案

function * foo () {
  console.log('zce')
  return 100
}
// 這個foo就是一個Generator函數(shù)

const result = foo()
console.log(result)// Object [Generator] {}
console.log(result.next())
// zce
// { value: 100, done: true }
// 可以看出生成器對象實現(xiàn)了Iterator接口

配合yield關鍵詞使用

生成器函數(shù)會返回一個生成器對象浦箱,調(diào)用這個生成器對象的next方法,才會讓函數(shù)體執(zhí)行祠锣,一旦遇到了yield關鍵詞酷窥,函數(shù)的執(zhí)行則會暫停下來,next函數(shù)的參數(shù)作為yield結果返回伴网,如果繼續(xù)調(diào)用函數(shù)的next函數(shù)蓬推,則會再上一次暫停的位置繼續(xù)執(zhí)行,直到函數(shù)體執(zhí)行完畢澡腾,next返回的對象done就變成true

function * fn () {
  console.log(111)
  yield 100
  console.log(222)
  yield 200
  console.log(333)
  yield  300
}

const generator = fn()

console.log(generator.next())
// 111
// { value: 100, done: false }
console.log(generator.next())
// 222
// { value: 200, done: false }
console.log(generator.next())
// 333
// { value: 300, done: false }

案例1:發(fā)號器

// Generator 應用: 發(fā)號器

function * createIdMaker () {
  let id = 1
  while(true) {
    yield id++
  }
}
const idMaker = createIdMaker()

console.log(idMaker.next())
console.log(idMaker.next())
console.log(idMaker.next())
console.log(idMaker.next())
console.log(idMaker.next())
// { value: 1, done: false }
// { value: 2, done: false }
// { value: 3, done: false }
// { value: 4, done: false }
// { value: 5, done: false }

案例2:

Generator函數(shù)實現(xiàn)迭代器Iterator
const todos = {
  life: ['吃飯', '睡覺', '打豆豆'],
  learn: ['語文', '數(shù)學', '英語'],
  work: ['喝茶'],

  // 實現(xiàn)迭代器接口
  [Symbol.iterator]: function * () {
    const all = [...this.life, ...this.learn, ...this.work]
    for (const item of all) {
      yield item
    }
  }
}

for(const item of todos) {
  console.log(item)
}
// 吃飯
// 睡覺
// 打豆豆
// 語文
// 數(shù)學
// 英語
// 喝茶

23.ES Modules

語言層面的模塊化標準

二沸伏、ESMAScript 2016

1.數(shù)組的includes方法

const arr = ['foo', 1, false, NaN]
// 以前使用indexOf, 存在則返回下標,不存在則返回-1动分, 缺點是無法判斷NaN
console.log(arr.indexOf('foo')) // 0
console.log(arr.indexOf(1)) // 1
console.log(arr.indexOf(false)) // 2
console.log(arr.indexOf(NaN)) // -1

console.log(arr.includes('foo')) // true
console.log(arr.includes(1)) // true
console.log(arr.includes(false)) // true
console.log(arr.includes(NaN)) // true

2.指數(shù)運算符**

console.log(2 ** -52) // 2.220446049250313e-16

三毅糟、ESMAScript 2017

1.Object.values(obj)

獲取對象所有值的數(shù)組

const obj = {
  name: 'jal',
  age: 20
}
// 對象的值組成的數(shù)組
console.log(Object.values(obj)) // [ 'jal', 20 ]

2.Object.eentries(obj)

獲取對象的鍵值數(shù)組

// 對象的鍵值數(shù)組, 可以for...of 這個對象了
console.log(Object.entries(obj)) // [ [ 'name', 'jal' ], [ 'age', 20 ] ]
for (const [key, value] of Object.entries(obj)) {
  console.log(key, value)
}
// name jal
// age 20

3.Object.getOwnPropertyDescriptors(obj)

獲取對象的詳細描述

const p1 = {
  firstName: 'Ji',
  lastName: 'Ailing',
  get fullName() {
    return this.firstName + ' '+ this.lastName
  }
}

const p2 = Object.assign({}, p1)
p2.firstName = 'zce'
console.log(p2) // { firstName: 'zce', lastName: 'Ailing', fullName: 'Ji Ailing' }
const descriptors = Object.getOwnPropertyDescriptors(p1)
console.log(descriptors)
/*
{
  firstName: { value: 'Ji', writable: true, enumerable: true, configurable: true },
  lastName: {
    value: 'Ailing',
    writable: true,
    enumerable: true,
    configurable: true
  },
  fullName: {
    get: [Function: get fullName],
    set: undefined,
    enumerable: true,
    configurable: true
  }
}
*/

const p3 = Object.defineProperties({}, descriptors)
p3.firstName = 'zce'
console.log(p3.fullName) // zce Ailing

4.padEnd/padStart

用指定字符串填充目標字符串的頭部或者尾部澜公,直到達到指定的長度為止

const books = {
  html: 5,
  css: 16,
  javascript: 128
}
for(const [key, value] of Object.entries(books)) {
  console.log(key, value)
}
// html 5
// css 16
// javascript 128

for(const [key, value] of Object.entries(books)) {
  console.log(`${key.padEnd(16, '-')}|${value.toString().padStart(3, '0')}`)
}
// html------------|005
// css-------------|016
// javascript------|128

5.在函數(shù)參數(shù)中添加尾逗號

function foo (
 bar, 
 baz,
) {
  
}

const arr = [
  10,
  20,
  30,
]

6.Async / Await

Promise的語法糖姆另,解決了回調(diào)地獄的問題

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蜕青,更是在濱河造成了極大的恐慌苟蹈,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件右核,死亡現(xiàn)場離奇詭異慧脱,居然都是意外死亡,警方通過查閱死者的電腦和手機贺喝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門菱鸥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人躏鱼,你說我怎么就攤上這事氮采。” “怎么了染苛?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵鹊漠,是天一觀的道長。 經(jīng)常有香客問我茶行,道長躯概,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任畔师,我火速辦了婚禮娶靡,結果婚禮上,老公的妹妹穿的比我還像新娘看锉。我一直安慰自己姿锭,他們只是感情好,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布伯铣。 她就那樣靜靜地躺著呻此,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腔寡。 梳的紋絲不亂的頭發(fā)上焚鲜,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機與錄音蹬蚁,去河邊找鬼。 笑死郑兴,一個胖子當著我的面吹牛犀斋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播情连,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼叽粹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起虫几,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤锤灿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后辆脸,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體但校,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年啡氢,在試婚紗的時候發(fā)現(xiàn)自己被綠了状囱。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡倘是,死狀恐怖亭枷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情搀崭,我是刑警寧澤叨粘,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站瘤睹,受9級特大地震影響升敲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜默蚌,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一冻晤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧绸吸,春花似錦鼻弧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至码俩,卻和暖如春度帮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背稿存。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工笨篷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瓣履。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓率翅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親袖迎。 傳聞我的和親對象是個殘疾皇子冕臭,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345