zoukankan      html  css  js  c++  java
  • 面向对象的程序设计

    1. 理解对象

    var person = new Object();
    person.name = "Nicholas";
    person.age = 29;
    person.job = "Software Engineer";
    person.sayName = function(){
        alert(this.name);
    };
    
    var person = {
        name: "Nicholas",
        age: 29,
        job: "Software Engineer",
        sayName: function(){
            alert(this.name);
        }
    };
    

    1.1 属性类型

    1.1.1 数据属性

    var person = {};
        Object.defineProperty(person, "name", {
        writable: false,
        value: "Nicholas"
    });
    alert(person.name); //"Nicholas"
    person.name = "Greg";
    alert(person.name); //"Nicholas"
    
    var person = {};
        Object.defineProperty(person, "name", {
        configurable: false,
        value: "Nicholas"
    });
    alert(person.name); //"Nicholas"
    delete person.name;
    alert(person.name); //"Nicholas"
    
    var person = {};
    Object.defineProperty(person, "name", {
        configurable: false,
        value: "Nicholas"
    });
    //抛出错误
    Object.defineProperty(person, "name", {
        configurable: true,
        value: "Nicholas"
    });
    
    • Configurable
    • Enumerable
    • Writable
    • Value

    1.1.2 访问器属性

    var book = {
        _year: 2004,
        edition: 1
    };
    Object.defineProperty(book, "year", {
        get: function(){
            return this._year;
        },
        set: function(newValue){
            if (newValue > 2004) {
                this._year = newValue;
                this.edition += newValue - 2004;
            }
        }
    });
    book.year = 2005;
    alert(book.edition); //2
    
    var book = {
        _year: 2004,
        edition: 1
    };
    //定义访问器的旧有方法
    book.__defineGetter__("year", function(){
        return this._year;
    });
    book.__defineSetter__("year", function(newValue){
        if (newValue > 2004) {
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    });
    book.year = 2005;
    alert(book.edition); //2
    
    • Configurable
    • Enuberable
    • Get
    • Set

    1.2 定义多个属性

    1.3 读取属性的特性

    2. 创建对象

    2.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("Nicholas", 29, "Software Engineer");
    var person2 = createPerson("Greg", 27, "Doctor");
    

    2.2 构造函数模式

    function Person(name, age, job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function(){
            alert(this.name);
        };
    }
    var person1 = new Person("Nicholas", 29, "Software Engineer");
    var person2 = new Person("Greg", 27, "Doctor");
    
    alert(person1.constructor == Person); //true
    alert(person2.constructor == Person); //true
    
    alert(person1 instanceof Object); //true
    alert(person1 instanceof Person); //true
    alert(person2 instanceof Object); //true
    alert(person2 instanceof Person); //true
    
    2.2.1 将构造函数当作函数
    // 当作构造函数使用
    var person = new Person("Nicholas", 29, "Software Engineer");
    person.sayName(); //"Nicholas"
    
    // 作为普通函数调用
    Person("Greg", 27, "Doctor"); // 添加到 window
    window.sayName(); //"Greg"
    
    // 在另一个对象的作用域中调用
    var o = new Object();
    Person.call(o, "Kristen", 25, "Nurse");
    o.sayName(); //"Kristen"
    
    2.2.2 构造函数的问题
    function Person(name, age, job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = sayName;
    }
    function sayName(){
        alert(this.name);
    }
    var person1 = new Person("Nicholas", 29, "Software Engineer");
    var person2 = new Person("Greg", 27, "Doctor");
    

    2.3 原型模式

    function Person(){
    }
    
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    Person.prototype.job = "Software Engineer";
    Person.prototype.sayName = function(){
        alert(this.name);
    };
    
    var person1 = new Person();
    person1.sayName(); //"Nicholas"
    var person2 = new Person();
    person2.sayName(); //"Nicholas"
    alert(person1.sayName == person2.sayName); //true
    
    2.3.1 理解原型对象
    alert(Person.prototype.isPrototypeOf(person1)); //true
    alert(Person.prototype.isPrototypeOf(person2)); //true
    
    alert(Object.getPrototypeOf(person1) == Person.prototype); //true
    alert(Object.getPrototypeOf(person1).name); //"Nicholas"
    
    //实例中的属性会屏蔽原型中同名属性
    function Person(){
    }
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    Person.prototype.job = "Software Engineer";
    Person.prototype.sayName = function(){
        alert(this.name);
    };
    var person1 = new Person();
    var person2 = new Person();
    person1.name = "Greg";
    alert(person1.name); //"Greg"—— 来自实例
    alert(person2.name); //"Nicholas"—— 来自原型
    
    //通过 delete 可以删除实例属性,让我们重新能够访问原型中的属性
    function Person(){
    }
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    Person.prototype.job = "Software Engineer";
    Person.prototype.sayName = function(){
        alert(this.name);
    };
    var person1 = new Person();
    var person2 = new Person();
    person1.name = "Greg";
    alert(person1.name); //"Greg"—— 来自实例
    alert(person2.name); //"Nicholas"—— 来自原型
    delete person1.name;
    alert(person1.name); //"Nicholas"—— 来自原型
    
    //使用 hasOwnProperty()方法可以检测一个属性是存在于实例中,还是存在于原型中。
    function Person(){
    }
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    Person.prototype.job = "Software Engineer";
    Person.prototype.sayName = function(){
        alert(this.name);
    };
    var person1 = new Person();
    var person2 = new Person();
    alert(person1.hasOwnProperty("name")); //false
    person1.name = "Greg";
    alert(person1.name); //"Greg"—— 来自实例
    alert(person1.hasOwnProperty("name")); //true
    alert(person2.name); //"Nicholas"—— 来自原型
    alert(person2.hasOwnProperty("name")); //false
    delete person1.name;
    alert(person1.name); //"Nicholas"—— 来自原型
    alert(person1.hasOwnProperty("name")); //false
    
    2.3.2 原型与 in 操作符
    function Person(){
    }
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    Person.prototype.job = "Software Engineer";
    Person.prototype.sayName = function(){
        alert(this.name);
    };
    var person1 = new Person();
    var person2 = new Person();
    alert(person1.hasOwnProperty("name")); //false
    alert("name" in person1); //true
    person1.name = "Greg";
    alert(person1.name); //"Greg" —— 来自实例
    alert(person1.hasOwnProperty("name")); //true
    alert("name" in person1); //true
    alert(person2.name); //"Nicholas" —— 来自原型
    alert(person2.hasOwnProperty("name")); //false
    alert("name" in person2); //true
    delete person1.name;
    alert(person1.name); //"Nicholas" —— 来自原型
    alert(person1.hasOwnProperty("name")); //false
    alert("name" in person1); //true
    
    function Person(){
    }
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    Person.prototype.job = "Software Engineer";
    Person.prototype.sayName = function(){
        alert(this.name);
    };
    var person = new Person();
    alert(hasPrototypeProperty(person, "name")); //true
    person.name = "Greg";
    alert(hasPrototypeProperty(person, "name")); //false
    
    function Person(){
    }
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    Person.prototype.job = "Software Engineer";
    Person.prototype.sayName = function(){
        alert(this.name);
    };
    var keys = Object.keys(Person.prototype);
    alert(keys); //"name,age,job,sayName"
    var p1 = new Person();
    p1.name = "Rob";
    p1.age = 31;
    var p1keys = Object.keys(p1);
    alert(p1keys); //"name,age"
    
    var keys = Object.getOwnPropertyNames(Person.prototype);
    alert(keys); //"constructor,name,age,job,sayName"
    
    2.3.3 更简单的原型语法
    function Person(){
    }
    Person.prototype = {
        name : "Nicholas",
        age : 29,
        job: "Software Engineer",
        sayName : function () {
            alert(this.name);
        }
    };
    
    var friend = new Person();
    alert(friend instanceof Object); //true
    alert(friend instanceof Person); //true
    alert(friend.constructor == Person); //false
    alert(friend.constructor == Object); //true
    
    function Person(){
    }
    Person.prototype = {
        constructor : Person,
        name : "Nicholas",
        age : 29,
        job: "Software Engineer",
        sayName : function () {
            alert(this.name);
        }
    };
    
    function Person(){
    }
    Person.prototype = {
        name : "Nicholas",
        age : 29,
        job : "Software Engineer",
        sayName : function () {
            alert(this.name);
        }
    };
    //重设构造函数,只适用于 ECMAScript 5 兼容的浏览器
    Object.defineProperty(Person.prototype, "constructor", {
        enumerable: false,
        value: Person
    });
    
    2.3.4 原型的动态性
    function Person(){
    }
    var friend = new Person();
        Person.prototype = {
        constructor: Person,
        name : "Nicholas",
        age : 29,
        job : "Software Engineer",
        sayName : function () {
            alert(this.name);
        }
    };
    friend.sayName(); //error
    
    2.3.5 原生对象的原型
    //为原生对象原型增加方法
    String.prototype.startsWith = function (text) {
        return this.indexOf(text) == 0;
    };
    var msg = "Hello world!";
    alert(msg.startsWith("Hello")); //true
    
    2.3.6 原型对象的问题
    function Person(){
    }
    Person.prototype = {
        constructor: Person,
        name : "Nicholas",
        age : 29,
        job : "Software Engineer",
        friends : ["Shelby", "Court"],
        sayName : function () {
            alert(this.name);
        }
    };
    var person1 = new Person();
    var person2 = new Person();
    person1.friends.push("Van");
    alert(person1.friends); //"Shelby,Court,Van"
    alert(person2.friends); //"Shelby,Court,Van"
    alert(person1.friends === person2.friends); //true
    

    2.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,Count,Van"
    alert(person2.friends); //"Shelby,Count"
    alert(person1.friends === person2.friends); //false
    alert(person1.sayName === person2.sayName); //true
    

    2.5 动态原型模式

    function Person(name, age, job){
        //属性
        this.name = name;
        this.age = age;
        this.job = job;
        //方法
        if (typeof this.sayName != "function"){
            Person.prototype.sayName = function(){
                alert(this.name);
            };
        }
    }
    var friend = new Person("Nicholas", 29, "Software Engineer");
    friend.sayName();
    

    2.6 寄生构造函数模式

    function Person(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 friend = new Person("Nicholas", 29, "Software Engineer");
    friend.sayName(); //"Nicholas"
    
    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|blue|green"
    

    2.7 稳妥构造函数模式

    function Person(name, age, job){
        //创建要返回的对象
        var o = new Object();
        //可以在这里定义私有变量和函数
        //添加方法
        o.sayName = function(){
            alert(name);
        };
        //返回对象
        return o;
    }
    

    3. 继承

    3.1 原型链

    function SuperType(){
        this.property = true;
    }
    SuperType.prototype.getSuperValue = function(){
        return this.property;
    };
    function SubType(){
        this.subproperty = false;
    }
    //继承了 SuperType
    SubType.prototype = new SuperType();
    SubType.prototype.getSubValue = function (){
        return this.subproperty;
    };
    var instance = new SubType();
    alert(instance.getSuperValue()); //true
    
    3.1.1 别忘记默认的原型
    3.1.2 确定原型和实例的关系
    alert(instance instanceof Object); //true
    alert(instance instanceof SuperType); //true
    alert(instance instanceof SubType); //true
    
    alert(Object.prototype.isPrototypeOf(instance)); //true
    alert(SuperType.prototype.isPrototypeOf(instance)); //true
    alert(SubType.prototype.isPrototypeOf(instance)); //true
    
    3.1.3 谨慎地定义方法
    function SuperType(){
        this.property = true;
    }
    SuperType.prototype.getSuperValue = function(){
        return this.property;
    };
    function SubType(){
        this.subproperty = false;
    }
    //继承了 SuperType
    SubType.prototype = new SuperType();
    //添加新方法
    SubType.prototype.getSubValue = function (){
        return this.subproperty;
    };
    //重写超类型中的方法
    SubType.prototype.getSuperValue = function (){
        return false;
    };
    var instance = new SubType();
    alert(instance.getSuperValue()); //false
    
    function SuperType(){
        this.property = true;
    }
    SuperType.prototype.getSuperValue = function(){
        return this.property;
    };
    function SubType(){
        this.subproperty = false;
    }
    //继承了 SuperType
    SubType.prototype = new SuperType();
    //使用字面量添加新方法,会导致上一行代码无效
    SubType.prototype = {
        getSubValue : function (){
            return this.subproperty;
        },
        someOtherMethod : function (){
            return false;
        }
    };
    var instance = new SubType();
    alert(instance.getSuperValue()); //error!
    
    • 还有一点需要提醒读者,即在通过原型链实现继承时,不能使用对象字面量创建原型方法,
      因为这样做就会重写原型链。
    3.1.4 原型链的问题
    function SuperType(){
        this.colors = ["red", "blue", "green"];
    }
    function SubType(){
    }
    //继承了 SuperType
    SubType.prototype = new SuperType();
    var instance1 = new SubType();
    instance1.colors.push("black");
    alert(instance1.colors); //"red,blue,green,black"
    var instance2 = new SubType();
    alert(instance2.colors); //"red,blue,green,black"
    

    3.2 借用构造函数

    function SuperType(){
        this.colors = ["red", "blue", "green"];
    }
    function SubType(){
        //继承了 SuperType
        SuperType.call(this);
    }
    var instance1 = new SubType();
    instance1.colors.push("black");
    alert(instance1.colors); //"red,blue,green,black"
    var instance2 = new SubType();
    alert(instance2.colors); //"red,blue,green"
    
    3.2.1 传递参数
    function SuperType(name){
        this.name = name;
    }
    function SubType(){
        //继承了 SuperType,同时还传递了参数
        SuperType.call(this, "Nicholas");
        //实例属性
        this.age = 29;
    }
    var instance = new SubType();
    alert(instance.name); //"Nicholas";
    alert(instance.age); //29
    
    3.2.2 借用构造函数的问题

    3.3 组合继承

    function SuperType(name){
        this.name = name;
        this.colors = ["red", "blue", "green"];
    }
    SuperType.prototype.sayName = function(){
        alert(this.name);
    };
    function SubType(name, age){
        //继承属性
        SuperType.call(this, name);
        this.age = age;
    }
    //继承方法
    SubType.prototype = new SuperType();
    SubType.prototype.constructor = SubType;
    SubType.prototype.sayAge = function(){
        alert(this.age);
    };
    var instance1 = new SubType("Nicholas", 29);
    instance1.colors.push("black");
    alert(instance1.colors); //"red,blue,green,black"
    instance1.sayName(); //"Nicholas";
    instance1.sayAge(); //29
    var instance2 = new SubType("Greg", 27);
    alert(instance2.colors); //"red,blue,green"
    instance2.sayName(); //"Greg";
    instance2.sayAge(); //27
    

    3.4 原型式继承

    var person = {
        name: "Nicholas",
        friends: ["Shelby", "Court", "Van"]
    };
    var anotherPerson = object(person);
    anotherPerson.name = "Greg";
    anotherPerson.friends.push("Rob");
    var yetAnotherPerson = object(person);
    yetAnotherPerson.name = "Linda";
    yetAnotherPerson.friends.push("Barbie");
    alert(person.friends); //"Shelby,Court,Van,Rob,Barbie"
    
    var person = {
        name: "Nicholas",
        friends: ["Shelby", "Court", "Van"]
    };
    var anotherPerson = Object.create(person);
    anotherPerson.name = "Greg";
    anotherPerson.friends.push("Rob");
    var yetAnotherPerson = Object.create(person);
    yetAnotherPerson.name = "Linda";
    yetAnotherPerson.friends.push("Barbie");
    alert(person.friends); //"Shelby,Court,Van,Rob,Barbie"
    

    3.5 寄生式继承

    function createAnother(original){
        var clone = object(original); //通过调用函数创建一个新对象
        clone.sayHi = function(){ //以某种方式来增强这个对象
            alert("hi");
        };
        return clone; //返回这个对象
    }
    

    3.6 寄生组合式继承

    function inheritPrototype(subType, superType){
        var prototype = object(superType.prototype); //创建对象
        prototype.constructor = subType; //增强对象
        subType.prototype = prototype; //指定对象
    }
    
    • 开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。
  • 相关阅读:
    Node自动重启工具 nodemon
    centos 集群
    kettle操作数据库增删改
    Dinic
    vim
    mermaid简介
    联赛模拟测试32
    检讨书模板
    博客园如何添加看板娘!
    手机浏览器如何调试
  • 原文地址:https://www.cnblogs.com/HuoAA/p/5074205.html
Copyright © 2011-2022 走看看