1. 程式人生 > >JavaScript初階(六)-------- 繼承發展史、命名空間

JavaScript初階(六)-------- 繼承發展史、命名空間

clas 這也 防止 microsoft 發展史 過多 pre spa highlight

繼承發展史

  繼承發展史一共有四種形式,接下來讓我們看看。

  1.傳統形式

     Fir.prototype.lastName = "stg";
             function Fir() {
                 this.age = 25;
             }
             var fir = new Fir();
             Foo.prototype = fir;
             function Foo() { }
             var foo = new Foo();
             Person.prototype = foo;
             function Person() { }

  

  從代碼中我們可以看出代碼看起來很繁瑣,不美觀,而且繼承起來很麻煩,所以這種形式一開始就out了。

缺點:過多的繼承了沒用的屬性。

  

  2.借助構造函數

      

             function Person1(name,age){ 
                    this.name = name;
                    this.age = age;
                }
                function Person2(name,age){
                    var pObj = Object.create(Person2.prototype);
                    Person1.call(pObj,name,age);
                    return pObj;
                }
                var person = new Person2(‘stg‘,23);

  

    這種方式本質上不叫繼承,因為他是借用call和構造函數,把構造函數Person的this指向改變為自己而已,而且訪問不了原型的原型。

  

      缺點:不能繼承借用構造函數的原型,每次構造函數都要多走一個函數。

3.共享原型

    

 function inherit(origin,target){
                    target.prototype = origin.prototype;
                }
                Person.prototype.lastName = "xiaoming";
                function Person(){ };
                function Son(){ }
                inherit(Person,Son);

  

      缺點:不能隨意改動自己的原型。

  4.聖杯模式

      由於第三種方式中出現的不足,所以我會在中間加一個中間層作為過渡,這也就出現了第四種繼承形式-------聖杯模式。

 function inherit(Origin,Target){
        function Func() { };
        Func.prototype = Origin.prototype;
        Target.prototype = new Func();
    }
    Person.prototype.lastName = "hhh";
    function Person () { }
    function Son() { }
    inhert(Person, Son);

    因為第三種形式中Person和Son的原型都是指向同一個原型,所以改變Person的原型就會是Son的原型發生改變,這裏我們加入一個中間層函數Func過渡,讓它的原型指向Origin的

原型,然後Target的原型繼承它的原型,也就是相當於Target原型繼承Origin的原型,這樣Son改變的時候,Person的原型不會變。再有一點美中不足是,我們知道constructor屬性指向的

是構造這個對象的函數,但是這時候son的constructor指向的是Person,因為Func函數裏面沒有constructor屬性,於是便會隨著原型鏈往上找,於是就找到了Person裏面,這時候我們需

要手動地給son添加一個constructor屬性。

   在開發的時候,我們需要一個叫超類(Uber)的東西,用來查詢這個函數究竟是繼承自誰。最終聖杯模式是這樣的:

 function inherit(Origin,Target){
        function Func() { };
        Func.prototype = Origin.prototype;
        Target.prototype = new Func();
        Target.prototype.constructor = Target;
        Target.prototype.uber = Origin.prototype;
    }

  

  利用閉包的私有化變量,我們可以將聖杯模式寫的更加高級一點

var inherit = (function () {
        var Func = function () { };
        return function (origin,target) {
        Func.prototype = Origin.prototype;
        Target.prototype = new Func() ;
        Target.prototype.constructor = Target;
        Target.prototype.uber = Origin.prototype;
    }
}())//**********function與函數Func產生閉包


命名空間

      作用:管理變量,防止汙染全局,適用於模塊化開發

      在開發的時候,往往每個人用到的變量不同,團隊開發時就會有變量沖突,我們可以用對象來解決,因為每個對象裏面的東西都是獨立的,互不幹擾。

org = {
    person: {
        xiaoming : {
        age : 20,
        sex : "male"
        },
        xiaozhang : {
        age : 22,
        sex : "female"
        }
    }
}
var per1 = org.person.xiaoming.age;
var per2 = org.person.xiaozhang.age;

采用對象來解決變量沖突問題是以前用的方法,現在我們可以用閉包來解決這一問題。

 var add = (function () {
                var count1 = 1;
                var count2 = 0;
                function myAdd(num1, num2){
                    count1 = num1;
                    count2 = num2;
                    console.log(count1 + count2);
                }
                return myAdd(count1,count2);
            }())

類似於私有化變量來解決命名沖突,只有在於自己產生閉包的變量才能訪問到。

JavaScript初階(六)-------- 繼承發展史、命名空間