美文网首页
对象的封装(面向对象)&& 原型(prototype)

对象的封装(面向对象)&& 原型(prototype)

作者: Sanyekui | 来源:发表于2019-11-06 16:41 被阅读0次

    JavaScript不区分类和实例的概念,是通过原型(prototype)来实现面向对象编程

    类:类是对象的类型模板,比如定义Student类来表示学生,但它不表示任何具体的学生
    实例:实例是根据类创建的对象,比如根据Student类,可以创建出"小明","小花"等多个
    实例,每一个实例代表一个学生,这些实例全部属于Student类

    创建一个对象:

    
    var obj = new Object();//obj就是new Object的实例
    obj.name = "小明";//静态的是属性
    obj.age = 18;
    obj.run = function(){//动态的是方法
        return this.name+this.age+"在跑步。。。";
        this用在对象里面,指向的是对象的实例
    }
    console.log(typeof obj,obj);//object {name: "小明", age: 18, run: ƒ}
    console.log(obj.run());//小明18在跑步。。。
    
    

    工厂模式:

    为了解决多个类似对象声明的问题,也是为了解决实例化对象产生大量代码重复的问题

    function createObj(name,age){
        var obj1 = new Object();//obj就是new Object的实例
        obj1.name = name;//静态的是属性 
        obj1.age = age;
        obj1.run = function(){//动态的是方法
            return this.name+this.age+"在跑步。。。";
    //      this用在对象里面,指向的是对象的实例
        }
        return obj1;
    }
                
    var create_obj = createObj("小花",18);
    var create_obj01 = createObj("小红",19);
    console.log(create_obj,create_obj01);
    //{name: "小花", age: 18, run: ƒ} {name: "小红", age: 19, run: ƒ}
    console.log(create_obj instanceof createObj);//false  
    
    

    工厂模式的问题:
    1.创建不同的对象,其中的属性和方法都会重复创建,消耗内存
    2.会产生函数识别的问题

    注意事项:
    1.用函数将所有内容都打包起来,按照需求传入形参
    2.函数内部必须返回该函数


    构造函数:

    构造函数的方法的规范:
    1.函数名和实例化构造名相同且大写(非强制性,这么写有助于区分构造函数和普通函数)
    2.通过构造函数创建的对象,必须要使用关键字new

    构造函数和普通函数的区别:
    使用关键字new的是构造函数,没有关键字new的是普通函数

      function Obj(name,age){
        this.name = name;
    //  this代表当前作用域对象的引用,如果在全局范围,指向的是window对象,
    //  如果在构造函数体内,指向的是构造函数所声明的对象
        this.age = age;
        this.run = function(){
            return this.name+this.age+"在跑步。。。";
        }
    }
                
    var obj2 = new Obj("小黑",30);
    var obj3 = new Obj("小乌龟",99);
    //当使用了 new 构造函数方法,就会在后边执行new Object
                
    console.log(obj2,obj3);//{name: "小黑", age: 30, run: ƒ} Ojb {name: "小乌龟", age: 99, run: ƒ}
    console.log(obj2.run());//小黑30在跑步。。。
    console.log(obj3.run());//小乌龟99在跑步。。。
                
    console.log(obj3 instanceof Obj);//true 解决了对象识别问题
                
    console.log(obj2 === obj3);//false
    
    

    同一个构造函数的实例之间无法共享属性和方法

    构造函数解决了工厂模式遗留的函数识别问题,没有解决内存消耗的问题,
    同时还带了新的this指向的问题

    构造函数创建对象的执行过程:
    1.当使用了构造函数,并且使用 new 构造函数(),就会在后台执行 new Object()
    2.将构造函数的作用域指给新的对象(也就是通过 new Object()创建出来的实例),函数体内的this就代表当前被创建出来的实例
    3.执行构造函数体内的代码
    4.返回新对象


    原型(prototype)

    function Student(name,age){
        this.name = name;
        this.age = age;
    }
    Student.prototype.run = function(){//公共方法.原型对象上的所有属性和方法,都是可以被对象实例所公用的
        return this.name+this.age+"在睡觉。。。";
    }
    var stu01 = new Student("小白",20);
    var stu02 = new Student("大白",21);
                
    stu01.run = function(){//私有方法
        return this.name+this.age+"在做梦";
    }
    console.log(stu01.run());//小白20在做梦。。。  若有私有方法 会先调用私有再去调用公共
    console.log(stu02.run());//大白21在睡觉。。。
    console.log(stu01.run === stu02.run);//true
    
    

    原型对象的作用,就是定义所有对象的实例所共享的属性和方法;
    prototype对于构造函数来说它是一个属性,对于对象实例来说,它是一个原型对象

    原型解决了内存消耗的问题和this指向的问题


    原型(prototype)

    js中除了undefined 和 null ,其他的数据类型都是有对象的,每一个对象都继承另外一个对象
    后者被称为原型(prototype)对象,null是没有自己的原型对象的
    原型对象上的所有属性和方法,都是可以被对象实例所公用的

    __ proto __:
    对象的内置属性,用于指向创建它的函数对象的原型对象的prototype

    console.log( stud01.__proto__ === Stu.prototype );//true
    console.log(stud01.__proto__,Stu.prototype);//指向一样 {total: ƒ, constructor: ƒ} {total: ƒ, constructor: ƒ}
                
    Stu.prototype对象也有__proto__(内置属性), 指向Object.prototype
    console.log(Stu.prototype.__proto__);
    

    原型链:
    原型对象本身也是对象,它也有自己的原型,而它自己的原型对象又可以有自己的原型
    这样就组成一条链,这个就是原型链

    实例对象的proto指向的是构造函数的原型
    构造函数原型的proto指向的是Object的原型
    Object原型的proto指向null

    相关文章

      网友评论

          本文标题:对象的封装(面向对象)&& 原型(prototype)

          本文链接:https://www.haomeiwen.com/subject/cmwubctx.html