• javaScript设计模式(2)——构造函数模式


    构造函数:用于创建特定类型的对象——不仅声明了使用的对象,构造函数还
    可以接受参数以便第一次创建对象的时候设置对象的成员值。
    构造函数是实现实例的,可多次实例化,每一次的new都是一次的全部代码执行

    一般特点:

    1. 函数首字母大写,区别于其他函数,function Person(){}
    2. 函数内部的this指向new实例化的新对象var o = new Person();
      Person内部的this指向o
    3. 多次new,存在内存消耗问题(重复new)

    1.基本的构造函数

    function Person(name,book) {
        this.name = name;
        this.book = book;
        this.output = function(){
            return this.name+' read '+this.book;
        }
    }
    
    
    var may = new Person('may','The little prince');    //this指向may
    console.log(may.name);     //may
    console.log(may.output());    //may read The little prince
    console.log(may instanceof Person);    //true,may是Person的一个实例
    

    存在一些问题:多次实例化,就会多次执行函数output();会大量消耗内存,所以下一步降低内存消耗。

    2.解决内存消耗的问题,提出function

    方案一:提出output到构造函数外部

    function Person(name,book) {
        this.name = name;
        this.book = book;
        this.output = read;
    }
    function read() {     //单独提出,用的时候再执行
        return this.name+' read '+this.book;
    }
    
    var alice = new Person('alice','gone with the wind')
    console.log(alice.output());
    

    方案二:利用原型链(推荐)

    调用构造函数创建对象的时候,构造函数原型的属性都可以在
    新创建的对象上使用,多个Person对象实例都可以共享使用output(),共享使用

    function Person(name,book) {
        this.name = name;
        this.book = book;
    }
    Person.prototype.output = function () {
        return this.name+' read '+this.book;
    }
    
    var alice = new Person('alice','gone with the wind')
    console.log(alice.output());
    

    3.用new和不用new的区别

    不用new会有什么问题?

    function Person(name,book) {
        this.name = name;
        this.book = book;
        this.output = function(){
            return this.name+' read '+this.book;
        }
    }
    /*不用new,则作为函数调用*/
    Person('alice','The little prince');          //this指向window
    console.log(window.name);     //alice
    console.log(window.output());     //alice read The little prince
    
    var alice = Person('alice','The little prince');       //this指向window
    console.log(typeof alice);        //undefined
    console.log(alice.name);      //error
    console.log(alice.output());      //error
    

    不用new的,不报错的解决方式

    利用新对象,在新对象的作用域上使用

    function Person(name,book) {
        this.name = name;
        this.book = book;
        this.output = function(){
            return this.name+' read '+this.book;
        }
    }
    var may = new Object();
    Person.call(may,'may','The little prince');     //利用call,使的this指向may
    console.log(may.name);      //may
    console.log(may.output());      //may read The little prince
    

    默认,强制使用new的实现方式

    function Person(name,book) {
        //判断this是否是Person的实例,没有则实例化
        if(!(this instanceof Person)){
            return new Person(name,book);
        }
        /*公有*/
        this.name = name;
        this.book = book;
        this.output = function(){
            return this.name+' read '+this.book;
        }
    }
    var may = Person('may','The little prince');    //this指向may
    console.log(may.name);      //may
    console.log(may.output());      //may read The little prince
    

    4.复杂构造函数,测试与总结(完全版)

    包含,公有及私有属相及方法,以及原型的使用

    function Person(weight,age) {
        /*公有*/
        this.weight = weight;
        this.sayWeight = function(){      //每次实例化后都要重新构造
            console.log("It's "+this.weight);
        }
        /*私有*/
        var age = '18';
        var getAge = function () {
            cosnoel.log(age);
        }
    
    }
    Person.prototype.hello = 'hello world!';
    Person.prototype.sayHello = function(){
        console.log('hello everybody!');
    }
    /*静态属性及方法*/
    Person.address = 'china';
    Person.sayAddress = function () {
        console.log(this.address);
    }
    var alice = new Person('50kg','10');
    
    /******************测试,类属性*******************/
    //    console.log(alice.weight);        //50kg
    //    console.log(alice.age);         //undefined,私有,不被实例化
    //    console.log(alice.hello);    //hello world!,原型上的属性,被所有实例继承
    //    console.log(alice.address);     //undefined,address属于函数本身的属性,
    //                                    //也可以说,是类属性和类本身(即函数本身)相关,和类实例没有关系
    //    console.log(alice.constructor.address); //china,通过函数的实例来访问函数的属性,
    //                                            // 则需要先访问该实例的构造函数,进而访问该函数的属性
    //    console.log(Person.weight);      //undefined,this指向的是实例化的对象alice,不是Person
    //    console.log(Person.age);         //undefined,私有,不被实例化对象拥有,也不被方法本身的Person对象拥有
    //    console.log(Person.hello);       //undefined,错误调用,在原型上呢
    //    console.log(Person.address);     //china,类自身的方法
    
    
    /******************测试,类方法(解释同属性)*******************/
    //    alice.sayName();       //It's alice
    //    alice.getAge();        //FF:...not a function,私有,不被实例化
    //    alice.sayHello();         //hello everybody!,原型上的方法都会被实例继承
    //    alice.sayAddress();         //FF:...not a function,类本身的方法,不被实例化的对象继承
    //    alice.constructor.sayAddress();         //china.用constructor访问this指向调用的对象,这里应该是Person
    //    Person.sayName();      //undefined,
    //    Person.getAge();      //undefined,
    //    Person.sayHello();      //undefined,
    //    Person.sayAddress();      //china,
    
    
    /******************测试,prototype*******************/
    //    console.log(alice.prototype);/*undefined,实例对象没有prototype*/
    //    console.log(Person.prototype);/*Object,*/
    //    Person.prototype.sayHello();/*hello everybody!,*/
    //    console.log(Person.prototype.hello);/*hello world!,*/
    //    console.log(Person.prototype.constructor);/*返回构造函数Person(){},*/
    //    console.log(Person.prototype.constructor.address);/*china,*/
    //    console.log(Person.prototype.constructor.name);/*Person,构造函数的名称*/
    //小结:实例化的对象没有prototype属性,只有构造函数才有(即构造函数保存了对prototype属性的引用)
    

    参考文章:
    http://www.cnblogs.com/jikey/archive/2011/05/13/2045005.html
    http://www.cnblogs.com/mrsunny/archive/2011/05/09/2041185.html
    http://www.cnblogs.com/TomXu/archive/2012/02/21/2352994.html

  • 相关阅读:
    BZOJ2456: mode 众数卡空间
    BZOJ4128: Matrix 矩阵BSGS
    [SDOI2011]计算器 BSGS
    前台中文搜索到后台乱码
    批量删除实现js+springmvc
    基于Jquery+Ajax+Json实现分页显示
    分页条的制作
    input text中不能显示空格后的内容
    mysql存入中文乱码问题
    WEBROOT根目录 <%=request.getContextPath()%>
  • 原文地址:https://www.cnblogs.com/flora-dn/p/7657711.html
Copyright © 2020-2023  润新知