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; //指定对象
    }
    
    • 开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。
  • 相关阅读:
    jvm基本结构和解析
    多态的意思
    java中对象的简单解读
    double类型和int类型的区别
    python 解析xml文件
    win10不能映射Ubuntu共享文件
    Qt程序打包
    Ubuntu boot分区文件误删,系统无法启动,怎么解
    ubuntu Boot空间不够问题“The volume boot has only 5.1MB disk space remaining”
    Ubuntu 分辨率更改 xrandr Failed to get size of gamma for output default
  • 原文地址:https://www.cnblogs.com/huoteng/p/4961331.html
Copyright © 2011-2022 走看看