当前位置: 首页 > news >正文

JavaScript高级,ES6 笔记 第三天

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

这里创造了两个实例,对于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>

相关文章:

  • 【雷达图】R语言绘制雷达图(ggradar),NBA季后赛数据为例
  • 机器学习笔记 - 在QT/PyTorch/C++ 中加载 TORCHSCRIPT 模型
  • redis 技术分享
  • 怎么让面试官喜欢你?
  • 深度学习模型理解-CNN-手写数据字代码
  • C# ZBar解码测试(QRCode、一维码条码)并记录里面隐藏的坑
  • 【技术美术图形部分】图形渲染管线3.0-光栅化和像素处理阶段
  • css:一个容器(页面),里面有两个div左右摆放并且高度和容器高度一致,左div不会随着页面左右伸缩而变化,右div随页面左右伸缩宽度自适应(手写)
  • Kubernetes 1.25 集群搭建
  • 【每周CV论文推荐】GAN在医学图像生成与增强中的典型应用
  • python毕业设计项目源码选题(16)跳蚤市场二手物品交易系统毕业设计毕设作品开题报告开题答辩PPT
  • C# 连接 SqlServer 数据库
  • 【408计算机组成原理】—进位计数制(二)
  • 拆解一下汽车电子软件开发工具链
  • 2021年华中杯数学建模挑战赛B题技术问答社区重复问题识别求解全过程文档及程序
  • 网络传输文件的问题
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • exif信息对照
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • JavaScript HTML DOM
  • java取消线程实例
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • Puppeteer:浏览器控制器
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • Python_OOP
  • Python利用正则抓取网页内容保存到本地
  • Spring Cloud Feign的两种使用姿势
  • TCP拥塞控制
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • Web标准制定过程
  • XML已死 ?
  • 前端设计模式
  • 探索 JS 中的模块化
  • 想使用 MongoDB ,你应该了解这8个方面!
  • - 转 Ext2.0 form使用实例
  • C# - 为值类型重定义相等性
  • scrapy中间件源码分析及常用中间件大全
  • 进程与线程(三)——进程/线程间通信
  • 扩展资源服务器解决oauth2 性能瓶颈
  • ​configparser --- 配置文件解析器​
  • ​ssh免密码登录设置及问题总结
  • #NOIP 2014# day.1 T2 联合权值
  • $jQuery 重写Alert样式方法
  • (附源码)ssm码农论坛 毕业设计 231126
  • (附源码)ssm学生管理系统 毕业设计 141543
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .net wcf memory gates checking failed
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .NET分布式缓存Memcached从入门到实战
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .NET使用存储过程实现对数据库的增删改查
  • .pop ----remove 删除