ES6总结(一) 初识

es6总结

xiong.jpg

往期文章

1.es6简介

  • 回顾javascrip组成:
    • 核心(ECMAScript)

      由ECMA-262定义的ECMAScript是一种在国际认可的标准的脚本语言规范,与Web浏览器没有依赖关系。

    • 文档对象模型(DOM)

      DOM(文档对象模型)是 HTML 和 XML 的应用程序接口(API)。DOM 将把整个页面规划成由节点层级构成的文档。HTML或XML页面中的每个组成部分都是某种类型的节点,这些节点又包含着不同类型的数据。

    • 浏览器对象模型(BOM)

      E 3.0 和 Netscape Navigator 3.0 提供了一种特性 - BOM(浏览器对象模型),可以对浏览器窗口进行访问和操作。使用 BOM,开发者可以移动窗口、改变状态栏中的文本以及执行其他与页面内容不直接相关的操作。

  • ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

2.es6转码

  • 转码原因:现在的Chrome浏览器已经支持ES6了,但是有些低版本的浏览器还是不支持ES6的语法,这就需要我们把ES6的语法自动的转变成ES5的语法。

浏览器es6支持度测试:ruanyf.github.io/es-checker

  • 建立工程目录:

    • 先建立一个项目的工程目录,并在目录下边建立两个文件夹:src和dist

    • src:书写ES6代码的文件夹,写的js程序都放在这里。

    • dist:利用Babel编译成的ES5代码的文件夹,在HTML页面需要引入的时这里的js文件。

  • 编写index.html:

    文件夹建立好后,我们新建一个index.html文件,需要注意的是index.html在引入js文件时,引入的是dist目录下的文件。

  • Babel 转码器:
    • npm init -y 先初始化我们的项目,-y代表全部默认同意,就不用一次次按回车了。命令执行完成后,会在项目根目录下生产package.json文件,可以根据自己的需要进行修改,比如我们修改name的值```
      //package.json文件
      {
      "name": "es6",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
      "test": "echo "Error: no test specified" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC"
      }

      
      
    • npm install -g babel-cli 全局安装Babel-cli

    • npm install --save-dev babel-preset-es2015 babel-cli 本地安装babel-preset-es2015 和 babel-cli

      成功后package.json文件多了devDependencies选项

    {
      "name": "es6",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "devDependencies": {
      "babel-cli": "^6.26.0",
      "babel-preset-es2015": "^6.24.1"
      }
     }
    
    • 新建.babelrc 在根目录下新建.babelrc文件,并打开录入下面的代码
      {
       "presets":[
       "es2015"
       ],
       "plugins":[]
      }
    
    • babel src/index.js -o dist/index.js ES6成功转化为ES5的命令

      转换后:

     //es6  目录src/index.js
     let a=1;
     console.log(a);
     ​
     //es5  目录dist/index.js
     "use strict";
     var a = 1;
     console.log(a);
    
    • 简化转化命令

      • 修改package.json文件
       {
         "name": "es6",
         "version": "1.0.0",
         "description": "",
         "main": "index.js",
         "scripts": {
         "build": "babel src/index.js -o dist/index.js" //更换指令
         },
         "keywords": [],
         "author": "",
         "license": "ISC",
         "devDependencies": {
         "babel-cli": "^6.26.0",
         "babel-preset-es2015": "^6.24.1"
         }
        }
      
      • npm run build 转码指令

        npm run XXX是执行配置在package.json中的脚本

3.变量声明

  • let声明
    • 块级作用域
       {
         let a = 10;
         var b = 1;
        }
        a // 报错: a is not defined.
        b // 1
      ​
        var a = [];
        for (var i = 0; i < 10; i++) {
         a[i] = function () {
         console.log(i);
         };
        }
        a[6](); // 10
        for (let i = 0; i < 10; i++) {
         a[i] = function () {
         console.log(i);
         };
        }
        a[6](); // 6
      

      分析:在var声明的循环中,在全局范围内都有效,所以全局只有一个变量i。每一次循环,变量i的值都会发生改变,而循环内被赋给数组a的函数内部的console.log(i),里面的i指向的就是全局的i

      在let声明的循环中:变量ilet声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6

    • 声明变量不能提升
       // var 的情况
       console.log(foo); // 输出undefined
       var foo = 2;
       // let 的情况
       console.log(bar); // 报错ReferenceError
       let bar = 2;
      

      且let不能提升和块级的特性,导致暂时性死区

       var tmp = 123;
       if (true) {
        tmp = 'abc'; // ReferenceError
        let tmp;
       }
      

      区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

    • 不允许重复声明
      // 报错
      function func() {
       let a = 10;
       var a = 1;
      }
      // 报错
      function func() {
       let a = 10;
       let a = 1;
      }
      function func(arg) {
       let arg; // 报错
      }
      function func(arg) {
       {
       let arg; // 不报错
       }
      }
    
    块级作用域的需求场景
    • 内层变量可能会覆盖外层变量。

        var tmp = new Date();
        function f() {
         console.log(tmp);
         if (false) {
         var tmp = 'hello world';
         }
        }
        f(); // undefined
      

      f()方法内定义的tmp变量提升,覆盖外部的变量,所有undefined

    • 用来计数的循环变量泄露为全局变量

        var s = 'hello';
        for (var i = 0; i < s.length; i++) {
         console.log(s[i]);
        }
      ​
        console.log(i); // 5
      

      循环结束后i并没有消失,而是变成了全局变量

  • const声明
    • 定义const声明一个只读的常量。一旦声明,常量的值就不能改变。
      const PI = 3.1415;
      PI // 3.1415
      PI = 3;
      // TypeError: Assignment to constant variable.
    
    • 性质:块级作用域、不可变量提升、短暂死区、不可重复声明
  • 小知识:javascript6种变量声明

    var命令、function命令、letconst命令、import命令和class命令

4.解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构

  • 数组解构赋值
 //基础用法
 let [a, b, c] = [1, 2, 3];
 let [foo, [[bar], baz]] = [1, [[2], 3]];
 foo // 1
 bar // 2
 baz // 3
 let [ , , third] = ["foo", "bar", "baz"];
 third // "baz"
 let [x, , y] = [1, 2, 3];
 x // 1
 y // 3
 let [head, ...tail] = [1, 2, 3, 4];
 head // 1
 tail // [2, 3, 4]
 let [x, y, ...z] = ['a'];
 x // "a"
 y // undefined
 z // []
 ​
 //不完全解构,解构不成功,变量的值就等于undefined
 let [foo] = []; //foo的值undefined
 let [bar, foo] = [1]; //foo的值undefined
 ​
 //解构设置默认值
 let [x, y = 'b'] = ['a']; // x='a', y='b'
 let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'</pre>
  • 对象解构赋值

    与数组解构不同点:数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

     let { bar, foo } = { foo: "aaa", bar: "bbb" };
     foo // "aaa"
     bar // "bbb"
     let { baz } = { foo: "aaa", bar: "bbb" };
     baz // undefined
    
  • 字符串结构
  const [a,b,c,d,e,f]="fengai";
  console.log(a);//f
  console.log(b);//e
  console.log(c);//n
  console.log(d);//g
  console.log(e);//a
  console.log(f);//i
  • 函数解构
 //函数数组解构
 function add([x, y]){
  return x + y;
 }
 add([1, 2]); // 3
 //函数对象解构
 let json = {
  a:'xiao',
  b:'feng'
 }
 function fun({a,b='ha'}){//默认b='ha'
  console.log(a,b);
 }
 fun(json);
  • 圆括号使用

    如果在解构之前就定义了变量,这时候你再解构,编译会报错

 //不使用圆括号
  let {foo} ={foo:'JSPang'};
  //使用圆括号
  let foo;
  ({foo} ={foo:'JSPang'});
  console.log(foo); //控制台输出jspang

5.字符串扩展

  • for...of 字符串遍历
    for (let codePoint of 'foo') {
      console.log(codePoint)
     }
     // "f"
     // "o"
     // "o"
    
  • includes(), startsWith(), endsWith()
    • includes():返回布尔值,表示是否找到了参数字符串。

    • startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。

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

     let s = 'Hello world!';
     s.startsWith('Hello') // true
     s.endsWith('!') // true
     s.includes('o') // true
    
  • repeat() 字符串重复次数
 'x'.repeat(3) // "xxx"
 'hello'.repeat(2) // "hellohello"
 'na'.repeat(0) // ""
  • 字符串模板
 //之前版本
  let jspang='字符串';
  let blog = '原来'+jspang+'拼接';
  //es6版本
  let jspang='字符串';
  let blog = '原来${jspang}拼接';
  //支持运算
  let a=1;
  let b=2;
  let result=`${a+b}`;//3

6.正则扩展

  • String.prototype.matchAll

    可以一次性取出所有匹配。不过,它返回的是一个遍历器(Iterator),而不是数组。

 const string = 'test1test2test3';
 ​
 // g 修饰符加不加都可以
 const regex = /t(e)(st(\d?))/g;
 ​
 for (const match of string.matchAll(regex)) {
  console.log(match);
 }
 // ["test1", "e", "st1", "1", index: 0, input: "test1test2test3"]
 // ["test2", "e", "st2", "2", index: 5, input: "test1test2test3"]
 // ["test3", "e", "st3", "3", index: 10, input: "test1test2test3"]

7.数值的扩展

  • 二进制、八进制表达

    二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示。

    0b111110111 === 503 // true
    0o767 === 503 // true
    
  • Number.isFinite(), Number.isNaN()

    Number.isFinite()用来检查一个数值是否为有限的(finite),即不是Infinity

    Number.isNaN()用来检查一个值是否为NaN

  Number.isFinite(15); // true
  Number.isFinite(0.8); // true
  Number.isFinite(NaN); // false
  Number.isFinite(Infinity); // false
  Number.isFinite(-Infinity); // false
  Number.isFinite('foo'); // false
  Number.isFinite('15'); // false
  Number.isFinite(true); // false</pre>
  • Number.parseInt(), Number.parseFloat()

    ES6 将全局方法parseInt()parseFloat(),移植到Number对象上面,行为完全保持不变。

 // ES5的写法
  parseInt('12.34') // 12
  parseFloat('123.45#') // 123.45
  ​
  // ES6的写法
  Number.parseInt('12.34') // 12
  Number.parseFloat('123.45#') // 123.45</pre>
  • Number.isInteger()

    Number.isInteger()用来判断一个数值是否为整数。

    Number.isInteger(25) // true
    Number.isInteger(25.1) // false</pre>
    
  • 安全整数和 Number.isSafeInteger()

    JavaScript 能够准确表示的整数范围在-2^532^53之间(不含两个端点),超过这个范围,无法精确表示这个值。

    • 最大安全数:Number.MAX_SAFE_INTEGER

    • 最小安全数:Number.MIN_SAFE_INTEGER

    • Number.isSafeInteger() :判断一个数是否为安全数

      Number.isSafeInteger('a') // false
      Number.isSafeInteger(null) // false
      Number.isSafeInteger(NaN) // false
      Number.isSafeInteger(Infinity) // false
      Number.isSafeInteger(-Infinity) // false
      ​
      Number.isSafeInteger(3) // true
      Number.isSafeInteger(1.2) // false
      Number.isSafeInteger(9007199254740990) // true
      Number.isSafeInteger(9007199254740992) // false
      ​
      Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 1) // false
      Number.isSafeInteger(Number.MIN_SAFE_INTEGER) // true
      Number.isSafeInteger(Number.MAX_SAFE_INTEGER) // true
      Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1) // false
      

8.Math对象的扩展

  • Math.trunc() 数字取整数
  • Math.sign() 判断一个数是否为正数、负数、0

    参数为正数,返回+1

    参数为负数,返回-1

    参数为 0,返回0

    参数为-0,返回-0;

    其他值,返回NaN

  • Math.cbrt() 计算一个数的立方根。
  • Math.hypot() 返回所有参数的平方和的平方根。
    Math.hypot(3, 4);        // 5
    Math.hypot(3, 4, 5);     // 7.0710678118654755
    Math.hypot();            // 0
    Math.hypot(NaN);         // NaN
    Math.hypot(3, 4, 'foo'); // NaN
    Math.hypot(3, 4, '5');   // 7.0710678118654755
    Math.hypot(-3);          // 3
    

9.函数的扩展

  • 函数参数设置默认值
    function log(x, y = 'World') {
     console.log(x, y);
    }
    log('Hello') // Hello World
    log('Hello', 'China') // Hello China
    log('Hello', '') // Hello
    
  • 函数的 length 属性

    指定了默认值以后,函数的length属性,将返回没有指定默认值的参数个数。也就是说,指定了默认值后,length属性将失真。

    (function (a) {}).length // 1
    (function (a = 5) {}).length // 0
    (function (a, b, c = 5) {}).length // 2</pre>
    

    同理,后文的rest 参数也不会计入length属性。

  • rest 参数

    rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

rest是真数组

function add(...values) {
 let sum = 0;
 for (var val of values) {
 sum += val;
 }
 return sum;
 }
 add(2, 5, 3) // 10
 //剩余参数
 function feng(first,...arg){
 for(let val of arg){
 console.log(val); //1,2,3,4,5,6,7
 }
 }
 feng(0,1,2,3,4,5,6,7);
  • arguments回顾

    arguments对象不是数组,而是一个类似数组的对象,伪数组

    arguments.length 参数个数

    arguments[0] 第一个参数,...

    转换成真数组:

    function arg2arr(){
     var arr = Array.prototype.slice.call(arguments);
     console.log(arr);
    }
    arg2arr(1,2,3);
    
  • name 属性

    函数的name属性,返回该函数的函数名。

    function foo() {}
    foo.name // "foo"</pre>
    
  • 箭头函数
    • 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

    • 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

    • 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

    var f = () => 5;
    // 等同于
    var f = function () { return 5 };
    ​
    var sum = (num1, num2) => num1 + num2;
    // 等同于
    var sum = function(num1, num2) {
     return num1 + num2;
    };
    //多个代码段用{}
    var sum = (num1, num2) => { 
     console.log("feng");
     return num1 + num2; 
     }
    
  • 函数体中的严格模式

    我们在ES中就经常使用严谨模式来进行编程,但是必须写在代码最上边,相当于全局使用。在ES6中我们可以写在函数体中,相当于针对函数来使用。

    function add(a,b=1){
     'use strict'
     if(a == 0){
     throw new Error('This is error');
     }
     return a+b;
    }
    console.log(add(1));
    
  • 双冒号运算符

    函数绑定运算符是并排的两个冒号(::),双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即this对象),绑定到右边的函数上面。(可替代apply,call,bind)

    foo::bar;
    // 等同于
    bar.bind(foo);
    ​
    foo::bar(...arguments);
    // 等同于
    bar.apply(foo, arguments);
    ​
    const hasOwnProperty = Object.prototype.hasOwnProperty;
    function hasOwn(obj, key) {
     return obj::hasOwnProperty(key);
    }
    

10.数组的扩展

  • 扩展运算符

    扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列

    console.log(...[1, 2, 3])
    // 1 2 3
    ​
    console.log(1, ...[2, 3, 4], 5)
    // 1 2 3 4 5
    ​
    [...document.querySelectorAll('div')]
    // [<div>, <div>, <div>]
    ​
    //替代apply,将数组分解成一个个函数参数
    // ES5 的写法
    function f(x, y, z) {
    // ...
    }
    var args = [0, 1, 2];
    f.apply(null, args);
    // ES6的写法
    function f(x, y, z) {
    // ...
    }
    let args = [0, 1, 2];
    f(...args);
    
    • 复制数组

      数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组。

        const a1 = [1, 2];
        const a2 = a1;//传址而非传值
        a2[0] = 2;
        a1 // [2, 2]
        //改变a2会影响a1的值
      

      ...扩运算克隆

      const a1 = [1, 2];
      // 写法一
      const a2 = [...a1];
      // 写法二</pre>
      
    • 合并数组

      const arr1 = ['a', 'b'];
      const arr2 = ['c'];
      const arr3 = ['d', 'e'];
      ​
      // ES5 的合并数组
      arr1.concat(arr2, arr3);
      // [ 'a', 'b', 'c', 'd', 'e' ]
      ​
      // ES6 的合并数组
      [...arr1, ...arr2, ...arr3]
      // [ 'a', 'b', 'c', 'd', 'e' ]
      
    • 与解构赋值结合

      // ES5
      a = list[0], rest = list.slice(1)
      // ES6
      [a, ...rest] = list
      
    • 字符串
    [...'hello']
     // [ "h", "e", "l", "l", "o" ]</pre>
    
  • Array.from() 将伪数组转化为真数组
    //伪数组: 1、伪数组是一个对象  2、这个对象必须要有length属性 3、如果这个对象的length不为0,那么必须要有按照下标存储的数据
    let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
    };
    ​
    // ES5的写法
    var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c'];
    ​
    // ES6的写法
    let arr2 = Array.from(arrayLike); // ['a', 'b', 'c'];
    ​
    / arguments对象
    function foo() {
    var args = Array.from(arguments);
    // ...
    }
    
  • Array.of() 将一组值,转换为数组
    Array.of(3, 11, 8) // [3,11,8]
    Array.of(3) // [3]
    Array.of(3).length // 1
    
  • find() 和 findIndex()实例方法

    find(): 用于找出第一个符合条件的数组成员。

    回调函数参数依次为当前的值当前的位置原数组

     find(function(value, index, arr) {
      return value > 9;
     })</pre>
    

    findIndex(): 数组实例的findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置

  • fill()实例方法 用给定值填充数组
 ['a', 'b', 'c'].fill(7)
 // [7, 7, 7]
 ​
 new Array(3).fill(7)
 // [7, 7, 7]
  • entries(),keys() 和 values()实例方法 数组遍历 同 for...of 循环使用

    keys()是对键名的遍历

    values()是对键值的遍历

    entries()是对键值对的遍历

    for (let index of ['a', 'b'].keys()) {
    console.log(index);
    }
    // 0
    // 1
    ​
    for (let elem of ['a', 'b'].values()) {
    console.log(elem);
    }
    // 'a'
    // 'b'
    ​
    for (let [index, elem] of ['a', 'b'].entries()) {
    console.log(index, elem);
    }
    // 0 "a"
    // 1 "b"
    
  • includes()实例方法 判断数组是否包含某一数组元素
    [1, 2, 3].includes(2)     // true
    [1, 2, 3].includes(4)     // false
    [1, 2, NaN].includes(NaN) // true
    
  • entries( )实例方法

    entries()实例方式生成的是Iterator形式的数组,那这种形式的好处就是可以让我们在需要时用next()手动跳转到下一个值。我们来看下面的代码:

    let arr=['hao','ha','hi']
    let list=arr.entries();
    console.log(list.next().value);//hao
    console.log(list.next().value);//ha
    console.log(list.next().value);//hi
    

11.对象的扩展

  • 声明变量直接赋值
    let name="jspang";
    let skill= 'web';
    var obj= {name,skill};
    console.log(obj);  //Object {name: "jspang", skill: "web"}
    
  • 对象Key值构建

    有时候我们会在后台取出key值,而不是我们前台定义好的,这时候我们如何构建我们的key值那。比如我们在后台取了一个key值,然后可以用[ ] 的形式,进行对象的构建

    let key='skill';
    var obj={
     [key]:'web'
    }
    console.log(obj.skill);
    
  • Object.is( ) 对象比较

    ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身

    Object.is就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致

    var obj1 = {name:'feng'};
    var obj2 = {name:'feng'};
    console.log(obj1.name === obj2.name);//true
    console.log(Object.is(obj1.name,obj2.name)); //true
    ​
    console.log(+0 === -0);  //true
    console.log(NaN === NaN ); //false
    console.log(Object.is(+0,-0)); //false
    console.log(Object.is(NaN,NaN)); //true
    
  • Object.assign() 对象的合并

    Object.assign(参数1,参数2,参数3) 将源对象(source)的所有可枚举属性,复制到目标对象(target)

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

    const target = { a: 1 } ​
    const source1 = { b: 2 };
    const source2 = { c: 3 };
    
    Object.assign(target, source1, source2);
    target // {a:1, b:2, c:3}
    

    注意:

    • 浅拷贝 拷贝对象属性的址,而非值
      const obj1 = {a: {b: 1}};
      const obj2 = Object.assign({}, obj1);
      ​
      obj1.a.b = 2;
      obj2.a.b // 2 
      
    • 同名属性替换
      const target = { a: { b: 'c', d: 'e' } }
      const source = { a: { b: 'hello' } }
      Object.assign(target, source)
      // { a: { b: 'hello' } }
      
    • 数组处理

    Object.assign([1, 2, 3], [4, 5])
    // [4, 5, 3]
    //相当于同名属性替换
    ```

  • Object.keys(),Object.values(),Object.entries()

    Object.keys() 返回对象所有键的新数组

    var obj = { foo: 'bar', baz: 42 };
    Object.keys(obj)
    // ["foo", "baz"]
    

    Object.values() 返回对象所有值的新数组

    const obj = { 100: 'a', 2: 'b', 7: 'c' };
    Object.values(obj)
    // ["b", "c", "a"]
    

    Object.entries() 返回对象所有键值对的新数组

    const obj = { foo: 'bar', baz: 42 };
    Object.entries(obj)
    // [ ["foo", "bar"], ["baz", 42] ]
    

12.in的用法

in是用来判断对象或者数组中是否存在某个值的。我们先来看一下用in如何判断对象里是否有某个值

判断对象:

let obj={
 a:'jspang',
 b:'技术胖'
}
console.log('a' in obj);  //true

判断数组:

ES5判断的弊端:以前会使用length属性进行判断,为0表示没有数组元素。但是这并不准确,或者说真实开发中有弊端

let arr=[,,,,,];
console.log(arr.length); //5 这是个坑

//es6
let arr=[,,,,,];
console.log(0 in arr); //false  空数组,判断0下标是否存在
let arr1=['jspang','技术胖'];
console.log(0 in arr1);  // true
  1. 参考:http://es6.ruanyifeng.com/
  1. 参考:http://jspang.com/post/es6.html

版权:本文为资源整理,侵权即删,欢迎转载。

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

推荐阅读更多精彩内容

  • 1、新的声明方式 以前我们在声明时只有一种方法,就是使用var来进行声明,ES6对声明的进行了扩展,现在可以有三种...
    令武阅读 942评论 0 7
  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,055评论 0 13
  • 用更合理的方式写 JavaScript 目录 声明变量 对象 数组 字符串 函数 箭头函数 模块 迭代器和生成器 ...
    小红依阅读 1,758评论 0 5
  • let and constDestructuring 解构赋值Spread and Reset Spre...
    小宝薯阅读 1,471评论 0 13
  • 【Day36】今日阅读《心流》。 主动阅读与被动阅读,收获的效果差别有些大。发自肺腑地想做一件事,就会想尽办法去完...
    巧儿践行者阅读 356评论 0 0