javascript的一些知识(七)--构造函数,原型,原型链,类及继承

new运算符

  • 1.执行函数 2.自动创建一个空对象 3.把创建的对象指向另一个对象
  • 4.把空对象和函数的this链接起来(this指向实例化对象) 5.隐式返还this
  • 6.简化工厂模式;----->构造函数
function Tab(){
  this.name = "张三";
  /* this.hobby = function(){
    console.log("篮球");
  } */
}
  Tab.prototype.hobby = function(){
    console.log("hobby.....",this.name);//hobby.....,张三
  }
  
 //会开辟一个公共空间(原型:Tab.prototype)
let tab1 = new Tab()
console.log(tab1.name);
tab1.hobby();

/* 
1.首字符大写,属性放在构造函数里,方法放在原型里。原型本质也是一个对象
2.构造函数一部分由构造函数构成本身构成,一部分由原型构成(prototype)。且共用一个this。
3.实例化之后形成一个对象,对象也由两部分构成,一部分由对象本身构成,另一部分由由原型
构成(__proto__).
4.上面两个原型本质上是一个东西只是表现形式不同。
5.每个原型上都有一个预定义属性:constructor 指向构造函数
故:  Tab.prototype = {
        constructor:Tab, //要这样写的化必须加这个,否则会覆盖原本的constructor属性
        hobby(){
        console.log("hobby.....")
        },
}
 */

//仿写new效果
function mynew(constructor,...arg){
  let obj={},
  constructor.call(obj,...arg);
  obj.__proto__ = constructor.prototype;
  return obj;
}

拖拽

<html>
  <head>
    <style>
      .mydiv1{
        width:100px;
        height:100px;
        background:red;
        position:absolute;
      }
      
    </style>
  </head>
  <body>
    <div class="mydiv1"></div>
  </body>
  <script>
    let mydiv1 = document.querySelector(".mydiv1");
    mydiv1.onmousedown = e=>{
      let ev = e||window.event;
      let x =ev.clientX - mydiv1.offsetLeft;
      let y =ev.clientY - mydiv1.offsetTop;
      mydiv1.onmousemove = e=>{
        let ev = e||window.event;
        let xx = ev.clientX;
        let yy = ev.clientY;
        mydiv1.style.left = xx-x+"px";
        mydiv1.style.top = yy-y+"px";
      }
      document.onmouseup = function(){
        mydiv1.onmousemove = "";
      }
    }
  </script>
  
</html>

拖拽面向对象封装

<html>
  <head>
    <style>
      .mydiv1{
        width:100px;
        height:100px;
        background:red;
        position:absolute;
      }
      .mydiv2{
        width:100px;
        height:100px;
        background:blue;
        position:absolute;
        left:300;
      }
    </style>
  </head>
  <body>
    <div class="mydiv1"></div>
    <div class="mydiv2"></div>
  </body>
  <script>  
    function Drag(ele){
      this.ele = ele; //节点
      this.downFn();
    }
    Drag.prototype.downFn = function(){
      this.ele.onmousedown = e=>{
        let ev = e||window.event;
        let x =ev.clientX - this.ele.offsetLeft;
        let y =ev.clientY - this.ele.offsetTop;
        this.moveFn(x,y);
        this.upFn();
      }
    }
    Drag.prototype.moveFn = function(x,y){
      this.ele.onmousemove = e=>{
        let ev = e||window.event;
        let xx = ev.clientX;
        let yy = ev.clientY;
        this.ele.style.left = xx-x+"px";
        this.ele.style.top = yy-y+"px";
      }
    }
    Drag.prototype.upFn = function(){
      this.ele.onmouseup = ()=>{
        this.ele.onmousemove = "";
      }
    }
    
    let mydiv1 = document.querySelector(".mydiv1");
    let mydiv1 = document.querySelector(".mydiv2");
    let drag1 = new Drag(mydiv1);
    let drag1 = new Drag(mydiv2);
  </script>
  
</html>

es5普通继承

function Dad(height){
  this.name = "张三"this.age = 20;
  this.height = height;
  this.money = "$11000000";
}

function Son(height){
  Dad.call(this,height);
  //或者 Dad.apply(this,[height]);
  //或者 Dad.bind(this)(height);
}

let newSon = new Son("178cm");
console.log(newSon); 

es5原型组合继承

function Dad(height){
  this.name = "张三"this.age = 20;
  this.height = height;
  this.money = "$11000000";
}
Dad.prototype.hobby = function(){
  console.log("喜欢高尔夫");
}

function Son(height){
  Dad.call(this,height);
  //或者 Dad.apply(this,[height]);
  //或者 Dad.bind(this)(height);
}

let Link = function(){}; //通过Link空函数实例化切断了子类原型与父类原型在内存之间的引用关系
Link.prototype = Dad.prototype;
Son.prototype = new Link();
//这里预定义属性constructor覆盖了;
Son.prototype.constructor = Son;
Son.prototype.hobby = function(){
  console.log("篮球")
}

let newSon = new Son("178cm");
console.log(newSon); 

深拷贝

function deepCopy(obj){
  let newObj = Array.isArray(obj)?[]:{};
  for(let i in obj){
    if(obj.hasOwnProperty(i)){ //判断不是原型而是本身属性和方法进行深拷贝
      if(typeof obj[i]==="object"){
        if(obj[i] ===null){
          newObj[i] = null;
        }else{
           newObj[i] = deepCopy(obj[i]);
        }
      }else{
        newObj[i] = obj[i];
      }
    }
  }
  return newObj;
}

深拷贝继承

  function LimitDrag(ele){
      Drag.call(this.ele);
    }
    
   // let Link = function(){};
   // Link.prototype = Drag.prototype;
   // LimitDrag.prototype = new Link();
    LimitDrag.prototype = deepCopy(Drag.prototype);
    LimitDrag.prototype.constructor = LimitDrag;
    LimitDrag.prototype.setStyle = function(leftNum,topNum){
      leftNum = leftNum<0?0:leftNum;
      topNum = topNum<0?0:topNum;
      this.ele.style.left = leftNum + "px";
      this.ele.style.top = topNum +"px";
    }
    
    let mydiv2 = document.querySelector(".mydiv2");
    let drag2 = new LimitDrag(mydiv2);
    
    function deepCopy(obj){
      let newObj = Array.isArray(obj)?[]:{};
      for(let i in obj){
        if(obj.hasOwnProperty(i)){ //判断不是原型而是本身属性和方法进行深拷贝
          if(typeof obj[i]==="object"){
            if(obj[i] ===null){
              newObj[i] = null;
            }else{
               newObj[i] = deepCopy(obj[i]);
            }
          }else{
            newObj[i] = obj[i];
          }
        }
      }
      return newObj;
    }

原型链

  • 构造函数在查找时先在自身查找返回,再在原型中查找
  • 原型本质也是一个对象,也由自身和原型构成,像链式一样;

es6类

function Tab(){
  this.name = "张三";
}
Tab.prototype.hobby = function(){
  console.log("篮球");
}

//类 它的类型是function
class Tab{
 // static height = "178cm" //静态属性只有类Tab有关
  constructor(){ 
    this.name = "张三";
  }
  hobby(){
    console.log("篮球");
  }
}
//或者这样写
Tab.height = "178cm"; //
console.log(Tab.height); //静态属性这样取

 //动态属性与实例化对象有关
let tab1 = new Tab();


es6继承类

class Tab{
  static height = "178cm" //静态属性只有类Tab有关
  constructor(age){ 
    this.name = "张三";
    this.age = age;
  }
  hobby(){
    console.log("篮球");
  }
}

class LimitTab extends Tab{
  constructor(age){
    super(age);  //必须调用
  }
  hobby(){
    super.hobby();会将父类的逻辑拿过来
    console.log("足球")
  }
}

//静态属性打印
console.log(LimitTab.height); //178cm

let tab2 = new LimitTab(20); //参数传给age
//动态属性打印
console.log(tab2.age); //20

tab2.hobby(); //篮球 足球

限定范围拖拽(通过继承实现)

<html>
  <head>
    <style>
      .mydiv1{
        width:100px;
        height:100px;
        background:red;
        position:absolute;
      }
      .mydiv2{
        width:100px;
        height:100px;
        background:blue;
        position:absolute;
        left:300;
      }
    </style>
  </head>
  <body>
    <div class="mydiv1"></div>
    <div class="mydiv2"></div>
  </body>
  <script>  
    function Drag(ele){
      this.ele = ele; //节点
      this.downFn();
    }
    Drag.prototype.downFn = function(){
      this.ele.onmousedown = e=>{
        let ev = e||window.event;
        let x =ev.clientX - this.ele.offsetLeft;
        let y =ev.clientY - this.ele.offsetTop;
        this.moveFn(x,y);
        this.upFn();
      }
    }
    Drag.prototype.moveFn = function(x,y){
      this.ele.onmousemove = e=>{
        let ev = e||window.event;
        let xx = ev.clientX;
        let yy = ev.clientY;
        this.ele.style.left = xx-x+"px";
        this.ele.style.top = yy-y+"px";
      }
    }
    Drag.prototype.upFn = function(){
      this.ele.onmouseup = ()=>{
        this.ele.onmousemove = "";
      }
    }
    
    let mydiv1 = document.querySelector(".mydiv1");
    //let mydiv2 = document.querySelector(".mydiv2");
    let drag1 = new Drag(mydiv1);
    //let drag2 = new Drag(mydiv2);
    //继承:es5
    function LimitDrag(ele){
      Drag.call(this.ele);
    }
    
    let Link = function(){};
    Link.prototype = Drag.prototype;
    LimitDrag.prototype = new Link();
    LimitDrag.prototype.constructor = LimitDrag;
    LimitDrag.prototype.setStyle = function(leftNum,topNum){
      leftNum = leftNum<0?0:leftNum;
      topNum = topNum<0?0:topNum;
      this.ele.style.left = leftNum + "px";
      this.ele.style.top = topNum +"px";
    }
    
    let mydiv2 = document.querySelector(".mydiv2");
    let drag2 = new LimitDrag(mydiv2);
    
    
   //es6继承
   class Drag{
     constructor(ele){
       this.ele = ele;
       this.downFn();
     }
     downFn(){
       this.ele.onmousedown = e=>{
         let ev = e||window.event;
         let x =ev.clientX - this.ele.offsetLeft;
         let y =ev.clientY - this.ele.offsetTop;
         this.moveFn(x,y);
         this.upFn();
       }
     }
     moveFn(x,y){
       this.ele.onmousemove = e=>{
         let ev = e||window.event;
         let xx = ev.clientX;
         let yy = ev.clientY;
         this.ele.style.left = xx-x+"px";
         this.ele.style.top = yy-y+"px";
       }
     }
     setStyle(leftNum,topNum){
       this.ele.style.left = leftNum + "px";
       this.ele.style.top = topNum +"px";
     }
     upFn(){
       document.onmouseup = ()=>{
         this.ele.onmousemove = "";
       }
     }
   }
   
   let mydiv1 = document.querySelector(".mydiv1");
   let drag1 = new Drag(mydiv1);
   
   class LimitDrag extends Drag{
     constructor(ele){
       super(ele);
     }
     setStyle(leftNum,topNum){
       leftNum = leftNum<0?0:leftNum;
       topNum = topNum<0?0:topNum;
       super.setStyle(leftNum,topNum);
     }
   }
   
   let mydiv2 = document.querySelector(".mydiv2");
   let drag2 = new LimitDrag(mydiv2);
   
   
   
  </script>
  
</html>

包装对象

//基本类型,string number boolean 系统会给基本类型包装一个对象,即实例化一个基本类型对象

几个方法

  • hasOwnProperty() 判断是不是对象自身的属性,返回布尔值
  • constructor 判断实例化对象的指向,返回布尔值
  • 精确判断类型 Object.prototype.toString.call(arr);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值