JavaScript高级,ES6 笔记 第三天(原型、原型对象、原型链、 constructor​编辑等)

目录

构造函数会造成内存浪费的问题

原型prototype

 自己创造对象方法

 constructor​编辑

 对象原型_proto_

原型继承

原型链

 instanceof

小案例


构造函数会造成内存浪费的问题

这里创造了两个实例,对于sing都会创造一部分内存,然而sing内部的函数是一样的,我们希望两者指向的是同一个内存区域 ,即指向同一个function();

原型prototype

    <script>
        function star(uname,age){
            this.uname = uname
            this.age = age
        }
        star.prototype.sing = function(){
            console.log(123);

        }

        let ldh = new star('ldh',55);
        let zxy = new star('zxy',67);
        ldh.sing()//123
        zxy.sing()//123
        console.log(ldh.sing == zxy.sing);//true
    </script>

也就是说将sing定义到prototype中可以使得所有对象的sing都指向同一块内存‘

公共属性写道构造函数里面

公共方法写道原型对象上

 自己创造对象方法

求最大值

        Array.prototype.max = function(){

            // return Math.max(...this)
            let max = this[0];
            for (let i = 1;i<arr.length;i++){
                if(this[i]>max){
                    max = this[i]
                }

            }
            return max;
        }

        arr = new Array(2,3,4,1,5,66,7);
        console.log(arr.max());

求和

        Array.prototype.sum = function(){
            return this.reduce((prev,item)=>prev+item,0)
        }

        arr = new Array(2,3,4,1,5,66,7);
        console.log(arr.sum());

 constructor

 也就是说可以指向原型的父辈构造函数

    function star(name){
      this.name = name;
      
    }

    console.log(star.prototype.constructor == star);//true

当给原型幅值时:

  <script>
    function star(name){
    }
    star.prototype = {
      sing:function(){
        console.log('aaa');
      },
      dance:function(){
        console.log('bbb');
      }
    }

    console.log(star.prototype.constructor == star);//false
  </script>

就不能指向构造函数了,因为对原型进行了赋值操作,故应该将constructor重新指回构造函数

  <script>
    function star(name){ 
    }
    star.prototype = {
      constructor:star,
      sing:function(){
        console.log('aaa');
      },
      dance:function(){
        console.log('bbb');
      }
    }

    console.log(star.prototype.constructor == star);//true
  </script>
</body>

 对象原型_proto_

 也就是说所有对象都有对象原型__proto__(也写作[[prototype]]),指向prototype,其是只读的。

对象原型也有constructor,指向构造函数

  <script>
    function star(name){
      
    }
    let ldh = new star()
    console.log(ldh.__proto__.constructor == star );//true
  </script>

原型继承

  <script>
    const person = {
      head: 1,
      arms: 2
    }
    function woman(){

    }

    woman.prototype = person
    woman.prototype.constructor = woman
    const red = new woman;
    console.log(red.arms);//2   
  </script>

也就是构造函数的原型继承person对象,叫做原型继承

遇到的问题

  <script>
    const person = {
      head: 1,
      arms: 2
    }
    function woman(){}
    function man(){}
    woman.prototype = person
    woman.prototype.constructor = woman
    woman.prototype.baby = function(){
      console.log('baby');
    }

    man.prototype = person
    man.prototype.constructor = man

    const red = new woman;
    console.log(red);//2

    const black = new man;
    console.log(black);
 
  </script>

主要是给woman  man构造函数都继承了person对象

然后给woman添加了一个baby方法

结果发现,red 和 black都有baby方法

原因是  woman和man的.prototype都指向了同一个地址,既person,当我改变woman.prototype时,实际上也就把person改变了

解决方法:将person换成构造函数

  <script>

    function person (){
      this.head = 1 ;
      this.arms = 2
    }
    function woman(){}
    function man(){}
    woman.prototype = new person()
    woman.prototype.constructor = woman
    woman.prototype.baby = function(){
      console.log('baby');
    }

    man.prototype = new person()
    man.prototype.constructor = man

    const red = new woman;
    console.log(red);//2

    const black = new man;
    console.log(black);

  </script>

这样就可以保证,woman和man的.prototype指向不同的地址

原型链

对于具体对象 ldh,其ldh.__proto__指向原型对象

    function person(){}
    const ldh = new person();
    console.log(ldh.__proto__ == person.prototype);//true

而原型对象也有对象原型,既person.prototype.__proto__ 存在

console.log(person.prototype.__proto__ == Object.prototype);//true

同理  ,也存在Object.prototype.__proto__,为null

console.log(Object.prototype.__proto__);//null

那么这几个__proto__连起来,就是原型链

 相当于原型链提供了一个查找的方向,可以一层一层查找方法或属性所在的位置

例如数组的map方法,其实是写在Array.prototype.map(),但是因为有原型链的存在,所以普通的数组对象也可以使用这个方法

    let sss = [123,22,33,44];
    let sae = sss.map(item=>item+3)
    console.log(sae);

 instanceof

    function person(){}
    const ldh = new person();
    console.log(ldh.__proto__ == person.prototype);//true
    console.log(Object.prototype.__proto__);//null

    console.log(ldh instanceof person);//true
    console.log(ldh instanceof Object);//true
    console.log(ldh instanceof Array);//false

小案例

目的:按下按钮弹出提示框(采用构造函数的方法来做)

 

 先给CSS

 <style>
    .modal {
      width: 300px;
      min-height: 100px;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
      border-radius: 4px;
      position: fixed;
      z-index: 999;
      left: 50%;
      top: 50%;
      transform: translate3d(-50%, -50%, 0);
      background-color: #fff;
    }

    .modal .header {
      line-height: 40px;
      padding: 0 10px;
      position: relative;
      font-size: 20px;
    }

    .modal .header i {
      font-style: normal;
      color: #999;
      position: absolute;
      right: 15px;
      top: -2px;
      cursor: pointer;
    }

    .modal .body {
      text-align: center;
      padding: 10px;
    }

    .modal .footer {
      display: flex;
      justify-content: flex-end;
      padding: 10px;
    }

    .modal .footer a {
      padding: 3px 8px;
      background: #ccc;
      text-decoration: none;
      color: #fff;
      border-radius: 2px;
      margin-right: 10px;
      font-size: 14px;
    }

    .modal .footer a.submit {
      background-color: #369;
    }
  </style>

 具体解释看代码,

<body>
  <button id="delete">删除</button>
  <button id="login">登录</button>


  <script>
    //先定义一个构造函数,表示这个提示框,里面有两个参数,即标题和内容,这个地方需要创造一个div,并按照格式写入
    function model(header = '', body = '') {
      this.header = header;
      this.body = body;
      this.box = document.createElement('div')
      this.box.className = 'model';
      this.box.innerHTML = `  <div class="modal">
    <div class="header">${this.header} <i>x</i></div>
    <div class="body">${this.body}</div>
  </div>`
    }

    //给构造函数添加关闭的方法,就是之间移除之前创造的div

    model.prototype.close = function(){
      document.body.removeChild(this.box)
    }

    //给构造函数添加打开的方法,先加判断,页面中没有提示框才能添加提示框
    //添加子节点box
    //将box中的x与close函数绑定

    model.prototype.open = function(){
      if(!document.querySelector('.model')){
        document.body.appendChild(this.box)
       this.box.querySelector('i').addEventListener('click',()=>{
        this.close()
       })
      }
    }

    //实例化


    document.querySelector('#delete').addEventListener('click',function(){
      const m = new model('温馨提示','你没有权限删除');
      m.open()
    })



  </script>
</body>

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值