学习ES6笔记[尚硅谷教育一]

01.严格模式

 

<!--
1. 理解:
  * 除了正常运行模式(混杂模式),ES5添加了第二种运行模式:"严格模式"(strict mode)。
  * 顾名思义,这种模式使得Javascript在更严格的语法条件下运行
2.  目的/作用
    * 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为
    * 消除代码运行的一些不安全之处,为代码的安全运行保驾护航
    * 为未来新版本的Javascript做好铺垫
3. 使用
  * 在全局或函数的第一条语句定义为: 'use strict';
  * 如果浏览器不支持, 只解析为一条简单的语句, 没有任何副作用
4. 语法和行为改变
    * 必须用var声明变量
    * 禁止自定义的函数中的this指向window
    * 创建eval作用域
    * 对象不能有重名的属性
-->

<script type="text/javascript">
    'use strict'
    var username='coke'
    console.log(username)

    function Person(name,age){
        this.name=name;
        this.age=age

    }
    new Person('coke',26)

    var str='NBA'
    eval('var str="CBA";alert(str)')
    alert(str)

</script>

02.JSON对象

 

<!--
1.JSON.stringify(obj/arr)
*js对象(数组)转换为js对象(数组)
2.JSON.parse(json)
*json对象(数组)转换为js对象(数组)

-->
<script>
    var obj={username:'kobe'};
    obj=JSON.stringify(obj);
    console.log(typeof obj);
    obj=JSON.parse(obj);
    console.log(typeof obj);
    //var a='aaa'
    //var b="bbb"

</script>

03.Object扩展

 

<!--
ES5给Object扩展了好一些静态方法, 常用的2个:
1. Object.create(prototype, [descriptors])
  * 作用: 以指定对象为原型创建新的对象
  * 为新的对象指定新的属性, 并对属性进行描述
    value : 指定值
    writable : 标识当前属性值是否是可修改的, 默认为false
    configurable: 标识当前属性是否可以被删除 默认为false
    enumerable: 标识当前属性是否能用for in 枚举 默认为false

2. Object.defineProperties(object, descriptors)
  * 作用: 为指定对象定义扩展多个属性
  * get :用来获取当前属性值得回调函数
  * set :修改当前属性值得触发的回调函数,并且实参即为修改后的值
  * 存取器属性:setter,getter一个用来存值,一个用来取值
-->

<script>
    var obj={username:'coke',age:'26'};
    var obj1={}
    obj1=Object.create(obj,{
         sex:{value:'',
             writable:true,
             configurable:true,
             enumerable:true
         }
    });
    console.log(obj1.sex)
    obj1.sex=''
    console.log(obj1.sex)
    // delete obj1.sex
    // console.log(obj1)
    for(var i in obj1){
        console.log(i)
    }
    //Object.defineProperties(object,descriptors)
    var obj2={firstName:'Kobe',lastName:'bryant'};
    Object.defineProperties(obj2,{
        fullName:{
            get:function(){//获取扩展属性的值,获取扩展属性的get方法自动调用
                console.log('get()')
                return this.firstName+' '+this.lastName;
            },
            set:function(data){//监听扩展属性,当扩展属性发生变化的时候会自动调用,自动调用后会将变化的值作为实参
                console.log('set()',data);
                var names=data.split(' ');
                this.firstName=names[0];
                this.lastName=names[1];
            }
        }
    })
    console.log(obj2)
    console.log(obj2.fullName);
    obj2.fullName='tim duncan'
    console.log(obj2.fullName)
</script> 

04.Object扩展2

 

<!--
对象本身的两个方法:
*get propertyName(){}用来得到当前属性值得回调函数
*set propertyName(){} 用来监视当前属性值变化的回调函数
-->

<script>
    var obj={
        fisrtName:'curry',
        lastName:'stephen',
        get fullName(){
            return this.firstName+' '+this.lastName ;
        },
        set fullName(data){
             var names=data.split(' ');
            this.firstName=names[0];
            this.lastName=names[1];
        }
    }
    console.log(obj);
    obj.fullName='kebo bryant'
    console.log(obj.fullName)
</script>

05.数组遍历

 

<!--
1. Array.prototype.indexOf(value) : 得到值在数组中的第一个下标
2. Array.prototype.lastIndexOf(value) : 得到值在数组中的最后一个下标
3. Array.prototype.forEach(function(item, index){}) : 遍历数组
4. Array.prototype.map(function(item, index){}) : 遍历数组返回一个新的数组,返回加工之后的值
5. Array.prototype.filter(function(item, index){}) : 遍历过滤出一个新的子数组, 返回条件为true的值
-->
<script>
    /*需求:
   1. 输出第一个6的下标
   2. 输出最后一个6的下标
   3. 输出所有元素的值和下标
   4. 根据arr产生一个新数组,要求每个元素都比原来大10
   5. 根据arr产生一个新数组, 返回的每个元素要大于4
   */
    arr=[2,1,3,4,5,2,8,4,1]
    console.log(arr.indexOf(4));
    console.log(arr.lastIndexOf(4));
    arr.forEach(function(item,index){
        console.log(item,index)
    })
    var arr1=arr.map(function(item,index){
        return item+10;
    });
    console.log(arr1,arr)
    var arr2=arr.filter(function(item,index){
        return item>3
    })
    console.log(arr,arr2)

</script>

06.Function扩展

<!--
1. Function.prototype.bind(obj) :
  * 作用: 将函数内的this绑定为obj, 并将函数返回
2. 面试题: 区别bind()与call()和apply()?
  * 都能指定函数中的this
  * call()/apply()是立即调用函数
  * bind()是将函数返回
-->

<script type="text/javascript">
    var obj={username:'kobe'};
    function foo(){
        console.log(this)
    }
    console.log(foo(obj))
    console.log(foo.call(obj))
    console.log(foo.apply(foo))
    function foo2(data){
        console.log(this,data)
    }
    // console.log(foo2.call(obj,33))//直接从第二个参数开始,依次传入
    // console.log(foo2.apply(obj,[22]))//第二个参数必须是数组,传入放在数组里
    //bind的特点:绑定完this不会立即调用当前的函数,而是将函数返回
    //bind传参的方式同call一样
    // var bar=foo.bind(obj)
    // console.log(bar)
    // bar()

    //foo2.bind(obj,33)()

    setTimeout(function(){
      console.log(this)
    }.bind(obj),1000)

</script>

07.let关键字

<button >按钮1</button>
<button >按钮2</button>
<button >按钮3</button>

<script type="text/javascript">
    let username='kobe';
    console.log(username);
    let btns=document.getElementsByTagName('button');
    for(let i=0;i<btns.length;i++){
        var btn=btns[i];
        /*(function(i){
            btn.onclick=function(){
            alert(i);}

        })(i)*/
         btn.onclick=function(){
            alert(i);}
    }

</script>

 

08.ES6字符串简写

 

<script>
    let username='kobe';
    let age=39;

    let obj={
        username,//同名的属性可以省略不写
        age,
        getName(){//可以上略函数的function
            return this.username
        }
    }
    console.log(obj)
    console.log(obj.getName())
</script>

09.箭头函数

<button id="btn1">测试箭头函数this_1</button>
<button id="btn2">测试箭头函数this_2</button>
<!--
* 作用: 定义匿名函数
* 基本语法:
  * 没有参数: () => console.log('xxxx')
  * 一个参数: i => i+2
  * 大于一个参数: (i,j) => i+j
  * 函数体不用大括号: 默认返回结果
  * 函数体如果有多个语句, 需要用{}包围,若有需要返回的内容,需要手动返回
* 使用场景: 多用来定义回调函数

* 箭头函数的特点:
    1、简洁
    2、箭头函数没有自己的this,箭头函数的this不是调用的时候决定的,而是在定义的时候处在的对象就是它的this
    3、扩展理解: 箭头函数的this看外层的是否有函数,
        如果有,外层函数的this就是内部箭头函数的this,
        如果没有,则this是window。

-->

<script>
    // let fun=function(){
    //     console.log('我是箭头函数')
    // }
    let fun=()=>console.log('我是箭头函数')
    fun();
    //形参的情况
    //1、没有形参的时候
    let fun1=()=>console.log('我是箭头函数');
    fun1();
    //2、只有一个形参的时候()可以省略
    let fun2=a=>console.log(a);
    fun2('aaa');
    //3、两个及两个以上的形参的时候()不能省略
    let fun3=(x,y)=>console.log(x,y)
    fun3(25,36)

    //函数体的情况
    //1、函数体只有一条语句或者是表达式的时候{}可以省略-->会自动返回语句执行的结果或者是表达式的结果
    let fun4=(x,y)=>x+y;
    console.log(fun4(24,36));
    //2.函数体不止一条语句或者是表达式的情况{}不可以省略
    let fun5=(x,y)=>{
        console.log(x,y);
        return x+y;
    }
    console.log(fun5(35,49));

    let btn1=document.getElementById('btn1');
    let btn2=document.getElementById('btn2');
    btn1.onclick=function(){
        console.log(this)
    }
        //let that=this;
    var obj={
        username:'箭头函数',
        getName:()=>{
             btn2.onclick=()=>{
                console.log(this)
            };
        }
    };
    obj.getName();

</script>

 

10.点点运算符

 

<!--
1. rest(可变)参数
    * 用来取代arguments 但比 arguments 灵活,只能是最后部分形参参数
    function fun(...values) {
        console.log(arguments);
        arguments.forEach(function (item, index) {
            console.log(item, index);
        });
        console.log(values);
        values.forEach(function (item, index) {
            console.log(item, index);
        })
    }
    fun(1,2,3);
2. 扩展运算符
  let arr1 = [1,3,5];
  let arr2 = [2,...arr1,6];
  arr2.push(...arr1);
-->

<script>
    function foo(a,...value){
        console.log(arguments);
        //arguments.callee();
        console.log(value)
        // arguments.forEach(function(item,index){
        //     console.log(item,index);
        // })
        value.forEach(function(item,index){
            console.log(item,index);
        })
    }
    foo(2,65,33,45);

    let arr=[1,6];
    let arr1=[2,3,4,5];
    arr=[1,...arr1,6];
    console.log(arr)
    console.log(...arr)
</script>

 

 

 

11.promise函数

 

<!--
1. 理解:
  * Promise对象: 代表了未来某个将要发生的事件(通常是一个异步操作)
  * 有了promise对象, 可以将异步操作以同步的流程表达出来, 避免了层层嵌套的回调函数(俗称'回调地狱')
  * ES6的Promise是一个构造函数, 用来生成promise实例
2. 使用promise基本步骤(2步):
  * 创建promise对象
    let promise = new Promise((resolve, reject) => {
        //初始化promise状态为 pending
      //执行异步操作
      if(异步操作成功) {
        resolve(value);//修改promise的状态为fullfilled
      } else {
        reject(errMsg);//修改promise的状态为rejected
      }
    })
  * 调用promise的then()
    promise.then(function(
      result => console.log(result),
      errorMsg => alert(errorMsg)
    ))
3. promise对象的3个状态
  * pending: 初始化状态
  * fullfilled: 成功状态
  * rejected: 失败状态
4. 应用:
  * 使用promise实现超时处理

  * 使用promise封装处理ajax请求
    let request = new XMLHttpRequest();
    request.onreadystatechange = function () {
    }
    request.responseType = 'json';
    request.open("GET", url);
    request.send();
-->

<script>
    /*
    //创建promise对象
    let promise=new Promise((resolve,reject)=>{
        //初始化promise状态;pending:初始化
        console.log('111')
        //执行异步操作,通常是发送ajax请求,开启定时器
        setTimeout(()=>{
            console.log('333');
            //根据异步任务的返回结果来去修改promise的状态
            //异步任务执行成功
           //resolve('哈哈');//修改promise的状态为 fullfilled:成功的状态
            //异步任务执行失败
            reject('555');//修改promise的状态为 rejected 失败的状态
        },2000)

    })
    console.log('222');
    promise
        .then((data)=>{//成功的回调
            console.log(data,'成功了.....');
        },(error)=>{//失败的回调
            console.log(error,'失败了....')
        },
    )
*/

   //定义获取新闻的功能函数
   function getNews(url){
       let promise=new Promise((resolve,reject)=>{
           //状态:初始化
           //执行异步任务
           //创建xmlHttp实例对象
           let xmlHttp=new XMLHttpRequest();
           //绑定监听 readyState
           xmlHttp.onreadystatechange=function(){
               if(xmlHttp.readyState===4){//请求成功
                   if(xmlHttp.status===200){
                  //      console.log(xmlHttp.responseText);
                       //修改状态
                       resolve(xmlHttp.responseText);//修改promise的状态为成功的状态
                   }else{//请求失败
                   reject('暂时没有新闻内容!!');
               }
               }
           };
           //open设置请求的方式以及url
           xmlHttp.open('GET',url);
           //
           xmlHttp.send()
       })
       return promise
   }
   getNews('http://localhost:3000/news?id=2')
    .then((data)=>{
        console.log(data)
        //发送请求获取评论内容准备url
        let commentsUrl=JSON.parse(data).commentsUrl;
        let url='http://localhost:3000'+commentsUrl;
        //发送请求
       return  getNews(url);
        },
        (error)=>{
        console.log(error)
        })
    .then((data)=>{
        console.log(data)
        },
        ()=>{

        })
</script>

12.symbol用法

 

<!--
前言:ES5中对象的属性名都是字符串,容易造成重名,污染环境
    Symbol:
      概念:ES6中的添加了一种原始数据类型symbol(已有的原始数据类型:String, Number, boolean, null, undefined, 对象)
      特点:
        1、Symbol属性对应的值是唯一的,解决命名冲突问题
        2、Symbol值不能与其他数据进行计算,包括同字符串拼串
        3、for in, for of遍历时不会遍历symbol属性。
      使用:
        1、调用Symbol函数得到symbol值
          let symbol = Symbol();
          let obj = {};
          obj[symbol] = 'hello';
        2、传参标识
          let symbol = Symbol('one');
          let symbol2 = Symbol('two');
          console.log(symbol);// Symbol('one')
          console.log(symbol2);// Symbol('two')
        3、内置Symbol值
          * 除了定义自己使用的Symbol值以外,ES6还提供了11个内置的Symbol值,指向语言内部使用的方法。
          - Symbol.iterator
           * 对象的Symbol.iterator属性,指向该对象的默认遍历器方法(后边讲)
-->
<script>
    //创建symbol属性值
    let symbol=Symbol();
    console.log(symbol);
    let obj={username:'kobe',age:39};
    obj[symbol]='hello';
    console.log(obj);

    let symbol2=Symbol('one');
    let symbol3=Symbol('two');
    console.log(symbol2===symbol3);
    console.log(symbol2,symbol3)

    //可以去定义常量
    const Person_key=Symbol('person_key');
    console.log(Person_key);

    const myIterable={};
    myIterable[Symbol.iterator]=function*(){
        yield 1;
        yield 2;
        yield 3;
    };
   console.log([...myIterable])
</script>

 

 

 

13.Iterator对象

 

<!--
 概念: iterator是一种接口机制,为各种不同的数据结构提供统一的访问机制
    作用:
      1、为各种数据结构,提供一个统一的、简便的访问接口;
      2、使得数据结构的成员能够按某种次序排列
      3、ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费。
    工作原理:
      - 创建一个指针对象(遍历器对象),指向数据结构的起始位置。
      - 第一次调用next方法,指针自动指向数据结构的第一个成员
      - 接下来不断调用next方法,指针会一直往后移动,直到指向最后一个成员
      - 每调用next方法返回的是一个包含value和done的对象,{value: 当前成员的值,done: 布尔值}
        * value表示当前成员的值,done对应的布尔值表示当前的数据的结构是否遍历结束。
        * 当遍历结束的时候返回的value值是undefined,done值为false
    原生具备iterator接口的数据(可用for of遍历)
      1、Array
      2、arguments
      3、set容器
      4、map容器
      5、String
      。。。
-->
<script>
    //模拟指针对象(遍历器对象)
    function myIterator(arr){//iterator接口
        let nextIndex=0;//记录指针的位置
        return {//遍历器对象
            next:function(){
                return nextIndex<arr.length?{value:arr[nextIndex++],done:false}:{value:undefined,done:false}

                //return {value:arr[nextIndex++],done:false}
            }
        }
    }
    let arr=[1,4,65,'abc'];
    let iteratorObj=myIterator(arr);
    console.log(iteratorObj.next())
    console.log(iteratorObj.next())
    console.log(iteratorObj.next())
    console.log(iteratorObj.next())
    console.log(iteratorObj.next())
    console.log(iteratorObj.next())
    //将Iterator接口部署到指定的数据类型上,可以使用for of 去循环遍历
    //数组,字符串,arguments,set容器。map容器
    for (let i of arr){
        console.log(i)
    }
    let str ='abcdef';
    for(let i of str){
        console.log(i)
    }
    function fun(){
        for(let i of arguments){
            console.log(i);
        }
    }
    fun(1,4,5,'abc')
//等同于在指定的数据内结构上部署了Iterator接口
//当使用for of 去遍历某一个数据结构的时候,首先去找symbol.iterator,找到了就去遍历,没有找到的话不能遍历 xxx is not iterable
    let targetData={
        [Symbol.iterator]:function(){
             let nextIndex=0;//记录指针的位置
        return {//遍历器对象
            next:function(){
                return nextIndex<this.length?{value:this[nextIndex++],done:false}:{value:undefined,done:false}
                //return {value:arr[nextIndex++],done:false}
            }}
        }
    }
//使用三点运算符,结构赋值,默认去调用iteartor接口
    let arr2=[1,6]
    let arr3=[2,3,4,5]
    arr2=[1,...arr3,6]
    console.log(arr2)
    let [a,b]=arr2
    console.log(a,b)
</script>

 

14.generator函数

<!--
Generator函数
    概念:
      1、ES6提供的解决异步编程的方案之一
      2、Generator函数是一个状态机,内部封装了不同状态的数据,
      3、用来生成遍历器对象
      4、可暂停函数(惰性求值), yield可暂停,next方法可启动。每次返回的是yield后的表达式结果
    特点:
      1、function 与函数名之间有一个星号
      2、内部用yield表达式来定义不同的状态
      例如:
        function* generatorExample(){
          let result = yield 'hello';  // 状态值为hello
          yield 'generator'; // 状态值为generator
        }
      3、generator函数返回的是指针对象(接11章节里iterator),而不会执行函数内部逻辑
      4、调用next方法函数内部逻辑开始执行,遇到yield表达式停止,返回{value: yield后的表达式结果/undefined, done: false/true}
      5、再次调用next方法会从上一次停止时的yield处开始,直到最后
      6、yield语句返回结果通常为undefined, 当调用next方法时传参内容会作为启动时yield语句的返回值。
-->
<script src="./js/jquery.js"></script>
<script>
    function *myGenerator(){
        console.log('开始执行')
       let result= yield 'hello';
        console.log(result)
        console.log('暂停后,再次执行')
        yield 'generator';
        console.log('遍历完毕,结束');
        return "返回结果"
    }
   let MG= myGenerator();//返回的指针对象
    console.log(MG)
    console.log(MG.next());
    console.log(MG.next('qqq'));
    console.log(MG.next());
    //对象的symbol.iterator属性 指向遍历器对象
    let obj={username:'kobe',age:39};
    obj[Symbol.iterator]=function *myTest(){
        yield 1
        yield 2
        yield 3
    }
    for (let i of obj){
        console.log(i)
    }

     // 对象的symbol.iterator属性  指向遍历器对象


    // 案例练习
    /*
    * 需求:
    * 1、发送ajax请求获取新闻内容
    * 2、新闻内容获取成功后再次发送请求,获取对应的新闻评论内容
    * 3、新闻内容获取失败则不需要再次发送请求。
    *
    * */

    function getNews(url){
        $.get(url,function(data){
            console.log(data)
            let url='http://localhost:3000'+data.commentsUrl;
            SX.next(url);
        })
    }
    function *sendXml(){
        let url=yield   getNews('http://localhost:3000/news?id=2')
        yield getNews(url)
    }
    //获取遍历器对象
    let SX=sendXml();
    SX.next();

</script>

 

15.async函数

 

<!--
async函数(源自ES2017)
  概念: 真正意义上去解决异步回调的问题,同步流程表达异步操作
  本质: Generator的语法糖
  语法:
      async function foo(){
        await 异步操作;
        await 异步操作;
      }
  特点:
    1、不需要像Generator去调用next方法,遇到await等待,当前的异步操作完成就往下执行
    2、返回的总是Promise对象,可以用then方法进行下一步操作
    3、async取代Generator函数的星号*,await取代Generator的yield
    4、语意上更为明确,使用简单,经临床验证,暂时没有任何副作用
-->

<script>
    /*
    //async 基本使用
    async function foo(){
        return new Promise(resolve=>{
            // setTimeout(function(){
            //     resolve();
            // },2000)
            setTimeout(resolve,2000);
        })
    }
    async function test(){
        console.log('开始执行',new Date().toTimeString());
        await foo();
        console.log('执行完毕',new Date().toTimeString());
    }
    test();
     */
    /*
    //async 里await返回值
    function test2(){
        return 'xxxx'
    }
    async function asyncPrint(){
        // let result=await test2()
        let result=await Promise.resolve('promise');
        console.log(result)
        result=await Promise.reject('失败了.....')
        console.log(result)
    }
    asyncPrint();
*/
    //获取新闻内容
    async function getNews(url){
        return new Promise((resolve,reject)=>{
            $.ajax({
            method:'GET',
            url,
            success:data=>resolve(data),
            error:error=>resolve(false)
            // success:function(data){
            //     resolve();
            // },
            // error:function(error){
            //     reject();
            // }
        })
        })
    }
    async function sendXml(){
       let result= await getNews('http://localhost:3000/news?id=2');
       console.log(result)
        if (!result){alert('暂时没有新闻推送...');return;}
        result=await getNews('http://localhost:3000'+result.commentsUrl)
        console.log(result)
    }
    sendXml()

</script>

 

 

 

16.class

 

<!--
1. 通过class定义类/实现类的继承
2. 在类中通过constructor定义构造方法
3. 通过new来创建类的实例
4. 通过extends来实现类的继承
5. 通过super调用父类的构造方法
6. 重写从父类中继承的一般方法
-->

<script>
    /*
    function Person(name,age){
        this.name=name;
        this.age=age;
    }
    let person=new Person('kobe',39);
    console.log(person)
    */
    //定义一个人物的类
    class Person{
         //类的构造方法
        constructor(name,age){
            this.name=name;
            this.age=age;
        }
        //类的一般方法
        showName(){
            console.log('调用父类的方法')
            console.log(this.name,this.age)
        }
    }
    let person =new Person('kobe',39);
    console.log(person);
    person.showName();
    //子类
    class StarPerson extends Person{
        constructor(name,age,salary){
            super(name,age);//调用父类的构造方法
            this.salary=salary;
        }
        //父类方法重写
        showName(){
            console.log('调用子类的方法')
            console.log(this.name,this.age,this.salary)
        }
    }
    let p1=new StarPerson('wade',36,10000000);
    console.log(p1);
    p1.showName()
</script>

 

17.数字进制

 

<!--
1. 二进制与八进制数值表示法: 二进制用0b, 八进制用0o
2. Number.isFinite(i) : 判断是否是有限大的数
3. Number.isNaN(i) : 判断是否是NaN
4. Number.isInteger(i) : 判断是否是整数
5. Number.parseInt(str) : 将字符串转换为对应的数值
6. Math.trunc(i) : 直接去除小数部分

1. includes(str) : 判断是否包含指定的字符串
2. startsWith(str) : 判断是否以指定字符串开头
3. endsWith(str) : 判断是否以指定字符串结尾
4. repeat(count) : 重复指定次数

-->
<script>

    console.log(0b1010);//10
    console.log(0o56);//46
    console.log(Number.isFinite(Infinity));

    console.log(Number.isNaN(NaN));

    console.log(Number.isInteger(123.12));
    console.log(Number.isInteger(123.0));

    console.log(Number.parseInt('123abc123'));
    console.log(Number.parseInt('a123sd123'));

    console.log(Math.trunc(123.123));

    let str='abcde'
    console.log(str.includes('a'))
    console.log(str.startsWith('a'))
    console.log(str.endsWith('e'))
    console.log(str.repeat(2))

</script>

 

 

 

18.数组扩展

<!--

1. Array.from(v) : 将伪数组对象或可遍历对象转换为真数组
2. Array.of(v1, v2, v3) : 将一系列值转换成数组
3. find(function(value, index, arr){return true}) : 找出第一个满足条件返回true的元素
4. findIndex(function(value, index, arr){return true}) : 找出第一个满足条件返回true的元素下标

-->
<h1>你好,世界!</h1>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>

<script>
    let btns=document.getElementsByTagName('button');
    Array.from(btns).forEach(function(item,index){
        console.log(item)
    })
    let arr=Array.of(1,4,'aba',true);
    console.log(arr)

    let arr2=[2,3,4,2,5,7,3,6]
    let result=arr2.findIndex(function(item,index){
        return item>4;
    })
    console.log(result)

</script>

 

 

 

19.对象扩展

 

<!--
1. Object.is(v1, v2)
  * 判断2个数据是否完全相等
2. Object.assign(target, source1, source2..)
  * 将源对象的属性复制到目标对象上
3. 直接操作 __proto__ 属性
  let obj2 = {};
  obj2.__proto__ = obj1;
-->

<script>
    console.log(0==-0);//true
    console.log(NaN==NaN);//false
    console.log(Object.is(0,-0));//false
    console.log(Object.is(NaN,NaN));//true

    let obj={};
    let obj1={username:'anverson',age:42};
    let obj2={sex:''};
    Object.assign(obj,obj1,obj2);
    console.log(obj);

</script>

20.对象拷贝

 

<!--
1、数据类型:
    * 数据分为基本的数据类型(String, Number, boolean, Null, Undefined)和对象数据类型
    - 基本数据类型:
      特点: 存储的是该对象的实际数据
    - 对象数据类型:
      特点: 存储的是该对象在栈中引用,真实的数据存放在堆内存里
  2、复制数据
    - 基本数据类型存放的就是实际的数据,可直接复制
      let number2 = 2;
      let number1 = number2;
    - 克隆数据:对象/数组
      1、区别: 浅拷贝/深度拷贝
         判断: 拷贝是否产生了新的数据还是拷贝的是数据的引用
         知识点:对象数据存放的是对象在栈内存的引用,直接复制的是对象的引用
         let obj = {username: 'kobe'}
         let obj1 = obj; // obj1 复制了obj在栈内存的引用
      2、常用的拷贝技术
        1). arr.concat(): 数组浅拷贝
        2). arr.slice(): 数组浅拷贝
        3). JSON.parse(JSON.stringify(arr/obj)): 数组或对象深拷贝, 但不能处理函数数据
        4). 浅拷贝包含函数数据的对象/数组
        5). 深拷贝包含函数数据的对象/数组
-->

<script>
    /*
    //不会影响元数据
    let str='abcd';
    let str2=str;
    console.log(str2);
    str2='';
    console.log(str);
    let bool1=true;
    let bool2=bool1;
    bool2=false;
    console.log(bool1);

    let obj={username:'kobe',age:39};
    let obj1=obj;
    console.log(obj1);
    obj1.username='wade';
    console.log(obj.username);

    //拷贝数组/对象 没有生成新的数据而是复制了一份引用。
    let arr=[1,4,{username:'kobe',age:39}];
    let arr2=arr;
    arr[0]='abcd';
    console.log(arr,arr2);
    */
    /*
    *拷贝数据:
    *   基本数据类型:
    *       拷贝后会生成一份新的数据,修改拷贝以后的数据不会影响元数据
    *   对象/数组
    *       拷贝后不会生成新的数据,而是拷贝是引用。修改拷贝以后的数据会影响原来的数据
    *   拷贝数据的方法
    * 1.直接赋值给一个变量 //浅拷贝
    * 2.Object.assign() //浅拷贝
    * 3.Array.prototype.concat()//浅拷贝
    * 4.Array.prototype.slice()//浅拷贝
    * 5.JSON.parse(JSON.stringify())//深拷贝(深度克隆),拷贝的数据里不能有函数 ,处理不了
    * 浅拷贝(对象/数组):
    *   特点:拷贝的引用,修改拷贝以后的数据会影响原数据
    * 深拷贝(深度克隆)
    *   特点:拷贝的时候生成新数据,修改拷贝以后的数据不会影响原数据

    * */
    /*
    let obj={username:'kobe'};

    let obj2=Object.assign(obj);
    console.log(obj2);//{username: "kobe"}
    obj2.username='wade';
    console.log(obj);//{username: "wade"}

    let arr=[1,3,{username:'kobe'}]
    //let testArr=[2,4]
    let arr2=arr.concat();

    console.log(arr2);
    arr2[2].username='wade';
    console.log(arr);
    let arr3=arr.slice();
    arr3[2].username='anverson';
    console.log(arr)
    console.log('--------');
    let arr4=JSON.parse(JSON.stringify(arr));
    console.log(arr4);
    arr4[2].username='duncan';
    console.log(arr,arr4);
*/
    /*
    * 思考:
    *   如何实现深度拷贝(克隆)
    *   拷贝的数据里面由对象/数组
    *   拷贝的数据里不能有对象/数组
    *   即使有对象/数组可以继续遍历对象、数组拿到里边每一项值,一直到拿到是基本数据类型,
    *   然后再去复制,就是深度拷贝
    * */
    /*
    * 如何判断数据类型:arr--->Array null-->Null
    * 1.typeof返回的数据类型:String,Number,Boolean,Undefined,Object,Function
    * 2.Object.prototype.toString.call()
    * */
    let result='abcd';
    result=null;
    // result=[1,2];
    //console.log(Object.prototype.toString.call(result).slice(8,-1))

    //for in 循环 对象(属性名) 数组(下标)
    let obj={username:'kobe',age:39};
    for(let i in obj){
        console.log(i)
    }
    let arr=[1,3,'abc']
    for(let i in arr){
        console.log(i)
    }
    //定义检测数据类型的功能函数
    function checkedType(target){
        return Object.prototype.toString.call(target).slice(8,-1)
    }
    //实现深度克隆-->对象/数组
    function clone(target){
        //判断拷贝的数据类型
        //初始化变量result 成为最终克隆的数据
        let result,targetType=checkedType(target);
        if (targetType==='Object'){
            result={};
        }else if(targetType==='Array'){
            result=[];
        }else{
            return target;
        }
        //遍历目标数据
        for(let i in target){
            //获取遍历数据结构的每一项值;
            let value=target[i];
            //判断目标结构里的每一项值是否存在对象/数组
            if(checkedType(value)==='Object'||checkedType(value)==='Array'){//对象/数组里嵌套了对象/数组
                //继续遍历获取到的value值
                result[i]=clone(value)
            }else{//获取到的value值是基本的数据类型或者是函数
                result[i]=value ;
            }
        }
        return result;
    }
    let arr3=[1,2,{username:'kobe'}]
    let arr4=clone(arr3);
    console.log(arr4);
    arr4[2].username='wade';
    console.log(arr3,arr4);

    let obj3={username:'kobe',age:39};
    let obj4=clone(obj3);
    console.log(obj4)
    obj4.username='wade';
    console.log(arr4,arr3)

</script>

 

 

 

21.set和map对象

 

<!--
1. Set容器 : 无序不可重复的多个value的集合体
  * Set()
  * Set(array)
  * add(value)
  * delete(value)
  * has(value)
  * clear()
  * size
2. Map容器 : 无序的 key不重复的多个key-value的集合体
  * Map()
  * Map(array)
  * set(key, value)//添加
  * get(key)
  * delete(key)
  * has(key)
  * clear()
  * size
-->

<script>
    /*
    let set=new Set([1,2,3,4,3,2,5,3,6]);
    console.log(set)
    set.add(7)
    console.log(set.size,set)
    console.log(set.has(8))//false
    console.log(set.has(7))//true
*/
    let map=new Map([['aaa','username1'],[39,'age']]);
    console.log(map)
    map.set(77,'hahah')
    console.log(map)
</script>

 

 

 

22.for,of循环

 

<!--

for(let value of target){}循环遍历
  1. 遍历数组
  2. 遍历Set
  3. 遍历Map
  4. 遍历字符串
  5. 遍历伪数组

-->

<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<script>
    // let set=new Set([1,2,3,5,4,6,7]);
    // for(let i of set){
    //     console.log(i)
    // }
    let arr=[1,2,3,2,4,5,3];
    let arr1=arr;
    arr=[];
    let set=new Set(arr1)
    for(let i of set){
        arr.push(i)
    }
    console.log(arr)


</script>

 

 

 

23.遍历伪数组

<!--
1. 指数运算符(幂): **
2. Array.prototype.includes(value) : 判断数组中是否包含指定value

-->

<script>
    console.log(3**3)
    let arr=[1,3,4,'abc'];
    //console.log(arr.includes('a'));
    console.log(Array.prototype.includes('a'))


</script>

 

posted @ 2022-08-05 08:01  布衣梦蝶1978  阅读(103)  评论(0编辑  收藏  举报