Javascript面向对象

简书上看到了关于Javascript面向对象的一些文章,突然也想写一点自己的见解。

按人们认识客观世界的系统思维方式,采用基于对象(实体)的概念建立模型,模拟客观世界分析、设计、实现软件的办法

  • 为什么要面相对象?
  • 首先要了解什么是面向对象,面向对象有哪些特性。我在网上查到关于面相对象现在还没有统一的概念,如果没有统一的概念,我就先随便找个差不多的概念吧。如上,简单的说就是一切都是对象,什么是对象,对象就是对现实世界的抽象。
  • 面相对象有什么特性,我在百度百科上找到几个,然后展开来说。
    • 对象唯一性:对象是对现实世界的抽象,现实世界每样东西都是唯一的,所以对象也是唯一的。
    • 抽象性:对象是对现实世界的抽象,比如说我们抽象人的概念,每个人都有姓名,性别,年龄等等,但是每个人又有不通的性格,然后我们把他抽象了出来,这就是抽象性
    • 继承性:还是人的概念,我们抽象的东西为了实现能够多次的复用,我们一类具有相同属性的东西抽离出来,用于继承这样就能实现代码最大程度上的精简,并且富有逻辑,人类社会不就是这样的么,小明和小红的孩子身上会有小红和小明身上的一些特质,当然,他们的孩子身上也会有,一些小红和小明身上没有的特质。正式因为有这个特性,社会才会进步。
    • 多态性:还是用人来举例子,每个人都有不同的名字,我叫每个人,每个人都会回答给我不一样的名字,但是我用了同样的方法去提问,这就是多态性,相同的方法,在不通的对象上体现出来的结果也是不同的。

Javascript如何实现面向对象,要讲Javascript面向对象之前首先要讲一下下面这些神奇的东西。

  • this:对于Javascript来说,一切都是function,那么this的作用域就只是在function里面。这个其实很好理解,但是如果不实际操作那就不一定了,用代码说话。

          var name = "ben";
          //ben作用域是this.Window
          function persion() {
              alert(this.name);
              //benalert(name);
              //benthis.name = "jill";//ben
              function showAge() {
                  var age = 25;
                  alert(this.name);//jill
                  alert(this.age);
                  //undifine 作用域是
                  //**this.window, age 的作用域在showAge这个方法中**
              }
          
              showAge();
          }
          alert(name);//ben
          alert(this.name);//ben
          persion();
    
* **prototype**:这个东西太他妈重要了,要是不知道的话,别逼我骂人。

    //首先说明原型
    //这里先借用一个例子
    //来自
    //http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html
    
    function DOG(name) {
        this.name = name;
        this.species = '犬科';
    }
    
    var dogA = new DOG('大毛');
    var dogB = new DOG('二毛');
    
    dogA.species = '猫科';
    alert(dogB.species); //示犬科",不受dogA的影响
    
    //下面是原型     
    
    
    function DOG(name) {
        this.name = name;
    }
    DOG.prototype = {species: '犬科'};
    var dogB = new DOG('二毛');
    alert(dogA.species); // 犬科
    alert(dogpecies); // 犬科
    
    //下面是借用原型的实现
    
    function Persion(name, age) {
        this.myName = name;
        this.myAge = age;
    }
    
    persion.prototype = {
        showName: function () {
            alert(this.myName);
        },
        showAge: function () {
            alert(this.myAge);
        }
    
    }
    
    //这样一个人就抽象好了
    
    var jack = new Persion("jack", 25);
    var shell = new Persion("shell", 25);
    
    jack.showName(); //jack
    shell.showName();//shell
* **constructor**

    ```javascript
        //其实就是一只构造函数
        function Persion(name, age) {
            this.myName = name;
            this.myAge = age;
        }
        Persion.prototype.showName = function () {
            alert(this.myName);
        };
        alert(Persion.constructor);
        var jack = new Persion("jack", 25);
        alert(jack.constructor);
        
        //但是constructor是会被覆盖的
        function Persion2(name, age) {
            this.myName = name;
            this.myAge = age;
        }
        Persion2.prototype = {
            showName: function () {
                alert(this.myName)
            }
        }
        alert(Persion2.constructor);
        var rose = new Persion("rose", 25);
        alert(rose.constructor);
        //所以如果要用,并不安全,但是我们也要把他给考虑进去
        
        
    ```     
            
            
* **call/apply**
    
    ```javascript
        //这个玩意儿相当的重要,重要到无法代替。
        //例子还是要举起来
        function Persion(name, age) {
            this.name = name;
            this.age = age;
        }
        
        function Student(name, age, school) {
            Persion.call(this, name, age, school)
            this.school = school;
        }
        
        Student.prototype = {
            showName: function () {
                alert(this.name);
            },
            showSchool: function () {
                alert(this.school);
        
            }
        }
        
        var jack = new Student("Jack", "24", "Jialidun");
        jack.showName(); // Jack
        jack.showSchool();//Jialidun
    ```
    
    
* **arguments**

    ```
    //这个玩意给我们提供了太多的方便,难以言喻。
    function Persion(name, age) {
        this.name = name;
        this.age = age;
    }
    Persion.prototype = {
        setSkills: function () {
            for (var item in arguments) {
                alert(arguments[item]);
            }
        }
    }
    
    var jack = new Persion("Jack", "24");
    jack.setSkills("java", "javascript", "css", "Node.js");
    //这个例子充分表明了这个家伙是干什么用的。  
    
    ``` 
    
####基本概念讲完了,下面讲几个我见到过在项目里面做继承的几个示范:
---
* **第一个示范**
    
        /**
        * 实现继承类
        * @private _object
        * */
        function _object (o) {
             function F() {
             };
            F.prototype = o;
            return new F();
        }
    
    
        /**
        *
        * 实现继承
        * @method inherit
        * @private
        * @param {Object} subType 子类
        * @param {Object} superType 超类
        * */
        function inherit (subType, superType) {
            var p = _object(superType.prototype);
            p.constructor = subType;
            subType.prototype = p;
        }
        
        function Persion(name,age){
            this.name = name;
            this.age = age;
        }
        
        Persion.prototype = {
            showName:function(){
                alert(this.name);
            },
            showAge:function(){
                alert(this.age);
            }
        }
        
        function Student(name,age,school){
            Persion.call(this,name,age);
            this.school = school;
        } 
        
        inherit(Student,Persion);
        
        Student.prototype.showSchool =  function(){
                alert(this.school);
        }
        
        var jack = new Student("Jack",25,"jialidun");           
        jack.showName();
        jack.showSchool();
    

        
* **第二个示范**
    
        function Persion(name,age){
            this.name = name;
            this.age = age;
        }
        
        Persion.prototype = {
            showName:function(){
                alert(this.name);
            },
            showAge:function(){
                alert(this.age);
            }
        }
        
        function Student(name,age,school){
            Persion.call(this,name,age);
            this.school = school;
        } 
        
        Student.prototype = new Persion(); //这块累赘了
        //你知道如果这块不这样,像下面那样
        //Student.prototype 和 Persion.prototype 就将是绑定死的
        //意思就是如果你改变Student.prototype中的东西
        //Persion.prototype也会变,很危险
        //孩子怎么能影响父亲呢,大逆不道不是
        //Student.prototype = Persion.prototype

        Student.prototype.showSchool =  function(){
                alert(this.school);
        }
        
        var jack = new Student("Jack",25,"jialidun");
        jack.showName();
        jack.showSchool();

* **第三个示范**这个例子来自 [Leaflet](http://leafletjs.com/reference.html)    
    

        /*
         * L.Class powers the OOP facilities of the library.
         * Thanks to John Resig and Dean Edwards for inspiration!
         */
         L = {};
         L.Util ={
        
         extend: function (dest) {
            var i, j, len, src;
        
            for (j = 1, len = arguments.length; j < len; j++) {
              src = arguments[j];
              for (i in src) {
                dest[i] = src[i];
              }
            }
            return dest;
          },
          // create an object from a given prototype
          create: Object.create || (function () {
            function F() {}
              return function (proto) {
                F.prototype = proto;
                return new F();
            };
          })()}
        
        L.Class = function () {};
        
        L.Class.extend = function (props) {
        
          // extended class with the new prototype
          var NewClass = function () {
        
            // call the constructor
            if (this.initialize) {
              this.initialize.apply(this, arguments);
            }
        
            // call all constructor hooks
            this.callInitHooks();
          };
        
          var parentProto = NewClass.__super__ = this.prototype;
        
          var proto = L.Util.create(parentProto);
          proto.constructor = NewClass;
        
          NewClass.prototype = proto;
        
          // inherit parent's statics
          for (var i in this) {
            if (this.hasOwnProperty(i) && i !== 'prototype') {
              NewClass[i] = this[i];
            }
          }
        
          // mix static properties into the class
          if (props.statics) {
            L.Util.extend(NewClass, props.statics);
            delete props.statics;
          }
        
          // mix includes into the prototype
          if (props.includes) {
            L.Util.extend.apply(null, [proto].concat(props.includes));
            delete props.includes;
          }
        
          // merge options
          if (proto.options) {
            props.options = L.Util.extend(L.Util.create(proto.options), props.options);
          }
        
          // mix given properties into the prototype
          L.Util.extend(proto, props);
        
          proto._initHooks = [];
        
          // add method for calling all hooks
          proto.callInitHooks = function () {
        
            if (this._initHooksCalled) { return; }
        
            if (parentProto.callInitHooks) {
              parentProto.callInitHooks.call(this);
            }
        
            this._initHooksCalled = true;
        
            for (var i = 0, len = proto._initHooks.length; i < len; i++) {
              proto._initHooks[i].call(this);
            }
          };
        
          return NewClass;
        };
        
        
        // method for adding properties to prototype
        L.Class.include = function (props) {
          L.Util.extend(this.prototype, props);
        };
        
        // merge new default options to the Class
        L.Class.mergeOptions = function (options) {
          L.Util.extend(this.prototype.options, options);
        };
        
        // add a constructor hook
        L.Class.addInitHook = function (fn) { // (Function) || (String, args...)
          var args = Array.prototype.slice.call(arguments, 1);
        
          var init = typeof fn === 'function' ? fn : function () {
            this[fn].apply(this, args);
          };
        
          this.prototype._initHooks = this.prototype._initHooks || [];
          this.prototype._initHooks.push(init);
        };
        
        //现在开始使用了
        Persion = L.Class.extend({
          options:{
            name:"",
            sex:"",
            age:""
          },
          initialize:function(options){
            this.name = options.name;
            this.sex = options.sex;
            this.age = options.age;
          },
          showName:function(){
            alert(this.name);
          }
        });
        
        Student = Persion.extend({
           options:{
            name:"",
            sex:"",
            age:"",
            school:"",
            score:""
          },
          initialize:function(options){
            Persion.prototype.initialize.call(this, options);
            this.school = options.school;
            this.score = options.score;
          },
          showSchool:function(){
            alert(this.school);
          }
        })
        
        var jack = new Student({
            name:"jack",
            sex:"man",
            age:"25",
            school:"Beijing University",
            score:"A++"
        });
        
        jack.showSchool();          
         
这个继承有点长,但是很用,很有启发。简单写了一下用法,但是不全。


>name:Jack

>QQ:84201088

>blog:[http://gdyblog.com](http://gdyblog.com)
    原文作者:JackGood
    原文地址: https://www.jianshu.com/p/617db1b5d943
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞