es6入门到五连绝世之三杀(triple kill )

欢迎来到e6语法笔记教学

  1. 这篇博客的记录手法,是通过 demo 记录 es6 要点,注释详细,运行结果也已备注,可能对于技术上的讨论很少,主要面向 es6 入门读者,篇幅可能很长,但是各个节点区分明确,可选择学习…
  2. 感觉从三连决胜开始,玩的开始高阶,一些更具实操意义的东西。这能在工作中确实能够帮助到你的东西

一、Promise 简介

1、主要用于异步计算
2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
3、可以在对象之间传递和操作promise,帮助我们处理队列

1.1、Promise 异步执行顺序

如果有大量异步操作,而异步本身是没执行顺序的,这样就会出现问题,为了满足自身业务需求,将异步嵌套达到执行时排序,但是如果大量异步需要嵌套,则会出现 “回调地狱” 的问题,头皮发麻的那种!!!

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js" type="text/javascript"></script>
<script type="text/javascript">

    let user;
    // jquery 的异步获取 github 上所有用户
    $.get('https://api.github.com/users', data => {

        console.log('fetched all users');
        user = data[0].login;

        // 异步取出返回的第一个用户的 repos , 此异步的执行是必须在前一个异步之后,故嵌套在其里面
        $.get(`https://api.github.com/users/${user }/repos`, data => {
            console.log('fetched all repos');
            console.log(data);
        });
    });



    // 上面的嵌套,如果大量出现,一层层的,就会出现“回调地狱”的现象
    // promise 理解就像一种承诺,无论请求是否成功,都会给你一个返回信息,基于axios解决“回调地狱”

    const userPromise = axios.get('https://api.github.com/users');

    userPromise.then(reponse =>{       // then() 就是请求返回的监听, reponse参数返回的信息
        console.log(reponse);
        let username = reponse.data[0].login;   // 取出用户名

        return axios.get(`https://api.github.com/users/${username }/repos`);    // 这里返回的同样还是一个 promise

    }).then(reponse => {        // 可接着对上面 return 的 peomise 接着监听

        console.log(reponse.data);

    }).catch(err =>{        // 异常捕获
        console.error(err);   // 智能打印对应的 异步请求 的错误
    });

</script>

1.2、自定义 promise

如果嫌弃引用别的框架太大,而自己只是想用一下异步的处理 promise,那么可以自定义实现,展示如下:

<script type="text/javascript">

    // 自定义 promise
    const p = new Promise((resolve, reject) => {

        // 模拟异步请求
        setTimeout(() => {

            /*
                1、参数介绍
                    resolve:用来返回成功的操作数据
                    reject : 如果失败用来返回指定信息,Error(),具体提示报错是哪一行!
             */
            //resolve("异步成功数据!");
            reject(Error("异步失败哦!"));

        }, 2000);
    })

    p.then(data => {

         console.log(data); // 异步成功数据!
    }).catch(err => {

        console.log(err);   //Error: 异步失败哦! at index.html:63
    });

</script>

1.3、自定义Promise示例

自定义使用 Promose 时,如果需要多个异步,使用函数拆解,监听其返回即可!!!

<script type="text/javascript">

    // 模拟后台数据中的表
    const repos = [
        {name: 'grit', owner: 'mojombo', description: 'Grit is no longer maintained', id: 1},
        {name: 'jsawesome', owner: 'vanpelt', description: 'Awesome JSON' , id: 2},
        {name: ' merb-core', owner: 'wycats', description: 'Merb Core: All you need. None you don\'t.', id: 3},
    ];

    const owners =[
        {name: 'mojombo', location: 'San Francisco', followers: 123},
        {name: 'vanpelt', location: 'Bay Minette' , followers: 1034},
        {name: 'wycats', location: 'Los Angeles, CA', followers: 388}
    ];



    // 定义函数获取
    function getRepoById(id){

        // 使用 promise
        return new Promise((resolve, reject) =>{
            // 模拟异步请求
            setTimeout(() => {
                const repo = repos.find(repo => repo.id === id);
                // 查找到有数据就是 true
                if(repo){
                    resolve(repo);
                }else{
                    reject(Error(`No repo found.`));
                }
            }, 1000);   //1秒后
        });
    }


    // 定义函数获取
    function comboundOwner(repo){

        // 使用 promise
        return new Promise((resolve, reject) =>{
            const owner = owners.find(owner => owner.name === repo.owner);
            // 查找到有数据就是 true
            if(owner){
                repo.owner = owner;     // 将repo 中的 ower 信息补全
                resolve(repo);
            }else{
                reject(Error(`No owner found.`));
            }
        });
    }


    // 调用函数后直接使用 then() 监听
    getRepoById(1).then(repo => {
        console.log(repo);
        return comboundOwner(repo);     // 调用函数,并返回,同 axios

    }).then(repo => {           // 再次监听
        console.log(repo);

    }).catch(err =>{
        console.log(err);
    });

</script>

1.4、同时处理多个 Promise

Promise.all(iterable) 方法返回一个 Promise 实例,此实例在 iterable 参数内所有 的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);
如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise 的结果。

Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝(第一个处理完的 promise)

<script type="text/javascript">


    const usersPromise = new Promise((resolve, reject) =>{
        setTimeout(() =>{
            resolve(['mojombo', 'vanpelt', 'wycats']);
        }, 2000);
    });

    const moviePromise = new Promise((resolve, reject) =>{
        setTimeout(() =>{

            // 使用了一个随机函数,概率返回
            if(Math.round(Math.random()*10) > 5 ){
                resolve({name: '摔跤吧,爸爸!', rating: 9.2, year: 2016});
            }else{
                reject(Error('No movie'));
            }

        }, 500);
    });

    Promise
        .all([usersPromise, moviePromise])      // 添加两个 promise
        .then(responses => {                    // 所有正确执行完,才会执行监听里面的

            //(2) [Array(3), {…}]   ,打印的是一个长度为2的数组,第一个元素是长度为3的数组,第二个元素是个对象
            //console.log(responses);

            // 数组解构打印
            const [users, movie] = responses;
            console.log(users);         // ["mojombo", "vanpelt", "wycats"]
            console.log(movie);         // {name: "摔跤吧,爸爸!", rating: 9.2, year: 2016}

        }).catch(err => {       // 只要有一个 promise 失败,则立马执行 catch 块

            console.log(err);
        });

    Promise
        .race([usersPromise, moviePromise])      // 添加两个 promise
        .then(responses => {                    // 添加的两个promise,由于其定时时间是不一样的,则第一个 Promise 执行正确返回才会执行监听里面的

            console.log(`responses:${responses }`);         // responses:[object Object]

        }).catch(err => {       // 第一个 Promise 执行完的返回失败,则立马执行 catch 块

            console.log(`err:${err }`);
        });

</script>

二、循环遍历

2.1、for ,of 遍历简介

<script type="text/javascript">

   // 定义一个数组,循环遍历
   const fruits = ['Apple', 'Banana', 'Orange', 'Mango'];
   // 为其原型对象加个值
   fruits.describe = "My favorite fruits";


   // 1、此循环比较繁琐,可读性也不是很高
   for(let i=0; i<fruits.length; i++){
         console.log(fruits[i]);    //逐个打印
   }


   // 2、js 提供的数组遍历函数,简化了语法,使用 fruit 变量参数遍历即可
   fruits.forEach( fruit => {

        // 缺点: 不能终止或跳过,下面的break,continue 会报错
        if(fruit === 'Orange'){
            //break;    //SyntaxError: Illegal break statement
            //continue;   //SyntaxError: Illegal continue statement: no surrounding iteration statement
        }
        console.log(fruit);        //逐个打印
   });


   // 3、for in 循环遍历下标
   for(let index in fruits){
        console.log(fruits[index]);    //缺点:逐个打印,还会打印其原型对象添加的值My favorite fruits
   }



   // 4、推荐使用 for of,取上之精华,去之其糟粕
   for(let fruit of fruits){

        //  支持终止与跳过
       if(fruit === 'Orange'){
            break;
            //continue;
        }
        console.log(fruit);        //逐个打印
   }
</script>

补充:有些场景可能需要使用到 index 下标
es6-for…of 循环一个数组返回索引的语法:
for(let [index,elem] of new Map( arr.map( ( item, i ) => [ i, item ] ) )){
  console.log(index);
  console.log(elem);
}

<script type="text/javascript">

	var arr = [ 'a', 'b', 'c' ];
	// new Map() 将其每次循环返回的 key=value,构建成新的 map
	for( let [i, item] of new Map( arr.map((item, i) => [i, item]) ) ){
		console.log( i, item ); //0 "a"     1 "b"       2 "c"
	}

</script>

2.2、for ,of 遍历示例

上一节讲到 for … of 可遍历可迭代对象,可迭代对象是部署了Iterator接口,或者定义了 [ Symbol.Iterator ] 方法的数据结构,遍历器便提供了这样的一种遍历方式。

<script type="text/javascript">

   // 1、定义一个数组,使用遍历器循环遍历
   const fruits = ['Apple', 'Banana', 'Orange', 'Mango'];

   // 接受其遍历器对象
   const iterator = fruits.entries();
   for(let fruit of iterator){
        // 其遍历器返回的是有下标的数组,这样既可以得到值,又能获得下标
        console.log(fruit);     //[0, "Apple"], [1, "Banana"], [2, "Orange"], [3, "Mango"]
        console.log(fruit[1]);  // 每次循环获得上面数组的第二的元素,Apple  Banana  Orange  Mango
   }

   // 解构语法改写
   for(let [index, fruit] of fruits.entries()){
        // 理想状态的遍历结果如下
        console.log(`${fruit} ranks ${index + 1} in my favorite fruits`);
   }



   // 2、 遍历参数 arguments 对象
   function sum(){
        let total = 0;
        // 这里是一个参数对象arguments,虽然不是数组,但可以使用 for...of 遍历
        for(let num of arguments){
            total = num + total;
        }
        console.log(total);     // 612
        return total;
   }
   sum(10,24,58,69,451);


   // 3、遍历字符串
   let name = 'Tom';
   for(let char of name){
        console.log(char);  //逐个打印 T  o  m
   }


   // 4、遍历 nodlist 类型的标签集合
   // 获取网页中所有 <li> 标签
   const list = document.querySelectorAll('li');
   for(let li of list){

        // meige li 都绑定一个点击事件
        li.addEventListener('click', function(){
            // 被点击的对象添加高亮样式
            this.classList.toggle('highlight');
        });
   }
   
</script>

三、Array数组方法

3.1、Array.from() … of() 浅析

e6 为类数组提供的新方法 Array.from() ,Array.from() 方法从一个类似数组或可迭代对象中创建一个新的。类数组对象就是拥有 length 属性,可遍历的对象。

<ul>
   <li>Go to store</li>
    <li>Watch TV</li>
    <li>Go Shopping</li>
</ul>
<script type="text/javascript">

		// 1、 将标签元素集合对象转换为数组
       const todos = document.querySelectorAll('li');
       console.log(todos);  // f12 看其打印类型,_proto__: NodeList

       // 必须要将todos转换为 数组对象,才能调用数组原型的 map() 方法
       const todosArr = Array.from(todos);
       const names = todosArr.map(todo => todo.textContent);
       console.log(names);      // ["Go to store", "Watch TV", "Go Shopping"]


       // Array.from()的第二个参数(可选),mapFn 最后生成的数组上再执行一次 map 方法后再返回
       // 将上面内容可改写成一步
       const strs = Array.from(todos, todo => todo.textContent);
       console.log(strs);      // ["Go to store", "Watch TV", "Go Shopping"]


        // 2、将 arguments 参数转换为数组
       function sum(){
         console.log(arguments);    // f12 查看其类型__proto__: Object
         // reduce()调用之前,必须将 arguments 转为数组
         return Array.from(arguments).reduce((prev, curr) => prev + curr, 0);
       }
       console.log(sum(78,85,63));  //226


       // 3、字符串转换为数组
       const website = "Laravist";
       console.log(Array.from(website));    //["L", "a", "r", "a", "v", "i", "s", "t"]
       
</script>

Array数组创建时,由于传入参数个数不一样,导致其方法的创建行为是不一样的,Array.of()能解决这样的不一致性,Array.of() 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。
看下图:
在这里插入图片描述

<script type="text/javascript">
	 let news = new Array(7);
     console.log(news);   //(7) [empty × 7],长度为7,各元素为空的数组

     let arr = Array.of(7);
     console.log(arr);        //[7],长度为1,元素是7
     arr = Array.of(7, 2, 3);
     console.log(arr);        //[7, 2, 3]

</script>

3.2、Array 其他实用方法

 <script type="text/javascript">

    // 1、 声明了一个数组对象
    const inventory = [
        {name: 'apples', quantity: 2},
        {name: 'bananas', quantity: 0},
        {name: 'cherries', quantity: 5}
   ];


   /*
     1、 查找数组中满足某个条件的元素,相对于for...of 循环,使用方法更简便
        find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined,找到立马return
        参考:https://www.runoob.com/jsref/jsref-find.html
   */
   const bananas = inventory.find( (currentValue, index, arr) => {
        if(currentValue.name === 'bananas'){
            return true; // 找到 return true, bananas变量接受到当前浏览的对象
        }
         return false;
    });

   //const bananas1 = inventory.find( fruit => fruit.name === 'bananas'); //简写形式,推荐
   console.log(bananas);    //{name: "bananas", quantity: 0}


   /*
     2、 同理,查询数组中某个条件的元素的下标,找到立马return
        findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
    */
   const cherries = inventory.findIndex(fruit => fruit.name === 'cherries'); //简写
   console.log(cherries);      //2 ,这是返回的下标



   /*
     3、 检测数组中是否存在至少一个元素,满足自己传入的函数检验,存在-->true, 不存在 --> false (至少一个返回true)
        some() 方法检测 TypedArray 的一些元素是否通过所提供函数的测试。
    */
   const isEnough = inventory.some(fruit => fruit.quantity >0 );
   console.log(isEnough);   // true


   /*
     4、 同上,检测所有元素是否满足传入函数,一个不满足马上返回 false
        every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。
    */
   const isAllEnough = inventory.every(fruit => fruit.quantity >0 );
   console.log(isAllEnough);   // false

</script>

四、剩余参数与扩展运算符

4.1、剩余参数使用

JS函数内部有个arguments对象,可以拿到全部实参。现在ES6给我们带来了一个新的对象,可以拿到除开始参数外的参数,即剩余参数。

理解:剩余参数语法允许我们将一个不定数量的参数表示为一个数组

<script type="text/javascript">

    /*
        1、 剩余参数,用于对参数需要计算的场景
           ...numbers : ...后加上自定义的参数变量名 numbers 即可
     */
    function sum(...numbers){

        console.log(numbers);   //(4) [1, 2, 5, 4], __proto__: Array(0),原型为数组,与 arguments 区别
        return numbers.reduce((prev, curr) => prev + curr, 0);
    }
    console.log(sum(1, 2, 5, 4));    // 12



    /*
        2、 剩余参数只能是函数形参的最后一个的位置,且前面可以有多个其他形参
     */
    function converCurrency(rate, ...amounts){

        console.log(rate, amounts);   // (3) [2, 5, 4], 只接受剩下没有映射的的参数,与 arguments 区别
        return amounts.map(amount => amount * rate);
    }
    console.log(converCurrency(0.85, 2, 5, 4)); //(3) [1.7, 4.25, 3.4]


    /*
        3、 应用于数组的解构
     */
    const player = ['Jelly', 12345, 6, 8, 5, 7];
    const [name, id, scores] = player;  // 复习,数组结构是下标对应映射
    console.log(name, id, scores);     //Jelly 12345 6 , 解构时 player 后面下标位没有则没有映射传入

    // 如果 scores1 解构剩余的元素,使用剩余参数
    const [name1, id1, ...scores1] = player;  // 复习,数组结构是下标对应映射
    console.log(name1, id1, scores1);       //Jelly 12345 (4) [6, 8, 5, 7]


</script>

4.2、扩展运算符

扩展运算符是把一个可遍历的对象的每个元素,扩展成一个新的参数序列

<script type="text/javascript">

    /*
        数组之间的整合,由浅入深,讲解
     */
    const youngers = ['George', 'John', 'Tom'];
    const olders = ['Tencent', 'Baidu', 'Ali'];

    // 1、利用数组的 concat() 方法,将数组整合为一个新的数组,原数组不变
    const numbers = youngers.concat(olders);
    console.log(youngers);  // ["George", "John", "Tom"]
    console.log(numbers);   // ["George", "John", "Tom", "Tencent", "Baidu", "Ali"]


    // 2、如果想在整合时在 youngers 和 olders 中新加一个 marry,老套用法
    let nums = [];         //先定义这是个数组
    nums = nums.concat(youngers);
    nums.push("Marry");     // 从数组尾部追加一个元素
    nums = nums.concat(olders);
    console.log(nums);     // ["George", "John", "Tom", "Marry", "Tencent", "Baidu", "Ali"]


    // 3、扩展运算符
    const str = 'Jerry';
    const sarr = [...str];  // 将每个字符扩展成了数组元素。此处等同 [...'Jerry']
    console.log(sarr);      //  ["J", "e", "r", "r", "y"]


    // 4、利用扩展运算符整合 youngers 和 olders
    let news = [...youngers, ...olders];
    console.log(news);      // ["George", "John", "Tom", "Tencent", "Baidu", "Ali"]


    // 5、当然,新增 marry 如下:
    const newS = [...youngers, 'Marry', ...olders];
    console.log(newS);      // ["George", "John", "Tom", "Marry", "Tencent", "Baidu", "Ali"]




    // 6、浅析关于数组间赋值,是对象间的地址的引用
    let s1 = youngers;
    s1[0] = 'Str';          // 改变了 s1 数组的0下标元素值,打印发现 youngers 数组也发生了变化
    console.log(s1);        //  ["Str", "John", "Tom"]
    console.log(youngers);  //  ["Str", "John", "Tom"]


    // 6.1、杜绝上面的现象,利用 concat() 生成一个新的数组
    let s2 = [].concat(olders);
    s2[0] = 'Change';
    console.log(s2);        // ["Change", "Baidu", "Ali"]
    console.log(olders);    // ["Tencent", "Baidu", "Ali"]


    //6.2、使用扩展运算符改写
    let s3 = [...olders];
    s3[0] = 'Hello';
    console.log(s3);        // ["Hello", "Baidu", "Ali"]
    console.log(olders);    // ["Tencent", "Baidu", "Ali"]

</script>

4.3、扩展运行符示例

1、 下面这个是一个结合扩展运算符,写的一个漂亮的 css 动态展示效果,里面介绍了两个有意思的 css 属性:transform、transition。

<style>
    .highlight{
        padding: 2px 5px;
        background: #00adb4;
        color: white;
    }

    .heading{
        justify-content: center;
        align-items: center;
        font-family: sans-serif;
        font-size: 50px;
        color: white;
        text-shadow: 3px 3px 0 rgba(0, 0, 0, 0.2);
        background-color: #f2be45;
        display: inline-block;
    }

    .heading span{
        cursor: pointer;
        display: inline-block;
        /*
            transition 属性是一个简写属性,用于设置四个过渡属性
            参考:https://www.w3school.com.cn/cssref/pr_transition.asp
         */
        transition: transform 0.25s;
    }

    .heading span:hover{
        color: black;
        /*
            transform 属性向元素应用 2D 或 3D 转换。该属性允许我们对元素进行旋转、缩放、移动或倾斜
            参考地址:https://www.w3school.com.cn/cssref/pr_transform.asp

            注意:对于内联元素 span 是不会有旋转效果的,所以上面的样式将 span 设置了 display: inline-block;
         */
        transform: translateY(-20px) rotate(10deg) scale(2);
    }
</style>
<body>

<h2 class="heading">LARAVIST!</h2>
<script type="text/javascript">

    /*
       通过 js 为上方h2标签元素的内容添加样式
     */
    const heading = document.querySelector(".heading");

    // 定义函数,将字符串内容扩张成字符数组,逐一处理
    function wrapWithSpan(context){
        //下面这一步简写,是不是很简单,此处所涉及到的都是之前举例过的知识
        return [...context].map(text => `<span>${text}</span>`).join('');
    }

    console.log(wrapWithSpan(heading.textContent));     // 查看返回的数据

    // 将返回的数据重新写回 h2 标签元素
    heading.innerHTML = wrapWithSpan(heading.textContent);

</script>
</body>

在这里插入图片描述

2、 扩展运算符应用于标签元素,对象属性,数组元素的示例。

<ul>
   <li>Go to store</li>
    <li>Watch TV</li>
    <li>Go Shopping</li>
</ul>
<script type="text/javascript">

    /*
       1、 应用于标签元素
     */
    const todos1 = document.querySelectorAll("li");     //__proto__: NodeList
    console.log(Array.from(todos1));     // 使用之前讲解的方法将其转换为 数组类型

    // 使用扩展运算符将todos转为数组再调用map()方法
    console.log([...todos1].map(todo => todo.textContent));  // ["Go to store", "Watch TV", "Go Shopping"]



   /*
        2、 扩展对象的属性
     */
    const favorites = {
        color: ['white', 'black'],
        fruit: ['banana', 'mongo']
    }
    // 在购买的列表中把喜欢的对象的水果属性扩展进来
    const shoppingList = ['milk', 'sweets', ...favorites.fruit];
    console.log(shoppingList);     // ["milk", "sweets", "banana", "mongo"]


    /*
        3、 扩展数组元素, 删除 todoss 数组中id为1(下标为1)的元素
     */
    let todos = [
        {id: 1, name: 'go to store', complete: false},
        {id: 2, name: 'watch TV', complete: true},
        {id: 3, name: 'go shopping', complete: false}
    ]

    const todoIndex = todos.findIndex(todo => todo.id === 2);  // 获得下标 1
    /*
        arrayObject.slice(start,end):可从已有的数组中返回选定的元素。
            --start   必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。
            --end   可选。规定从何处结束选取。如果没有指定该参数,那么切分的数组结束的所有元素。

        参考地址:https://www.w3school.com.cn/jsref/jsref_slice_array.asp
     */
    //  下面注释内容得到的是一个二维数组,因为 slice() 切分得到是数组,而不是对象
    // const newTodos = [todos.slice(0, todoIndex), todos.slice(todoIndex + 1)];    // [Array(1), Array(1)]

    const newTodos = [...todos.slice(0, todoIndex), ...todos.slice(todoIndex + 1)]; //通过扩展运算符,迭代数组中的元素(对象),得到对象
    console.log(newTodos);  // [{…}, {…}]

    todos = newTodos;
    console.log(todos); // [{…}, {…}]

</script>

3、 扩展运算符应用到函数参数的传入。

<script type="text/javascript">

    /*
       1、 扩展运算符在函数中运用,数组追加元素
     */
    const fruit = ['apple', 'banana', 'pear'];
    const newFruit = ['orange', 'mongo'];

    // 将 newFruit 添加到 fruit 中
    //  fruit.push(newFruit);  // ["apple", "banana", "pear", Array(2)] ,添加的元素为数组,不是我们想要的

    /*
        apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性
            Function.apply(obj,args)方法能接收两个参数
                obj:这个对象将代替Function类里this对象
                args:这个是数组,它将作为参数传给Function(args-->arguments)
     */
    // fruit.push.apply(fruit, newFruit); //["apple", "banana", "pear", "orange", "mongo"] ,可以利用 apply() 传值

    fruit.push(...newFruit);   // es6 写法,简单快捷,需注意这不同于 concat(),这里更改的就是原来的数组
    console.log(fruit);         //  ["apple", "banana", "pear", "orange", "mongo"],



    /*
        2、 日期函数传参
     */

    const dateFields = [2019, 9, 12];
    // const date = new Date(dateFields[0], dateFields[1], dateFields[2]); //想利用这种数组来构建是不是很繁琐

    const date = new Date(...dateFields);   // es6改写,再多参数也灵活传入
    console.log(date);  // Sat Oct 12 2019 00:00:00 GMT+0800 (中国标准时间)

</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值