zoukankan      html  css  js  c++  java
  • 面向对象设计——创建对象

    1.工厂模式 

    function createPerson(name,age,job) {
        var o = new Object();
        o.name = name;
        o.age = age;
        o.job = job;
        o.sayName = function(){
            alert(this.name);
        }
        return o;
    }
    var person1 = createPerson("Lucy",30,"Software Engineer");
    var person2 = createPerson("Greg",30,"Doctor");

    优势:可无数次调用,每次都返回一个包含三个属性一个方法的对象,避免出现多个相似对象的问题。

    缺点:无法判断对象的类型。   

    2.构造函数模式

    与其他函数的区别在于调用方式,通过new操作符来调用,如果不用new,跟其他函数没有什么区别。

    function Person(name,age,job) {
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function(){
            alert(this.name);
        }
    }
    var person1 = new Person("Lucy",30,"Software Engineer");
    var person2 = new Person("Greg",30,"Doctor");
    
    作为构造函数调用:
    var person = new Person("Greg",30,"Doctor");
    person.sayName(); //Greg
    作为普通函数调用:
    Person("Greg",30,"Doctor");  //添加到window
    window.sayName();或者sayName();  //Greg
    在另一个对象作用域中调用
    var o = new Object();
    Person.call(o,"Kristen",30,"Nurse");
    o.sayName();  //Kristen

    优势:

    (1)创建自定义的构造函数,意味着可以将实例标识为一种特定的类型,是胜过工厂模式的地方。

    alert(person1 instanceof Person);  //true

    alert(person1 instanceof Object);  //true

    (2)每个方法都要每个实例上重新创建一遍,例子中person1和person2都有一个sayName()的方法,但是两个方法不是同一个Function实例。注:ECMAScript中的函数是对象,因此每定义一个函数,也就实例化一个对象。

    等价于:this.sayName = new Function("alert(this.name)");

    避免方案:

    function Person(name,age,job) {
    	this.name = name;
    	this.age = age;
    	this.job = job;
    	this.sayName = sayName;
    }
    function sayName(){
    	alert(this.name);
    }  //弊端:全局作用域的函数实际只能被某个对象调用,让全局作用域名不副实;若对象需要定义很多方法,就对应很多全局方法。
    

    3.原型模式

    function Person() {}
    Person.prototype.name = "Lucy";
    Person.prototype.age = 30;
    Person.prototype.job = "Software Engineer";
    Person.prototype.sayName = function(){
    	alert(this.name)
    }
    var person1 = new Person();
    person1.sayName();  //Lucy
    

    //简单语法

    function Person() {}
    Person.prototype = {
    constructor: Person, //确保constructor属性指向Person函数 name: "Lucy", age: 30, sayName: function(){ alert(this.name) } }; var person1 = new Person(); person1.sayName(); //Lucy
    注:若将var person1 = new Person();提升到第二行,则报错,因为重写原型对象切断了现有实例和新原型之间的联系,它们的引用任然是最初的原型。

    优势:可以让所有实例共享它所包含的属性和方法。

    原理:只要创建了一个函数,即为该函数创建一个prototype属性,这个属性指向函数的原型对象。默认情况下,所有的原型对象都会自动获得一个constructor(构造函数)属性,这个属性指向函数。

    方法:

    确定原型与实例关系的两个方法:

    (1)instanceof操作符

    person1 instanceof Person  //true

    (2)isPropotypeOf()方法

    Person.prototype.isPrototypeOf(person1)  //true

    其他:

    Object.getPrototypeOf()方法:Object.getPrototypeOf(person1)返回[[prototype]]的值

    hasOwnProperty():检测一个属性是否存在于实例中

    in操作符:只要通过对象能访问到属性,就返回true,同上结合即可确定该属性是存在于对象中还是原型中。

    弊端:原型模式的所有的属性被很多实例共享,即由于其共享本质所致;尤其是引用类型值的属性(即["red","green","yellow"])。

    4.组合使用构造函数模式和原型模式(认可度高,推荐)

    即构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性

    function Person(name, age, job){
        this.name = name; 
        this.age = age; 
        this.job = job; 
        this.friends = ['Shelby', 'Court'];
    }
    
    Person.prototype = {
        constructor : Person,
        sayName : function(){
            alert(this.name);
        }
    }
    
    var person1 = new Person('Nicholas', 29, 'Software Engineer');
    var person2 = new Person('Greg', 27, 'Doctor');
    
    person1.friends.push('Van');
    alert(person1.friends);  //'Shelby,Court,Van'
    alert(person1.friends);  //'Shelby,Court'

    缺点:有其他OO语言开发经验的人员在看到独立构造函数和原型时,有些困惑。

    5.动态原型模式

    把所有信息都封装在了构造函数中,通过在构造函数中初始化原型(仅在有必要的情况下)。

    function Person(name, age, job){
        this.name = name; 
        this.age = age; 
        this.job = job; 
        //方法
        if(typeof this.name != function){
             Person.prototype.sayName = function(){
                  alert(this.name);  
             }  
        }
    }       

    优势:对于采用这种模式创建的对象,还可以使用instanceof操作符来确定它的类型。即 person1 instanceof Person; //true

    6.寄生构造函数模式

    除了使用new操作符外,其他跟工厂模式一模一样。

    function SpecialArray(){
        var values = new Array();
        //添加值
        values.push.apply(values, arguments);
        //添加方法
        values.toPipedString = function(){
            return this.join('|');
        }
        //返回数组
        return values;
    } 
    var colors = new SpecialArray('red','blue','green');
    alert(colors.toPipedString()); //'red|blur|green'

    缺点:返回的函数与构造函数或者说与构造函数的原型属性一点关系没有,跟工厂模式一样的,不能依赖instanceof操作符来确定类型。

    7.稳妥构造函数模式

    function Person(name, age, job){
        var o = new Object();
        //可以在这里定义私有变量和函数
        o.sayName = function(){
            alert(name);
        }
        return o;
    }
    var person1 = Person('Nicholas', 29, 'Software Engineer');
    person1.sayName();  //'Nicholas'

    优势:除了调用sayName方法外没有别的办法可以访问到其数据成员,适合安全环境中,防止数据被其他程序改动时使用。

    与寄生构造函数的区别

    (1)新创建对象的实例方法不使用this

    (2)不使用new操作符调用构造函数  

    缺点:与寄生构造函数类似,操作符instanceof对此对象不起作用。

      

  • 相关阅读:
    paper 66: MATLAB函数—disp的使用
    paper 65 :尺度不变特征变换匹配算法[转载]
    paper 64:尺度空间(Scale space)理论
    paper 63 :函数比较:imfilter与fspecial
    paper 62:高斯混合模型(GMM)参数优化及实现
    paper 61:计算机视觉领域的一些牛人博客,超有实力的研究机构等的网站链接
    paper 60 :转载关于视觉SCI期刊
    paper 59:招聘
    paper 58 :机器视觉学习笔记(1)——OpenCV配置
    paper 57 :颜色直方图的代码
  • 原文地址:https://www.cnblogs.com/lixuemin/p/5695231.html
Copyright © 2011-2022 走看看