zoukankan      html  css  js  c++  java
  • 浅谈面向对象和继承

    1.面向对象和面向过程的区别

      面向过程:注重代码的过程

      面向对象:注重代码的结果

    2.面向对象三大特性

      抽象   封装  继承  多态(JS不存在多态)

    3.什么是一个构造函数

      new 一个关键字函数  创建一个对象,该对象的属性this指向window 函数里面指向这个对象

      构造函数和普通函数的区别 :

        1、前者的this的指向是实例化后的对象 后者的指向是指向window

        2、普通函数返回值需要加return 构造函数不需要因为返回的是自己本身


      为什么构造函数没有return却能够有返回值呢?
          因为构造函数在调用的时候系统内部 自动return出了一个this,而这个this就是指的这个对象

    这时就不得不说下this的指向问题了!!

    this的指向调用它的对象(可以通过bind/apply/call来改变this的指向)

    1.严格模式下this的指向为undefined 但如果在全局则为 window 因为调用它的对象是window
    2.一个对象 属性this指向window 方法里面的指向为这个对象

    3.异步事件this的指向为调用它的对象
      计时器为window
      ajax也为window
    4.箭头函数中的this
      此时的 this继承自obj, 指的是定义它的对象obj(也可以理解为它外层的指向就是它的指向)
    , 而不是 window,里面只要还是箭头函数就一直是obj 而不是window 如若不是则是window(会继承下来)

    var obj={
        say:function(){
            un=()=>{
                console.log(this)  //obj
                cn=function(){
                    console.log(this)//window
                }
                cn()
                dn=()=>{
                    console.log(this) //obj
                }
                dn()
            }
            un()
        }
    }
    obj.say()
    var obj={
        say:function(){
            setTimeout(()=>{
        console.log(this) //obj
      });
            (function(){
                console.log(this) //window
            })()
            setTimeout(function(){
                console.log(this) //window
    }) } } obj.say()

    这里要注意输出顺序函数声明提升


    5.箭头函数和普通函数混用
      

    var obj = {
      say: function () {
         console.log(this) //obj   un
    =function(){     console.log(this) //没有宿主对象,默认是window     setTimeout(()=>{     console.log(this) //定义它对象的obj是window   })   }   un() } } obj.say()

    6.严格模式下的混用
    箭头存在其中依然是undefinde
    严格模式下,没有宿主调用的函数中的this是undefined!!!所以箭头函数中的也是undefined!

    继承:

      call和apply一般情况下我们都是用来做属性继承的。

      第一个参数都是 this的指向

      call第二个参数为一系列的值

      apply第二个参数为一个数组

    Object.prototype.toString.call():检测一个复杂数据类型是一个什么样的类型
    instanceof:判断一个对象是不是另一个对象创建出来的
    typeof:只能判断基本数据类型 引用数据类型统计返回OBject

      原型:

      

    prototype:
    每一个函数里面都有一个prototype属性 这个属性叫做原型 这个原型指向一个对象 我们把这个对象叫做原型对象
      1、节约内存
      2、扩展属性和方法
      3、实现类的继承
    原型对象里面有2个东西
      constructor:构造器-->作用指向创建自己的那个构造函数
      __proto__:__proto__属性指向的是创建自己的那个构造函数的原型


      1、每一个对象里面都会有一个__proto__这个属性
      2、__proto__指向了一个对象 这个对象是原型对象
      3、实例化对象可以直接访问__proto__里面的一些方法

        new person).__proto__==person.prototype
      原型链:
    什么叫做原型链?
      原型链:由__proto__形成的链条
      Object里面的__proto__指向的是null 原型链的顶点

    方法继承:后面改变在加会影响到前面的(引用传递)
    1.原型继承 Man.prototype = Person.prototype 缺点:污染父级

    function person(name,age) {
        this.name=name
        this.age=age
    }

    person.prototype.eat = function(){
    }

    person.prototype.sleep = function(){
    }

    function man(sex){
        this.sex=sex
    }
    console.log([person])
    man.prototype=person.prototype
    man.prototype.work = function(){};
    p1=new man()
    console.log(p1,[person])

    2.原型拷贝:for(var attr in person.prototype){
    man.prototype[attr]=person.prototype[attr]
    }

    function person(name,age) {
        this.name=name
        this.age=age
    }
    person.prototype.eat = function(){
    }
    
    person.prototype.sleep = function(){
    }
    function man(sex){
        this.sex=sex
    }
    console.log([person])
    for(var key in person.prototype){
        man.prototype[key] = person.prototype[key];
    }
    man.prototype.work = function(){};
    p1=new man()
    console.log(p1,[person])


    缺点:假设Person上面还有父级 那么我们的Man是无法访问到Person父级的原型上的方法

      
    3.原型链继承(Man.prototype = new Person())
    多了东西少了东西

    person.prototype==new man.__proto__.__proto__

    function person(name,age) {
        this.name=name
        this.age=age
    }
    person.prototype.eat = function(){
    }
    
    person.prototype.sleep = function(){
    }
    function man(sex){
        this.sex=sex
    }
    console.log([person])
    man.prototype=new person()
    man.prototype.work = function(){};
    p1=new man()


    4.混合继承:少了contructor 原型对象的指向也发生改变 而且还无缘无故多了好多东西
    man.prototype = {
      constructor:man,
      //原型链继承
      __proto__:person.prototype
      }(因此改善)


    5.寄生继承(间接继承)
    利用的是原型链继承的基础
      function fn(){}
    继承空的方法
      fn.prototype=person.prototype
    因为它是纯净的只有里面的方法 不能直接Man.prototype = new fn() 这样也会污染
      Man.prototype = new fn()
      少了contructor 原型对象的指向也发生改变 而且还无缘无故多了好多东西
      改善(加contructor)
    不能做到函数复用

     6.ES6类继承

      

    class person{
        constructor(name,age){
            this.name = name
            this.age = age
        }
        eat(){
    
        }
    }
    class man extends person{
        constructor(bread,name,age){
            super(name,age)
            this.bread=bread
        }
        c(){
    
        }
    }
    p=new man(1,2,3)
    console.log(p)
  • 相关阅读:
    vue异步组件
    vue-awesome-swiper的使用
    自定义button组件时slot的使用
    axios拦截器的简单使用
    vue静态类名和动态类名绑定的几种方式
    快速知道所有元素的边框
    【转】CICD工具
    mocha学习(四)为项目开发一个BDD测试
    mocha学习(三)hook 机制 和 测试技巧
    mocha学习(二)mocha接口
  • 原文地址:https://www.cnblogs.com/lianqing/p/9073863.html
Copyright © 2011-2022 走看看