• 面向对象的程序设计


    创建对象的方式

    1、Object构造函数

     var person = new Object();
        person.name = "viven";
        person.age = 28;
        person.sayAge = function(){
            console.log(this.age);
        }
        person.sayAge()

    2、对象字面量方式

    var person ={
            name: "viven",
            age: 28,
            sayAge:function(){
                console.log(this.age);
            }
        }
        person.sayAge()

    3、工厂模式   ----只能知道是Object的实例,不能判断是否是createPerson实例

    function createPerson(name,age,job){
            var o = new Object();
            o.name = name;
            o.age = age;
            o.job = job;
            o.sayAge = function(){
                console.log(this.age);
            };
            return o;
        }
        var person1 = createPerson("viven",28,"didi");
        var person2 = createPerson("kevin",26,"baidu");
        console.log(person1.name); //viven
        person2.sayAge();   //26
        console.log(person1 instanceof Object); //true
        console.log(person1 instanceof createPerson);//false

    4、构造函数模式  ----person1,person2同时是Object的实例,因为所有的对象均继承Object

      I.创建一个新对象

      II.将构造函数的作用域赋值给对象(this指向)

      III. 执行构造函数中的代码(添加属性)

      IV.返回新对象

    function Person(name,age,job){
            this.name = name;
            this.age = age;
            this.job = job;
            this.sayAge  =function(){
                console.log(this.age);
            }
        }
        var person1 = new Person("viven",28,"didi");
        var person2 = new Person("kevin",26,"baidu");
        console.log(person1.name); //viven
        person2.sayAge();  //26
        console.log(person1 instanceof Object); //true
        console.log(person2 instanceof Person); //true

      把构造函数当做普通函数使用

    //赋值给window
        Person("lal",22,"wangyi"); 
        console.log(window.name);// lal 
    //在另一个对象的作用域中调用
        var O = new Object();
        Person.call(O,"bal",18,"tx");
        O.sayAge(); //18

      函数中每定义一个函数 就是实例化了一个对象。

      

    function Person(name,age,job){
            this.name = name;
            this.age = age;
            this.job = job;
            this.sayAge  =function(){
                console.log(this.age);
            }
        }
        var person1 = new Person("viven",28,"didi");
        var person2 = new Person("kevin",26,"baidu");
        console.log(person1.sayAge ==person2.sayAge); //false

      那么我们可以将函数定义转移到构造函数之外。来解决这个问题

    function Person(name,age,job){
            this.name = name;
            this.age = age;
            this.job = job;
            this.sayAge  = sayAge;
        }
        function sayAge(){
            console.log(this.age);
        }
        var person1 = new Person("viven",28,"didi");
        var person2 = new Person("kevin",26,"baidu");
        console.log(person1.sayAge ==person2.sayAge);//true

    这样一来,我们person1和person2就公用了在全局内的函数sayAge()。但是这样一来,在全局内定义函数,只能被实例化的Person来调用。怎么解决

    5、原型模式

    function Person(){
    
        }
        Person.prototype.name = "viven";
        Person.prototype.age = 26;
        Person.prototype.job = "wy";
        Person.prototype.sayAge = function(){
            console.log(this.age);
        }
        var person1 = new Person();
        person1.age = 18;
        person1.sayAge() //18
        var person2 = new Person();
        person2.sayAge() //26

      I.理解原型

    每个原型对象会自动获得一个constructor属性。这个属性包含一个指向prototype的指针

    Person.prototype.constructor 指向 Person

     function Person(){
    
        }
        Person.prototype.name = "viven";
        Person.prototype.age = 26;
        Person.prototype.job = "wy";
        Person.prototype.sayAge = function(){
            console.log(this.age);
        }
        var person1 = new Person();
        person1.age = 18;
        person1.sayAge() //18  来自实例化person1
        var person2 = new Person();
        person2.sayAge() //26  来自原型Person

     为实例化的对象添加属性的时候会覆盖原型对象中的同名属性。可以删除通过delete

    function Person(){
    
        }
        Person.prototype.name = "viven";
        Person.prototype.age = 26;
        Person.prototype.job = "wy";
        Person.prototype.sayAge = function(){
            console.log(this.age);
        }
        var person1 = new Person();
        var person2 = new Person();
        person1.age = 18;
        person1.sayAge() //18  来自实例化person1
        person2.sayAge() //26  来自原型Person
        delete person1.age;
        person1.sayAge(); //26 来自原型Person

    可以通过hasOwnProperty()方法检测访问的到底是实例属性还是原型属性。 返回true则是实例属性

    function Person(){
    
        }
        Person.prototype.name = "viven";
        Person.prototype.age = 26;
        Person.prototype.job = "wy";
        Person.prototype.sayAge = function(){
            console.log(this.age);
        }
        var person1 = new Person();
        var person2 = new Person();
        person1.age = 18;
        person1.sayAge() //18  来自实例化person1
        console.log(person1.hasOwnProperty("age")); //true
        person2.sayAge() //26  来自原型Person
        console.log(person2.hasOwnProperty("age")); //false
        delete person1.age;
        person1.sayAge(); //26 来自原型Person
        console.log(person1.hasOwnProperty("age")); //false

      II.更简单的原型写法

    function Person(){
    
        }
        Person.prototype={
            name: "viven",
            age: 26,
            job: "wy",
            sayAge: function(){
                console.log(this.age);
            }
        }

    这样的话,constructor就没有了。因为重新定义了原型prototype对象。如果需要的话可以这样

    function Person(){
    
        }
        Person.prototype={
            constructor:Person,
            name: "viven",
            age: 26,
            job: "wy",
            sayAge: function(){
                console.log(this.age);
            }
        }

    定义一个constructor指向原来的Person构造函数。

     III.原型对象的问题

    忽略了构造函数中 传入参数的步骤,然后实例化的函数取得的值都是一样的。

    6.组合使用构造函数和原型模式

    function Person(name,age,job){
            this.name = name;
            this.age = age;
            this.job = job;
            this.friends = ["shelby","count"];
        }
        Person.prototype = {
            constructor: Person,
            sayAge: function(){
                console.log(this.age);
            }
        }
        var person1 = new Person("viven",26,"wy");
        var person2 = new Person("kevin",24,"al");
        person1.friends.push("plmm");
        console.log(person1.friends);
        console.log(person2.friends);

     7、动态原型模式

    function Person(name,age,job){
            this.name = name;
            this.age = age;
            this.job = job;
            if(this.name != "function"){
                Person.prototype.sayName = function(){
                    console.log(this.name);
                }
            }
        }
        var person1 = new Person("viven",26,"wy");
        person1.sayName();

    通过检查某个存在的方法是否有效来决定是否要初始化原型。

    8、稳妥构造函数模式

     function Person(name,age,job){
            //创建要返回的对象
            var o =new Object();
            //定义私有变了和函数
            o.haha = "smile";
            //添加方法
            o.sayName = function(){
                console.log(name );
            };
            return o;
    
        }
        var person1 = Person("viven",26,"wy");
        person1.sayName();
        console.log(person1.name); //undefined

    除了通过方法来访问里面的name值,没有其他方法来访问

  • 相关阅读:
    数据结构与算法(一):初识算法和计算模型
    Flutter学习笔记(41)--自定义Dialog实现版本更新弹窗
    Mybatis-Plus简介及HelloWorld实现(附视频教程)~连载中
    “乐观锁”解决高并发下的幂等性问题(附java实测视频教程)
    git merge&rebase区别
    GIT TAG标签使用
    idea操作github远程库分支
    idea操作GIT本地库分支操作
    eclipse GIT本地库分支操作
    git分支操作命令
  • 原文地址:https://www.cnblogs.com/vivenZ/p/6434623.html
Copyright © 2020-2023  润新知