es6

3.1 const

{
    const a = {
        j: 2
    };
    a.k = 3; //a={j:2,k:3}
    a.j = 1; //j=1
}
//const声明一个常量,不可更改。但声明一个对象的话,是指向对象的指针,而对象本身,是可以更改的

3.2 解构赋值

//数组的解构赋值
{
    let a, b;
    [a, b] = [1, 2]; //a=1,b=2 
}

{
    let a, b, rest;
    [a, b, ...rest] = [1, 2, 3, 4, 5]; //a=1,b=2,rest=[3,4,5]
}

//对象的解构赋值
{
    let a, b;
    ({ a, b } = { a: 1, b: 2 }); //a=1,b=2
} 

{
    let o = { p: 42, q: true };
    let { p, q } = o; //p=42,q=true
} 

{
    let a, b;
    ({ a, b, c = 3 } = { a: 1, b: 2 }); //a=1,b=2,c=3
} 

{
    let { a = 10, b = 5 } = { a: 3 }; //a=3,b=5
}

{
    let metaData = {
        title: 'abc',
        test: [{
            title: 'test',
            desc: 'description'
        }]
    }
    let { title: esTitle, test: [{ title: cnTitle }] } = metaData;
    //esTitle='abc',cnTitle='test'
}

//变量的交换
{
    let a = 1,
        b = 2;
    [a, b] = [b, a]; //a=2,b=1
}

//获取函数返回值
{
    function f() {
        return [1, 2, 3, 4, 5];
    }
    let a, b;
    [a, b] = f(); //a=1,b=2
    let c, d;
    [c, , , d] = f(); //c=1,b=4
    let e, rest;
    [e, , ...rest] = f(); //e=1,rest=[3,4,5]
}

3.3 正则拓展

 //es5写法
 let regex=new Regexp('xyz','i');
 let regex=new Regexp(/xyz/i);             
 //es5的这种写法 只能为一个参数

  //es6写法
  let regex=new Regexp(/xyz/ig,'i')   
  后面的i会覆盖前面的ig

  //Regexp.flags    —— 获取正则对象的修饰符

  let regex=bew Regexp(/a/g)
  let regex=bew Regexp(/a/y)
  //g修饰符和y修饰符都是全局匹配 ,g修饰符从上次匹配的位置继续寻
  //找,不强调为下次匹配位置的第一个开始匹配,只能后续能找到即可,
  // y修饰符必须为下次匹配位置的第一个位置开始就可以匹配到,否则第
  //二次匹配为false

  let a=/a+/y;
  console.log(a.sticky)    //true
  //sticky   判断正则对象是否为粘连模式(含有y修饰符)   

//添加u修饰符之后,会把后面的四个字节(两个字符)当做一个字符(实际为两个字符)
  console.log('u-1',  /^\uD83D/.test('/uD83D\uDC2A'));
  console.log('u-2',  /^\uD83D/u.test('/uD83D\uDC2A')); 

  console.log(/\u{61}/.test('a'));
  console.log(/\u{61}/u.test('a'));
//如果大括号包裹的是unicode字符,需要加上u修饰符才能被识别 
// ‘.’ 只能表示为不大于2个字节的字符。
//如果字符串中有大于两个字节的字符 则需要添加u修饰符,否则无法正确识别

3.4 字符串拓展

  console.log('a','\u0061');
  console.log('a','\u20BB7');
  console.log('a','\u{20BB7}');
//当Unicode编码大于两个字节,则需要使用大括号包围,才可以正常解析

//  codePointAt   取码值(es6的方法)
let a='𠮷a';
console.log(a.length);
console.log('0',a.charAt(0));
console.log('1',a.charAt(1));
console.log('2',a.charAt(2));
console.log('at0',a.charCodeAt(0).toString(16));
console.log('at1',a.charCodeAt(1).toString(16));
console.log('at2',a.charCodeAt(2).toString(16));
console.log('code0',a.codePointAt(0).toString(16));
console.log('code1',a.codePointAt(1).toString(16));
console.log('code2',a.codePointAt(2).toString(16));

//“𠮷”大于两个字节 会按照四个字节编译。每两个字节为一个长度,也
//就是有两个长度。codePointAt在处理大于两个字节的字符时,
//codePointAt(0)会按照四个字节进行编译

console.log(String.fromCharCode('0x20bb7'));
console.log(String.fromCodePoint('0x20bb7'));
//fromCodePoint  给码值取字符 (es6方法) 可解析大于0xFFFF的字符

{
    let str = '\u{20BB7}abc';
    for (let i of str) {
        console.log(i);
    }
}
//可使用let of遍历大于两个字节的字符

  let str='string';
  console.log('includes',str.includes('r'));
       —— 判断字符串是否包含某些字符
   console.log('start',str.startsWith('st'));
       —— 判断字符串是否以某些字符开始
   console.log('end',str.endsWith('ng'));
       —— 判断字符串是否以某些字符结束
   console.log(str.repeat(2));
       —— 将字符串重复两次

//模板字符串
let a='jm';
let b='hello world';
let c=`i am ${a},${b}`;
 console.log(c); // i am jm,hello world

ES7提案
  //str.padStart(length,'value') 
   console.log('1'.padStart(2,'0')); //01
    //字符串的起始位置补白
   console.log('1'.padEnd(2,'0')); //10
    //字符串的结束位置补白

    #标签模板

 //String.raw
console.log(String.raw`Hi\n${1+2}`);  //Hi\n3
console.log(`Hi\n${1+2}`);  //Hi(换行) 3
//String.raw对所有的斜杠进行转义

3.6 数值拓展

console.log(0b111110111);
console.log(0o767);
//0B位二进制,0o为八进制,大小写皆可;

//判断一个数是否为有尽
console.log(Number.isFinite(15));    //true
console.log(Number.isFinite(NaN));    //false  
console.log(Number.isFinite(15/0));    //false

//判断一个值是否为非数字
 console.log(Number.isNaN(15));    //false
 console.log(Number.isNaN(NaN));    //true
 console.log(Number.isNaN(15/0))    //false

//判断一个数是否为整数
console.log(Number.isInteger(25));    //true
console.log(Number.isInteger(25.0));    //true
console.log(Number.isInteger(25.1));    //false
console.log(Number.isInteger(‘a’));    //false 

//一个数的有效值范围为-2的53次方到2的53次方(不包含端点本身)。ES6设置两个常量为:
console.log(Number.MAX_SAFE_INTEGER);     //2的53次方
console.log(Number.MIN_SAFE_INTEGER);    //-2的53次方

//Es6给出的API为:
console.log(Number.isSafeInteger(15));    //true
console.log(Number.isSafeInteger('a'));    //false
//判断一个数是否为有效值,即是否安全

console.log(Math.trunc(4.1));    //4
console.log(Math.trunc(4.8));    //4
//取一个数的整数部分

console.log(Math.sign(5));    //1
console.log(Math.sign(0));    //0
console.log(Math.sign(-5));    //-1
console.log(Math.sign('5'));    //1
console.log(Math.sign('aa'));    //NaN
 //判断一个数是大于0,小于0,或者等于0,如果为字符串,则会转换
 //为数字进行解析,不通过则返回NaN;

//求一个数的立方根
console.log(Math.cbrt(-1));    //-1
console.log(Math.cbrt(8));    //2

3.7 数组拓展

  //Array.of() 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。
  Array.of(7);       // [7] 
  Array.of(1, 2, 3); // [1, 2, 3] 
  Array(7);          // [ , , , , , , ]
  Array(1, 2, 3);    // [1, 2, 3]
  // Array.of() 和 Array 构造函数之间的区别在于处理整数参数:
  //Array.of(7) 创建一个具有单个元素 7 的数组,而 Array(7) 创建一个包
  //含 7 个 undefined 元素的数组

  //Array.from() 方法从一个类似数组或可迭代对象中创建一个新的数组实例。
  const bar = ["a", "b", "c"];
  Array.from(bar);
  // ["a", "b", "c"] 
  Array.from('foo');
  // ["f", "o", "o"]
  Array.from([1,2,3],function(item){return item*2})   
  //Array.from可以有两个参数,第二个参数为一个函数可以进行MAP操作。

  //替换数组内容
  cnosole.log([1,2,3].fill(7));  //[7,7,7]
  console.log([1,1,1,1,1].fill(7,1,3));  //[1,7,7,1,1]

  //获取数组的index和值
  for(let [index,value] of ['a','b','c'].entries()){
        console.log(index); //1,2,3
       }    

  //arr.copyWithin(target, start, end)
  console.log([1,2,3,4,5,6,7,8,9].copyWithin(0,2,4)); //[1, 3, 4, 4, 5, 6, 7, 8, 9] 

  //target 复制序列到该位置。如果是负数,target 将从末尾开始计算
  //start 开始复制元素的起始位置。如果是负数,start 将从末尾开始计算。
  //end 开始复制元素的结束位置。copyWithin 将会拷贝到该位置, 
  //但不包括 end 这个位置的元素。如果是负数, end 将从末尾开始计算。

  console.log([1,2,3,4,5,6].find(function(item){return item>3})) //4
  console.log([1,2,3,4,5,6].findIndex(function(item){return item>3})) //3
  //找到第一个符合条件的数组成员

  console.log([1,2,NaN].includes(NaN)) //true
  //参数不是函数,直接寻找数组里有没有这个值,可匹配NaN

3.8 函数拓展

{
    let x = 'test';

    function test2(x, y = x) {
        console.log('作用域',
            x, y)
    }
    test2('kill'); //作用域 kill kill
}

{
    let x = 'test';

    function test2(x, y = x) {
        console.log('作用域',
            x, y)
    }
    test2(); //作用域 undefined  undefined  
}

{
    let x = 'test';

    function test2(c, y = x) {
        console.log('作用域',
            x, y)
    }
    test2('kill'); // 作用域 kill   test
}

//rest参数,将离散的值转为数组,使用rest参数之后,后面不能在添加别的参数
{
    function test3(...arg) {
        console.log(arg)
        for (let v of arg) {
            console.log('rest', v)
        }
    }
    test3(1, 2, 3, 4)
} 

  //将数组转为离散的值。可添加别的参数
  console.log(...[1,2,3,4]);
  console.log('a',...[1,2,3,4])

//箭头函数     ( let + 函数名 + 参数 + 返回值 )
{
    let demo = v => v * 2;
    console.log(demo(10)); //20

    let demo1 = () => 5;
    console.log(demo1()); //5
}

3.9对象扩展

//简洁表示法
{
    let [a, b] = [1, 2];
    let es5 = {
        a: a,
        b: b
    }
    let es6 = {
        a,
        b
    }
    console.log(es5, es6)
} 

{
    let c = {
        demo: function() {
            console.log('es5的方法表示')
        }
    }
    let d = {
        demo() {
            console.log('es6的方法表示')
        }
    }
    console.log(c.demo(), d.demo())
} 

//属性表达式(中括号中为变量,里面可填表达式)
{
    let a = 'b';
    let es5 = {
        a: 'c',
        b: 'c'
    }
    let es6 = {
        [a]: 'c'
    }
    console.log(es5, es6)
}

//新增API
{
    console.log('字符串', Object.is('abc', 'abc'), 'abc' === 'abc')
    //判断两个参数是否相等,和‘===’在功能上是相同的
    console.log('数组', Object.is([], []), [] === [])
    //数组是引用类型,引用的两个不同地址,严格上是不相等的
    console.log('拷贝', Object.assign({ a: 'a' }, { b: 'b' }))
    //Object.assign(要拷贝到的对象,要拷贝的对象),浅拷贝。
    //只拷贝自身对象的属性,不拷贝继承和不可枚举的属性 

    let test = { k: 123, o: 456 };
    for (let [key, value] of Object.entries(test)) {
        console.log(key, value)
    }
    //Object.entries配合对象的使用
} 

 //扩展运算符
 let {a,b,...c}={a:'a',b:'b',c:'c',d:'d'}
//最后c应该为   c{c:'c',d:'d'}

3.10 Symbol用法

//Symblo的声明:
let a1=Symbol();
let a2=Symbol();
console.log(a1===a2);  //false

let a3=Symbol.for('a3');
let a4=Symbol.for('a3');
 console.log(a3===a4); //true
//使用Symbol声明的变量永远是独一无二的

Object.getOwnPropertySymbols(obj);
//可以拿到使用Symbol作为key值的对象的属性

Reflect.ownKeys(obj);
//可以拿到使用Symbol作为key值的对象的属性,也可以拿到非Symbol作为key值的对象的属性 

3.11 set-map数据结构

{ 
    //set的定义:
    let list = New Set();
    list.add(1);
    list.add(2);
    console.log(list.size); //2
}


{
    //不同的定义方式:
    let arr = [1, 2, 3.1, 2];
    let list = New Set(arr);
    console.log(list); //1,2,3(去重,不会做数据类型的转换)
}
 
//相当于数组,但是里面的值不能重复,add为添加元素,size相当于数组中的length,也就是长度

//set的方法:
obj.add() :添加元素
obj.delete():删除元素
obj.has():判断是否含有这个元素
obj.clear():清空Set集合中的元素

//遍历
{
    let arr = ['add', 'delete', 'clear', 'has'];
    let obj = New Set(arr);

    for (let key of obj.keys()) {
        console.log(key); //'add','delete','clear','has'
    }
    for (let value of obj.values()) {
        console.log(value); //'add','delete','clear','has'
    }
    for (let [key, value] of obj.entries()) {
        console.log(key, value)  //key和value的值都是相同的
    }

    obj.forEach(function(item) {
        console.log(item); //'add','delete','clear','has'
    }) 
}

//WeakSet的定义:
let weakset=new WeakSet();
let arg={};
weakset.add(arg);
//WeakSet里只能放对象,没有size属性,没有clear方法,不能遍历,不会和垃圾回收机制挂钩。
//在WeakSet中添加一个对象,只是地址的引用,也不会检测这个对象是否已经被垃圾回收。

//Map的定义:
let map=New Map();
let arr=['123'];
map.set(arr,456);
console.log('map',map,map.get(arr));

//第二种定义方法:
let map =New Map([['a',123],['b',456]])
//Map中是一个数组,数组里还是数组
//Map的特性是key可以是任何数据类型,Map的添加元素的方法是set(),Map的获取元素的方法为get()
//长度为size(),删除为delete(),清空为clear(),遍历和Set是一样的。

//WeakMap的定义: 
let weakmap=new WeakMap(); 
//WeakMap的key值只能是对象,没有size属性,没有clear方法,不能遍历。 

3.13 Proxy和Reflect

//Proxy
{
    let obj = {
        time: '2017-3-11',
        name: 'jm',
        _r: 123
    }

    let monitor = new Proxy(obj, {
        //拦截对象属性的读取
        get(target, key) {
            return target[key].replace('2017', '2018')
        },
        //拦截对象设置属性
        set(target, key, value) {
            if (key === 'name') {
                return target[key] = value;
            } else {
                return target[key];
            }
        },
        //拦截key in object操作
        has(target, key) {
            if (key === 'name') {
                return target[key]
            } else {
                return false
            }
        },
        //拦截delete
        deleteProperty(target, key) {
            if (key.indexOf('_') > -1) {
                delete target[key];
                return true;
            } else {
                return target[key]
            }
        },
        //拦截object,keys,Object.getOwnPropertySymbols,Object.getOwnPropertyNames
        ownKeys(target) {
            return Object.keys(target).filter(item => item != 'time')
        }
    });

    console.log('get', monitor.time); //2018-3-11
    monitor.time = '2018';
    monitor.name = 'muke';
    console.log('set', monitor.time, monitor);
    console.log('has', 'name' in monitor, 'time' in monitor); //true,false
    delete monitor.time;
    console.log('delete', monitor.time);
    console.log('ownkeys', Obiect.keys(monitor))
}

//Proxy和Reflect只是写法不同,用法是一样的,都是对原数据的代理
{
    let obj = {
        time: '2017-3-11',
        name: 'jm',
        _r: 123
    }
    console.log('reflect', Refect.get(obj, 'time')); //2017-3-11
    Refect.set(obj, 'name', 'muke');
    console.log(obj)
}

3.14 类与对象

//基本定义和生成实例
{
    class Parent {
        constructor(name = 'moren') { //构造函数
            this.name = name;
        }
    }
    let v_parent = new Parent('v');
    console.log('构造函数实例',
        v_parent)
}

  //继承
{
    class Parent {
        constructor(name = 'moren') {
            this.name = name;
        }
    }
    class Child extends Parent { //继承
    }
    console.log('继承',
        new Child())
}

  //继承传递参数
{
    class Parent {
        constructor(name = 'moren') {
            this.name = name;
        }
    }
    class Child extends Parent {
        constructor(name = 'child') {
            super(name); //如果为空会使用父类的默认值
            this.type = 'child'; //子类定义属性调用this需要放在super之后
        }
    }
    console.log(‘继承’, new Child())
}

//getter,setter
{
    class Parent {
        constructor(name = 'moren') {
            this.name = name;
        }
        get longName() { //get后面为属性,不是方法
            return 'mk' + this.name
        }
        set longName(value) {
            this.name = value;
        }
    }
    let v = new Parent();
    console.log('getter', v.longName); // mkmoren
    v.longName = 'hello';
    console.log('setter', v.longName); //mkhello
}

//静态方法
{
    class Parent {
        constructor(name = 'moren') {
            this.name = name;
        }
        static tell() { //加了static就变成了静态方法,通过类调用,而不是通过实例调用
            console.log('tell')
        }
    }
    Parent.tell(); //tell
}

//静态属性
{
    class Parent {
        constructor(name = 'moren') {
            this.name = name;
        }
        static tell() {
            console.log('tell')
        }
    }
}
  Parent.type='test';      //静态属性  通过类去读取
  console.log('静态属性',Parent.type) ;   //test

3.15 Promise

//Promise的基本定义
{
        let ajax=function(){
            console.log('执行1'); 
            return new Promise(function(resolve,reject){     
             //resolve为执行下一步操作,reject为中断当前操作
                setTimeout(function(){
                    resolve()
                },1000)
            })
        }
        ajax().then(function(){
            console.log('promise','timeout1')
        },function(){ })   //第二个function为reject
}

//Promise的多步调用
{
    let ajax = function() {
        console.log('执行1');
        return new Promise(function(resolve, resect) {
            setTimeout(function() {
                resolve()
            }, 1000)
        })
    }

    ajax().then(function() {
        console.log('setTimeout2')
        return new Promise(function(resolve, resect) {
            setTimeout(function() {
                resolve()
            }, 1000)
        })
    }).then(function() {
        console.log('setTimeout3')
    })
}

// catch 错误捕获
{
    let ajax=function(num){
        console.log('执行1');
        return new Promise(function(resole,resect){
            if(num>5){
                resole()
            }else{
                throw new Error('出错了')
            }
        })
    }
    ajax(6).then(function(){
        console.log('6',6)
    }).catch(function(err){
        console.log('catch',err)
    }) 
    ajax(3).then(function(){
        console.log('3',3)
    }).catch(function(err){
        console.log('catch',err)
    }) 
}

//所有图片加载完再添加到页面  Promise.all
{
    function loadImg(src){
        return new Promise((resolve,resect)=>{
            let img =document.createElement('img');
            img.src=src;
            img.onload=function(){
                resolve(img)
            }
            img.onerror=function(err){
                resect(err)
            }
        })
    }
    function showImgs(imgs){
        imgs.forEach(function(img){
            document.body.appendChild(img)
        })
    }
    Promise.all([
        loadImg('http://i4.buimg.com/567571/df1ef0720bea6832.png'),
        loadImg('http://i4.buimg.com/567571/df1ef0720bea6832.png'),
        loadImg('http://i4.buimg.com/567571/df1ef0720bea6832.png')
        ]).then(showImgs)
}
//Promise.rece   当有一张图片加载完成就添加到页面,其他的不再响应,用法和Promise.all相同

3.16 Iterator

//自定义部署interator方法  (使obj可遍历)
{
    let obj = {
        start: [1, 2, 3],
        end: [4, 5, 6],
        [Symbol.iterator]() {
            let self = this;
            let index = 0;
            let arr = self.start.concat(self.end);
            let len = arr.length;
            return {
                next() {
                    if (index < len) {
                        return {
                            value: arr[index++],
                            done: false
                        }
                    } else {
                        return {
                            value: arr[index++],
                            done: true
                        }
                    }
                }
            }
        }

    }
    for (let key of obj) {     //obj原本是不能使用for...of遍历
        console.log(key)
    }
}

3.17 Generator

//基本定义
{
    let demo = function*() {
        yield 'a';
        yield 'b';
        return 'c'
    }
    let k = demo();
    console.log(k.next())
    console.log(k.next())
    console.log(k.next()) 
}

//使用Generator让obj具有iterator接口,让obj可遍历
{
    let obj = {};
    obj[Symbol.iterator] = function*() {
        yield 1;
        yield 2;
        yield 3;
    }
    for (let value of obj) {
        console.log('value', value)
    } 
}

//状态机
{
    let state=function*(){
        while(1){
            yield 'A';
            yield 'B';
            yield 'C';
        }
    }
    let status=state();
    console.log(status.next())
    console.log(status.next())
    console.log(status.next())
    console.log(status.next())
    console.log(status.next())
    console.log(status.next()) 
}

//async语法   用法和Generator一样,是Generator的语法糖
{
    let state=async function(){
        while(1){
            await 'A';
            await 'B';
            await 'C';
        }
    }
    let status=state();
    console.log(status.next())
    console.log(status.next())
    console.log(status.next()) 
}

//抽奖小实例
{
    let draw = function(count) {
        //具体抽奖逻辑
        console.log(`剩余${count}次`)
    }
    let residue = function*(count) {
        while (count > 0) {
            count--;
            yield draw(count);
        }
    }
    let star = residue(5);
    let btn = document.createElement('button');
    btn.id = 'start';
    btn.textContent = '抽奖';
    document.body.appendChild(btn);
    document.getElementById('start').addEventListener('click', function() {
        star.next()
    }, false)
}

//长轮询
{
        let ajax=function* (){
            yield new Promise(function(resolve,reject){
                setTimeout(function(){
                    resolve({code:1})
                },200)
            })
        }
        let pull=function(){
            let generator=ajax();
            let step=generator.next(); 
            step.value.then(function(d){
                if(d.code!=0){
                    setTimeout(function(){
                        console.info('wait');
                        pull()
                    },1000)
                }else{
                    console.info(d)
                }
            })
        }
        pull()
} 

3.18 Decorators修饰器

//基本定义与功能
{
    //修饰器函数
    let readOnly = function(target, name, descriptor) { 
    //(类本身,修改的属性名称,该属性的描述对象)
        descriptor.writable = false;
        return descriptor
    }
    // @readOnly  写在类前面也行
    class Test {
        @readOnly
        time() {
            return '2018-04-12';
        }
    }
    let test = new Test();
    console.log(test.time())
    //第三方修饰器库: core-decorators   
}

//日志系统
{
    let log = (type) => {
        return function(target, name, descriptor) {
            let src_method = descriptor.value;
            descriptor.value = (...arg) => {
                src_method.apply(target, arg);
                console.info(`log ${type}`)
            }
        }
    }
    class AD {
        @log('show')
        show() {
            console.log('ad is show')
        }
        @log('click')
        click() {
            console.log('ad is click')
        }
    }
    let ad = new AD();
    ad.show();
    ad.click()
}

3-19 Module模块化

//export导出
{
    export let A = 123;
    export function test() {
        console.log('test')
    }
    export class Hello{
        test() {
            console.log('class')
        }
    }
} 
//import导入
{
    import {A,test,Hello} from src
    console.log(A,test,Hello)
}

{
    import {A} from src
    console.log(A)
}

//导入所有
{
    import * as lesson from src
    console.log(lesson.A,lesson.test)
}

// export default 默认导出
{
    let A = 123;
    let test = function() {
        console.log('test')
    }
    class Hello {
        test() {
            console.log('class')
        }
    }

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

推荐阅读更多精彩内容