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

    理解对象

       属性类型

        数据属性(数据属性包含一个数据值的位置,这个位置可以读取和写入值,数据属性有4描述)

          [Configurable]:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性的特性,或者能否把属性修改为访问器属性,像前面例子中

            那样直接在对象上定义的属性,他们的这个特性默认为true.

           var person = {};
           Object.defineProperty(person,'name',{
              configurable:false,
              value:"Nicholas"
           });
            alert(person.name); // "Nicholas"
           delete person.name;
            alert(person.name); //"Nicholas"

          [Enumerable]: 表示能否通过for-in 循环返回属性。像前面例子中那样直接在对象上定义的属性,它们的这特性默认值为true.

          [Writable]: 表示能否修改属性的值,像前面例子中那样直接子对象上定义的属性,它们的这个属性默认值为true.

           var person = {};
           Object.defineProperty(person,'name',{
              writable:false,
              value:"Nicholas"
           });
           alert(person.name); // "Nicholas"
           person.name = "Greg";
           alert(person.name); //"Nicholas"

          [Value]: 包含这个属性的数值,读取属性值的时候,从这个位置读; 写入属性值的时候把新值保存在这个位置,这个属性的默认值为undefined;

        访问器属性 (访问器属性不能直接定义,必须使用Object.defineProperty() 来定义)

          [Configurable]:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性的特性,或者能否把属性修改为访问器属性,像前面例子中

            那样直接在对象上定义的属性,他们的这个特性默认为true.

          [Enumerable]: 表示能否通过for-in 循环返回属性。像前面例子中那样直接在对象上定义的属性,它们的这特性默认值为true.

          [Get]: 在读取属性时调用的函数。默认值为undefined。

          [Set]: 在写入属性时调用的函数。默认值为undefined。

            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;
            console.log(book.edition) // 2
            var obj = {
                _x:"obj._x",
              _y:"obj._y",
              _z:"Obj._z"
            }
            Object.defineProperty(obj,"x",{ // x属性,只读不写
              get:function(){
                return this._x;
              }
            });
            console.log(obj.x); // "obj._x"
            obj.x = "Rewrite x"; // 尝试修改x属性
            console.log(obj.x); // "obj.x" 写入失败
            
            Object.defineProperty(obj,"y",{ // y属性,只写不能读
              set:function (newValue){
                this._y = newValue;
              }
              
            });
            console.log(obj.y);      // "undefined" 读取失败
            obj.y = "Rewrite obj.y"; // 尝试修改属性
            console.log(obj._y);      // "Rewrite obj.y" 可以写入

            Object.defineProperty(obj,"z",{
              get:function(){
                return this._z;
              },
              set:function (newValue){
                 this._z = newValue;
              }
            });
            console.log(obj.z);     //"obj.z"
            obj.z = "Rewrite obj.z";   // 修改z 属性
            console.log(obj._z);     // "Rewrite obj.z"

         创建访问器属性一般使用两个标准方法:_defineGetter_()和_defineSetter_()。

        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;
        console.log(book.edition); // 2

        定义多个属性   对象定义多个属性的可能性很大,利用Object.defineProperties()  方法可以通过描述一次定义多个属性。

        var book = {};
        Object.defineProperties(book,{
          _year:{
            value;2004
          },
          edititon:{
            value;1
          },
          year:{
            get:function(){
              return this._year;
            },
            set:function(newValue){
              if(newValue > 2004{
                this._year = newValue;
                this.edition += newValue -2004;
              }
            }
          }
        })

        读取属性的特性     Object.getOwnPropertyDescriptor() 方法可以取得给定属性的描述符,这个方法接收两个参数  属性所在的对象和要读取其描述的属性

              返回是一个对象: 如果是访问器属性,这个对象属性有   configurable,enumerable,get 和set;

                     如果是数据属性 ,这个的对象的属性有 configurable,enumerable,writable和value。   

              var book = {};
              Object.defineProperties(book,{
                _year:{  
                  value;2004
                },
                edition:{
                  value:1
                },
                year:{
                  get:function(){
                    return this._year;
                  },
                  set:funtion(newValue){
                    if(newValue > 2004){
                      this._year = newValue;
                      this.edition += newValue - 2004;
                    }
                  }
                }
              })

              var descriptor = Object.getOwnPropertyDescriptor(book,"_year");
              console.log(descriptor.value); // 2004
              console.log(descriptor.configurable); //false
              console.log(descriptor.get); // undefined
              var descriptor = Object.getOwnPropertyDescriptor(book,"year");
              console.log(descriptor.value); // undefined
              console.log(descriptor.enumerable) // false
              console.log(typeof descriptor.get) // function

    创建对象

        工厂模式 

        function createPerson(name,age,job){
          var o = new Object();
          o.name = neame;
          o.age = age;
          o.job = job;
          o.sayName = function(){
            console.log(this.name)
          };
          return o;
         }
         var person1 = createPerson("Nicholas",29,"Software Engineer");
         var person2 = createPerson("Greg",27,"Doctor")
          // 函数 createPerson() 能够根据接受的参数来构建一个包含所有必要信息的person对象。

           

       构造函数模式

        function Person(name,age,job){
          this.name = name;
          this.age = age;
          this.job = job;
          this.sayName = function(){
            console.log(this.name);
          }
          var person1 = new Person("Nicholas",29,"Software Enginerer");
          var person 2 = new Person("Greg",27,"Doctor");
         }

            要创建Person 的实例,必须使用new 操作符,以这种方式调构造函数实际上会经历以下4个步骤

              1.创建一个行对象。

              2.构造函数的作用域赋给新对象(因此this 就指向了这个新对象)

              3.执行构造函数中的代码(为这个新对象添加属性)

              4.返回新对象。

       原型模式

        function Person(){}
        Person.prototype.name = "Nicholas";
        Person.prototype.age = 29;
        Person.protoype.sayName = function(){
            alert(this.name);
        };
        var person1 = new Person();
        person1.sayName(); // "Nicholas"
        var person2 = new Person();
         person2.sayName();
        alert(person1.sayName == person2.sayName); // true
        

         在实例中无法访问到[[Prototype]],可以通过isPrototypeOf() 方法来确定对象直接是否存在这种关系。

          console.log(Person.prototype.isPrototypeOf(person1)); // true
    
          console.log(Person.prototype.isProtoypeOf(Person2));// true

          Object.getPrototypeOf(),在所有支持的实现中,这个方法返回[[Protoype]]的值。

     console.log(Object.getPrototypeOf(person1) == Person.prototype); // true
    
          console.log(Object.getPrototypeOf(person1).name); // "Nicholas"

         使用delete   操作符则可以完全删除实例属性,可以重新访问原型中的属性。

            function Person(){}
            Person.prototype.name = 'Nicholas';
            Person.prototype.age = 29;
            Person.prototype.job = "Software Engineer";
            Person.protooype.sayName = function(){
              console.log(this.name)
            }
            var person1 = new Person();
            var person2 = new Person();
            person1.name = "Greg";
            console.log(person1.name); // "Greg"    来自实例
            console.log(person2.name); // "Nicholas"   来自原型
            delete person1.name;
            console.log(person1.name); // “Nicholas”  来自原型

          Object.keys()  方法 接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组。

            function Person(){}
            Person.prototype.name = "Nicholas"
            Person.prototype.age = 29;
            Person.prototype.job = "Software Engineer"
            Person.prototype.sayName = function(){
               console.log(this.name);
            }
            var keys =Object.keys(Person.ptototype);
            console.log(keys) // "name,age,job,sayName"

            var p1 = new Person();
            pl.name = "Rob";
            p1.age = 31;
            var p1keys = Object.keys(p1);
            console.log(p1keys); //"name,age"

          无论是否可枚举,都可以使用Object.getOwnPropertyNames();

            var keys = Object.getOwnPertyNames(Person.protoype);
           console.log(keys) // “constructor,name,age,job,sayName”

           对象字面量来重写原型

            function(){}
            Person.prototype = {
              name:"Nicholas",
              age:29,
              job:"Software Engineer",
              sayName:function(){
                console.log(this.name);
              }
            }

          重设构造函数  

          Object.defineProperty(Person.prototype."constructor",{
            enumerable:false,
            value:Person
          })

          实例中的指针仅指向原型,而不执行构造函数

           function Person(){}
           var friend = new Person();
           Person.prototype = {
              constructor:Person,
              name:"Nicholas",
              age:29,
              job:"Software",
              sayName:function(){
                console.log(this.name)
              }
           };
           friend.sayName(); // error

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

           function Person(name,age,job){
              this.name = name;
              this.age = age;
              this.job = job;
              this.friends = ["Shelby","Court"];
           }
          Person.protoype = {
            constructor :Person,
            sayName:function(){
              console.log(this.name)
            }
          }
          var person1 = new Person("Nicholas",29,"Software Engineer");
          var person2 = new Person("Greg",27,"Doctor")

          person1.friends.push("Van");
          console.log(person1.friends); // "Shelby,Count,Van"
          console.log(person2.friends); //"Shelby,Count"
          console.log(person1.friends === person2.frends); // false
          console.log(person1.sayName === person2.sayName); // true

       动态原型模式

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

       寄生构造函数模式

        function Person(){
          var o = new Object();
          o.name = name;
          o.age = age;
          o.job = job;
          o.sayName = function(){
            console.log(this.name)
          }
          return o;
        }
        var friend = new Person('Nicholas',29,"Software Engineer");
        friend.sayName(); //"Nicholas”

         稳妥构造函数模式

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

    继承  (ECMAScript 只支持实现继承,而且实现继承主要依靠)

      原型链

        function SuperType(){
          this.property = true;
        }
        SuperType.protoype.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();
        console.log(instance.getSuperValue()) // true
        // 在调用 instance.getSuperValue() 会经历三个搜索步骤1.搜索实例2.搜索SubType.prototype;3.搜索SuperType.ptototype ,最后一步才会找到方法

          1.所有函数的默认原型都是Object的实例,默认原型会包含一个内部指针,指向 Object.prototype  这也是所有自定义类型都会继承 toString() ,valueOf() 等默认方法的根本原因。

          2.确定原型和实例的关系 (第一种方式是使用instanceof,  第二个方式是使用isPrototypeOf())

            console.log(instance instanceof Object);  // true
            console.log(instance instanceof SuperType) // true
            console.log(instance instanceof SuperType) //true
          
             console.log(Object.prototype.isPrototypeOf(instance)); // true
            console.log(Object.prototype.isPrototypeOf(instance)); // true
    console.log(Object.prototype.isPrototypeOf(instance)); // true

          3.有时候需要重新超类中的某个方法,给原型添加方法一定要房子替换原型语句之后。

            function SuperType(){
              this.property = true;
            }
            SuperType.prototype.getSuperValue = function(){
              return this.property;
            }
            function SubType(){
              this.subproerty = false;
            }
            // 继承了SuperType
            SubType.prototype = new SuperType();
            // 添加新方法
            SubType.prototype.getSubValue = function(){
              return this.subproperty;
            };
            // 重写超类型中的方法,
            SubType.prototype.getSuperValue = function(){
              return false;
            }
            var instance = new SubType();
            console.log(instance.getSuperValue()); // false

           4.原型链的问题 

           function SuPerType(){
                  this.colors = ['red','blue',"green"]
           }
           function SubType(){}
           // 继承了 SuperType
           var instance1 = new SuperType();
          instancel.colors.push("black");
          console.log(instance1.colors);
          
          var instance2 = new SubType();
          console.log(instance2.colors); //"red,blue,green,black"
          var instance2 = new SubType();
          console.log(instance2.colors); // "red,blue,green,black"

      借用构造函数 (函数只不过是在特定环境中执行代码的对象,因此通过使用apply() 和 call() 方法也可以在将来新创建的对象上执行构造函数)

        function SuperType(){
          this.colors = ["red","blue","grren"];
        }  
        function SubType(){
          // 继承了SuperType
          SuperType.call(this);
        }
       var instance1 = new SubType();
       instance1.colors.push("black");
       conole.log(insstance1.colors); // 'red,blue,green,black'
       var instance2 = new SubType();
       console.log(instance2.colors); //"red,blue,green"
       

      组合继承(是将原型链和借用构造函数组合到一起)

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

      原型式继承

        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");
        
        console.log(person.friends); // "Shelby,Court,Van,Rob,Barbie"
        var person = {
          name:"Nicholas",
          friends:["Shelby","Court","Van"]
        }
        var anotherPerson = Object.create(person,{
            name:{
              value:"Greg"
            }
        })
        console.log(anotherPerson.name); // "Greg"

      寄生式继承

      function createAnother(original){
          var clone = Object(original);   // 通过调用函数创建一个新对象
          clone.sayHi = function(){ // 以某种方式来增强增对象
            console.log("hi")
          }
          return clone;    // 返回这个对象   }
      var person = {
        name:"Nicholas",
        friends:["Shelby","Court","Van"]
      };
      var anotherPerson = createAnother(person);
      anotherPerson.sayHi(); // "hi"

      寄生组合式继承

      function SuperType(name){
        this.name = name;
        this.colors = ["red","blue","green"];
      }
      SuperType.prototypes.sayName = function(){
        SuperType.call(this,name); // 第二次调用SuperType
        this.age = age;
      }
      SubType.prototype = new SuperType(); // 第一次调用 SuperType
      SubType.prototype.constructor = SubType;
      subType.prototype.sayAge = function(){
        console.log(this.age)
      }
  • 相关阅读:
    Populating Next Right Pointers in Each Node II
    Populating Next Right Pointers in Each Node
    Construct Binary Tree from Preorder and Inorder Traversal
    Construct Binary Tree from Inorder and Postorder Traversal
    Path Sum
    Symmetric Tree
    Solve Tree Problems Recursively
    632. Smallest Range(priority_queue)
    609. Find Duplicate File in System
    poj3159最短路spfa+邻接表
  • 原文地址:https://www.cnblogs.com/nmxs/p/11993658.html
Copyright © 2011-2022 走看看