Js高级 数组方法--构造函数

208 阅读6分钟

JS高级

箭头函数

ES6中新增定义函数方式

( )=>
const fn = ( )=>{ }

1650643279139

1650643298205

箭头函数以小括号开头,小括号里面放置形参的地方 小括号后面要写一个箭头 这是固定语法 小箭头后面 要写一个大括号 大括号 依然表示函数体 这就是定义箭头函数的基本方式

箭头函数没有名字 要如何调用呢?

通常我们都会讲箭头函数赋值给一个变量 变量名字就是函数名字 ,通过变量名字来调用函数就可以了

函数体中只有一句代码,且代码的执行结果就是返回值,可以省略大括号 、不能写return

 <SCRipt>
    function sum(num1,num2){
        return num1 + num2
    }
    </SCRipt>    //此为传统函数定义
    
    <SCRipt>
    箭头函数定义则为:
     const sum = (num1, num2) => num1 + num2;
     const result = sum(10,20);
     condole.log(result);
     </SCRipt>

使用传统的函数定义方式为上面

箭头函数为 下面 num1 num2 为函数的形参

在箭头函数中 如果形参只有一个 形藏外侧的小括号也是可省略的

  <script>
      const fn = v => {
         alert(v);
      }
      fn(20);
   </script>

箭头函数有几个使用注意点。

(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象,箭头函数继承而来的this指向永远不变。

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

(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。

(4)不可以使用yield命令,因此箭头函数不能用作Generator函数。

箭头函数都是匿名函数,ES5匿名函数的语法糖,并且没有自己的this,arguments,super或new.target。

它的优点是:

(1)简洁的语法。

(2)隐式返回,如 下面的代码可以去掉return,代码一到一行,减少代码量numbers.map((number)=>number*2)

(3)解决了this的指向问题,原生的写法this指向的是调用者,箭头函数this绑定的是定义时的那个对象。如果有对象嵌套的情况下,则this绑定到最近的一层对象上

它的缺点是:

(1)做为构造函数的时候不能使用箭头函数

(2)真正需要this的时候如给元素绑定click事件的时候,执行的回调函数不能使用箭头函数。

(3)我们需要使用arguments对象的时候不能使箭头函数。箭头函数中没有arguments对象。

(4)对象的方法也不可以使用箭头函数

1650649210000

常用数组方法

forEach( ) 方法

forEach () 数组每一个元素都会执行一次回调函数 =类似以前的for forEach 高阶函数 (可以接受一个形参-函数)

for循环可以通过break来打断 forEacah不能通过break 打断

 <script>
    const arr=['a','b','c'];
    //分别打印他们
    // arr.forEach(function(value,index){
    //     console.log(`值是${value} 下标是${index}`);
    // });

    // arr.forEach((value,index)=>console.log(`值是${value} 下标是${index}`))
    arr.forEach(value=>console.log(`值是${value}`))
        
    </script>

注意:forEach() 对于空数组是不会执行回调函数的。

利与弊:foreach虽然是for循环的简化版本,但是并不是说foreach就比for更好用,foreach适用于循环次数未知,

或者计算循环次数比较麻烦情况下使用效率更高,但是更为复杂的一些循环还是需要用到for循环效率更高。

 foreach不能对数组或集合进行修改(添加删除操作),如果想要修改就要用for循环。

map( )方法

  <script>
        map();
    function map(){
        //map 根据原来的数组 来返回新的数组
        //也会循环数组 在循环的回调函数中 可以返回新的数据 组成新的数组
        const arr = ['a','b','c'];
        //要求返回['我的字母是a','我的字母是b','我的字母是c']
        const newArr =arr.map(value=>`我的字母是${value}`); //1,1,1  return了什么 就会被装到数组的每一个元素当中
        console.log(newArr);


        const list =[9,99,999];  //要求返回10 100 1000
        const newList =list.map(value=>value+1)
        console.log(newList);
        

        const objArr = [{name:'悟空'},{name:'八戒'},];
        const newObjArr = objArr.map(value=>{
            value.color='red';
            return value
           
        })
        console.log(newObjArr);


        //数组拼接成字符串数组 转成字符串 插到网页上
       
        const text =['刘德华','张学友','胡歌']
        const newText =text.map(value=>`<div>${value}</div>`)
        console.log(newText);
        //把它转成字符串
        const html = newText.join('');
        console.log(html);
        document.body.innerHTML=html;
    }
    </script>

04-箭头函数返回对象

  <script>
        
        const arr = ['a','b','c'];
        //返回 [{name:'a',name:'b',name:'c'}]
        const newArr = arr.map(value=>
        {return{name:value}});
        console.log(newArr);
        //次为正确
        

        //{} 这个大括号 就是对象(只是我们的认为  浏览器认为这是块级空间)
        //如果 一定要在箭头函数中想要通过省略  return的方式 来返回对象,请一定加上小括号
        const func7 = (num)=>({a:123}); //右边加了小括号 表示想要返回 小括号里面的数据return {a:123};
        const func8 = (num)=>{a:123}; //undefined

        console.log(func7()); //{a:123};
        console.log(func8());//undefined
    </script>

every ( )

 <script>
        every();
        function every(){
        const arr = [1,2,3,4];
        //判断数组中的每一个元素,是不是都小于5 如果是 返回true

        //every 当中的函数,要求每一个都return 了true  最后every 的返回值才是true
        const result = arr.every((value)=>{
            if(value<5){
                return true;
            }else{
                return false;
            }
        });
        console.log(result);
    }
    // every:
    // 会返回true 或者false
    // 要求数组中每一个元素都符合条件,every 得到true
    // 如果空的数组调用了every   得到结果 也是 true
    </script>

06-商品单选全选案例

<html>
  <head lang="en">
    <meta charset="UTF-8" />
    <title>08-全选和不全选-every</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      table {
        border-collapse: collapse;
        border-spacing: 0;
        border: 1px solid #c0c0c0;
        width: 500px;
        margin: 100px auto;
        text-align: center;
      }

      th {
        background-color: #09c;
        font: bold 16px '微软雅黑';
        color: #fff;
        height: 24px;
      }

      td {
        border: 1px solid #d0d0d0;
        color: #404060;
        padding: 10px;
      }

      .allCheck {
        width: 80px;
      }
    </style>
  </head>

  <body>
    <table>
      <tr>
        <th class="allCheck">
          <input type="checkbox" name="" id="checkAll" />
          <span class="all">全选</span>
        </th>
        <th>商品</th>
        <th>商家</th>
        <th>价格</th>
      </tr>
      <tr>
        <td>
          <input type="checkbox" name="check" class="ck" />
        </td>
        <td>小米手机</td>
        <td>小米</td>
        <td>¥1999</td>
      </tr>
      <tr>
        <td>
          <input type="checkbox" name="check" class="ck" />
        </td>
        <td>小米净水器</td>
        <td>小米</td>
        <td>¥4999</td>
      </tr>
      <tr>
        <td>
          <input type="checkbox" name="check" class="ck" />
        </td>
        <td>小米电视</td>
        <td>小米</td>
        <td>¥5999</td>
      </tr>
    </table>
  </body>
    <script>
          let checkAll = document.querySelector('#checkAll');

let checkboxList = document.querySelectorAll('.ck'); // checkboxList 现在是一个伪数组
checkboxList =[...checkboxList];  //伪数组 转为真数组



// 商品全选点击 功能
checkAll.addEventListener('click', function () {
  for (let index = 0; index < checkboxList.length; index++) {
    checkboxList[index].checked = checkAll.checked;
  }
});

// // 给每一个商品绑定点击事件
for (let index = 0; index < checkboxList.length; index++) {
  checkboxList[index].addEventListener('click', function () {
    // 判断是否达到了全选 条件
    // 判断每一个小小的复选框的选中状态 如果都是true,那么就全选
   let checked = checkboxList.every((value)=>{
       if(value.checked===true){
           return true;
       }else{
           return false;
       }
   });
     checkAll.checked = checked;
   
  });
}

// 两个知识
// 1.伪数组转真正的数组  let newArr=[...伪数组];
// 2.every 要求数组的每一个元素符号要求  every才返回true
//   使用场景,商品全选=》 每一个小商品都选中 全选才勾选
</script>

07-伪数组转真数组

<body>
    <ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
    <script>
        const lis = document.querySelectorAll('li')
        //  console.log(lis.every);  07-伪数组转真数组.html:19 undefined   伪数组

        // const liList = [].concat(lis); //concat 合并数组 把空数组和伪数组合并=》返回新数组
        // console.log(liList.every);

        //最简单的伪数组转真数组办法
        // const liList = [...伪数组]
        const liList = [...lis];
    </script>
</body>

some( )方法

  <script>
        some();
        function some(){
            // 检测数组,其中只要有一个元素符合条件,some返回true (every要求每一个都符合)
            const arr = [1,2,3,4,5,6,7,8];
            //这个数组有没有大于8的
            const result = arr.some((value)=>value>8);
            console.log(result);
        }
        /*
        every 和some 一起学习
        every要求全部都符合
        some 最少有一个符合即可*/ 
    </script>

filter( ) 方法

 <script>
        filter();
        function filter(){
            //过滤 ,过滤出满足条件的数据 =》新的数组
            const arr = [1,2,3,4,5,6,7]
            const newArr = arr.filter((value)=>{
                //如果return了true 表示当前的value你想要
                if(value%2!==0){    //value  1 2 3 4 5 6 7
                    return true;    //value%2!==0 [1,3,5,7]
                }else{
                    return false;
                }
            })
            console.log(newArr);
        }
    </script>

构造函数

构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋值初始化,它总与new一起使用我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。

在js中,使用构造函数时 要注意以下两点:

1.构造函数用于创建某一类对象,其首字母要大写

2.构造函数要和new一起使用才有意义

在ES6之前,对象不是基于类创建的。而是用一种称为构造函数的特殊函数定义对象和他们的特征

创建对象可以通过以下三种 方式

  1. 对象字面量

  2. new Object( )

  3. 自定义构造函数

     <script>
         //1.利用new Object()   创建对象
         const obj1 = new Object();
    
         //2.利用 对象字面量创建对象
         const obj2 = {};
    
         //3.利用构造函数创建对象
         function Star(name,age){
             this.name = name;     //属性
             this.age = age;       //属性 
             this.sing =function(){      //方法
                 console.log('我会唱歌');
             }
         }
         const hu = new Star('胡歌',38);
         console.log(hu);
         const ou = new Star('欧豪',28);
         console.log(ou);
         ou.sing();
    
         //sing 为方法
       </script>
    

new在执行时会做的四件事

  1. 在内存中创建一个新的空对象
  2. 让this指向这个新的对象
  3. 执行构造函数里面的代码,给这个新对象添加属性和方法
  4. 返回这个新对象(所以构造函数里面不需要retum)

JavaScript的构造函数中可以添加一些成员,可以在构造函数本身上添加,也可以在构造函数的内部添加。通过这两个方式添加成员,就分别称为静态成员和实例成员。

   <script>
    //构造函数中的属性和方法我们称为成员,成员可以添加
     function Star(name,age){
         this.name = name;       //name属性
         this.age = age;         //age属性
         this.sing =function(){
             console.log('我会唱歌');    //sing方法
         }
     }
     const hu = new Star('胡歌',38);
    //1.实例成员 就是构造函数内部通过this添加的成员 name age sing 就是实例成员
    //实施成员只能通过实例化对象来访问     
     console.log(hu.name);
     hu.sing();
    //   错误    console.log(Str.name);  //不可以通过构造函数来访问实例成员

    //  2.静态成员  在构造函数本身上添加的成员  sex就是静态成员
     Star.sex = '男';
    //静态成员只能通过构造函数来访问
    console.log(Star.sex);
    //   错误  console.log(hu.sex);    //不能通过对象来访问
   </script>
  • 静态成员:在构造函数本身上添加的成员称为静态成员,只能由构造函数本身来访问
  • 实例成员:在构造函数内部创建的对象成员成为你实例成员,只能由实例化的对象来访问

构造函数的问题

构造函数方法很好用 但是存在浪费内存问题。

上面的name 和age 是简单数据类型 还好说 但是里面的sing方法是个函数 而函数又是个复杂数据类型

当创建胡歌个对象的时候 会再单独再开一个内存空间来存放这个复杂数据类型 也就是把这个函数放进去

1650703688856

所以我们希望所有的对象使用同一个函数,这样就比较节省空间

构造函数原型

构造函数通过原型的分配的函数是所有对象共享的。

JavaScrip规定,每一个构造函数都有一个prototype属性,指向另一个对.注意这个prototype就是一个对象,这个对象的所有有属性和方法,都会被构造函数有拥有。

我们可以把那些不变的方法,直接用prototype对象上,这样所有对象的实例就可以共享这些方法。

构造函数的 原型对象 追加的方法

   <script>
    //构造函数中的问题
     function Star(name,age){
         this.name = name;       //name属性
         this.age = age;         //age属性
     }

    Star.prototype.sing = function(){
        console.log('我会唱歌');
    }
    const hu = new Star('胡歌',38);
    const nie = new Star('聂成林',23)    
     console.log(hu.name);
     hu.sing();
     
     console.log(nie.name);
     nie.sing();
   
   </script>

1650714468654

???

1.原型是什么?

一个对象,我们也称为prototype为原型对象

2.原型的作用是什么 ?

共享方法

注意:一般情况下,我们的公共属性定义到构造函数里面,公共的方法我们放到原型对象身上

对象原型 proto

对象都会有一个属性 proto 指向构造函数的prototype原型对象,之所以我们对象可以使用构造函数prototype原型对象的属性和方法,就是要问对象有 proto 原型的存在。

  • _proto_对象原型和原型对象prototype是等价的
  • proto 对象圆的意义就在于 为对象的查找机制提供一个方向,或者说一条线路,但是它是一个非标准,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象prototype

1650716448370

小结:原型对象 ---构造函数 一般情况

构造函数内只放属性 name age color height

对应原型上 都是放 方法==》就是函数 复杂类型

![image (md.zbztb.cn/uploads/494… (1).png)

面向对象的初体验1

 <script>
        function MyImg(src){
            const img = document.createElement('img');
            img.src = src;
            img.style.width='250px'
            document.body.appendChild(img);
           
        }
        const img1 = new MyImg('./imgs/1.webp')
        const img2 = new MyImg('./imgs/2.jpg')
        
       </script>

1650725524380

面向对象的初体验2

  <script>
        function MyImg(src){
            const img = document.createElement('img');
            img.src = src;
            img.style.width='250px'
            document.body.appendChild(img);

            this.dom = img;  //把图片dom元素 添加到 this 对象的一个属性 dom属性
           
        }
        //原型
        MyImg.prototype.scale =function(){
            //图片放大缩小的本质就是给图片的dom元素 添加一个class(类)
            // console.log(this.dom);
            this.dom.classList.add('scale')
        }

        const img1 = new MyImg('./imgs/1.webp')

        const but = document.querySelector('button')
        but.addEventListener('click',function(){
            img1.scale();      //img1 调用了scale这个方法
        })
        
       </script>

当地

面向对象的初体验3

<body>
    <button></button>
    <script>
     function Div(text){
        const div =document.createElement('div');
        div.innerText=text;
        document.body.appendChild(div);
        this.dom = div;
        
     }
     Div.prototype.changeColor = function(color,size){
        // this.dom  等于上述div
         this.dom.style.backgroundColor = color;
         this.dom.style.fontSize =size;
     }

     const divObj1 = new Div('这是个普通的div1')
     const divObj2 = new Div('这是个普通的div2')
     const divObj3 = new Div('这是个普通的div3')
     const but =document.querySelector('button');
     but.addEventListener('click',function(){
        divObj1.changeColor('red','20px')
        divObj2.changeColor('aqua','35px')
        divObj3.changeColor('yellow','50px')
     })
    </script>
</body>

面向对象的初体验4

<script>
      // 需求:点击哪张图片,哪张图片变成边款圆角为50%
      //构造函数
      function MyImg(src) {
        const img = document.createElement("img");

        img.src = src;
        img.style.width = "370px";
        img.style.transition = "2.3s";

        document.body.appendChild(img);
        this.dom = img;

        //给图片绑定点击事件
        img.addEventListener("click", function () {
          img.style.borderRadius = "50%";
        });
      }
      const img1 = new MyImg(
        "./imgs/83cc8615214a62c1c3f3a67b9c5fee32--2780999425.jpg"
      );
      const img2 = new MyImg("./imgs/2.jpg");
      const img3 = new MyImg("./imgs/新建文件夹IMG_0131.JPG");
    </script>

当地.gif

深夜听着歌 写着笔记 突然就想家了

望我们不忘初心

砥砺前行