JavaScript 對象及初識面向對象

1)回顧JavaScript 數據類型

        

2)對象是什麼

        1.對象是包含相關屬性和方法的集合體

            1-1:屬性

            1-2:方法

        2.什麼是面向對象

            2-1:面向對象僅僅是一個概念或者編程思想

            2-2:通過一種叫做原型的方式來實現面向對象編程

3)創建對象

1.自定義對象

                基於Object 對象的方式創建對象

                語法:

                var  對象名稱 = new Object();

栗子一:   基於Object 對象的方式創建對象

<script>
    var flowe=new Object();
    //添加屬性
    flowe.name="長春花";
    flowe.genera="長春花園";
    flowe.areas="ssabvbvhvdhv";
    flowe.uses="觀賞";
    //添加方法
    flowe.showName=function()
    {
        alert(flowe.name);
    }
    flowe.showName();
</script>

栗子二:    使用字面量賦值方式創建對象

    var flowe1=
    {
        name:"長春花",
        genera:"長春花園",
        areas:"ssabvbvhvdhv",
        uses:"觀賞",
        showName:function()
        {
            alert(this.name);
        }
    }
    flowe1.showName();

2)內置對象

+常見的內置對象

1.    String                (字符串)對象

2.    Date                    (日期)對象

3.    Array                    (數組)對象

4.    Boolean                (邏輯)對象

5.    Math                    (算數)對象

6.    RegExp                    對象  

---String(字符串)對象

    1.length    屬性

    2.indexOf()方法        replace()方法

---Date(日期)對象

var time = new Date();//獲取系統時間
var hh = time.getHours();//獲取系統小時
var mm = time.getMinutes();//獲取系統分鐘
var ss = time.getSeconds();//獲取系統秒數

---Array(數組)對象

    1. length屬性

    2.sort()、concat()、join()方法

---Boolean(邏輯)對象

    1.true 或者 false

    2.toString()方法

---Math(算數)對象

    1.round()、max()、min()方法

    ....................

---RegExp對象

    RegExp是正則表達式的縮寫

3)構造函數


小栗子:

<script>
    function Flowe(name,genera,areas,uses)
    {
        this.name=name;
        this.genera=genera;
        this.areas=areas;
        this.uses=uses;
        this.showName=function()
        {
            alert(this.name);
        };
    }
    var Flowe1=new Flowe("長春花","長春花園","ssabvbvhvdhv","觀賞");
    Flowe1.showName();
    var Flowe2=new Flowe("野蠻書","長春花園","ssabvbvhvdhv","觀賞");
    Flowe2.showName();
    var Flowe3=new Flowe("也漫畫","長春花園","ssabvbvhvdhv","觀賞");
    Flowe3.showName();
</script>

使用構造函數創建新實例:調用構造函數的4個步驟

    1.創建一個新對象

    2.將構造函數的作用域賦給新對象(this就指向了這個新對象)

    3.執行構造函數中的代碼

    4.返回新對象

constructor屬性 檢測對象類型

constructor屬性指向Flower

alert(Flowe1.constructor == Flowe);

alert(Flowe2.constructor == Flowe);

alert(Flowe3.constructor == Flowe);


instanceof操作符檢測對象類型

alert(Flowe1 instanceof Object);
alert(Flowe1 instanceof Object);
alert(Flowe2 instanceof Object);
alert(Flowe2 instanceof Flowe);
alert(Flowe3 instanceof Flowe);
alert(Flowe3 instanceof Flowe);

栗子修改代碼如下:

把方法寫成全局方法:調用

<script>
    function Flowe(name,genera,areas,uses)
    {
        this.name=name;
        this.genera=genera;
        this.areas=areas;
        this.uses=uses;
        this.showName=showName;
    }
    function showName()
    {
        alert(this.name);
    }
    var Flowe1=new Flowe("長春花","長春花園","ssabvbvhvdhv","觀賞");
    Flowe1.showName();
    var Flowe2=new Flowe("野蠻書","長春花園","ssabvbvhvdhv","觀賞");
    Flowe2.showName();
    var Flowe3=new Flowe("也漫畫","長春花園","ssabvbvhvdhv","觀賞");
    Flowe3.showName();
    alert(Flowe1.showName==Flowe2.showName)//判斷函數是否相等

同樣也可以實現效果,但是這樣的寫法就沒有了 封裝性可言   不安全 

那怎麼解決那  , 那就耐心點接着往下看

3-1)原型對象

        1.  每個函數都有一個prototype屬性,這個屬性是一個指針,指向一個對象。

        2. prototype就是通過調用構造函數而創建的那個對象實例的原型對象

小栗子:


原型對象的代碼  小栗子:

<script>
    function Flowe()
    {
    }
    Flowe.prototype.name='長春花';
    Flowe.prototype.genera="長春花園";
    Flowe.prototype.areas="ssabvbvhvdhv";
    Flowe.prototype.uses="觀賞";
    Flowe.prototype.showName=function()
    {
        alert(this.name);
    };
    var Flowe1=new Flowe();
    Flowe1.name='曼陀羅花';//註釋掉  可以看到 兩個對象是一樣的值,這裏是更改 Flowe1的值
    Flowe1.showName();
    var Flowe2=new Flowe();
    Flowe2.showName();
    alert(Flowe1.showName==Flowe2.showName);
</script>

提示:原型對象的創建 解決了構造函數當中的一個減少方法實例的創建,實現了封裝

原型對象的結構圖:


4)JavaScript 繼承

        1.原型鏈         2.對象繼承

原型鏈圖:


1.  一個原型對象是另一個原型對象的實例

2.  相關的原型對象層層遞進,就構成了實例與原型的鏈條,就是原型鏈

原型鏈小栗子:


原型鏈代碼小栗子:

<script>
    function Humans()
    {
        this.foot=2;
    }
    Humans.prototype.getFoot=function()
    {//原型對象添加方法
        return this.foot;
    }
    function Man()
    {
        this.head=1;
    }
    //Man繼承Humans
    Man.prototype=new Humans();
    Man.prototype.getHead=function()
    {//原型對象添加方法
        return this.head;
    }
    var man1=new Man();
    alert(man1.getFoot());//2
    alert(man1.getHead());//1
    alert(man1 instanceof Object);//true
    alert(man1 instanceof Humans);//true
    alert(man1 instanceof Man);true
</script>


調用man1.getFoot() 經歷的三個步驟

1.搜索實例

2.搜索Man.prototype

2.搜索Humans.prototype

如果沒有搜索到則產生下列圖:完整原型鏈


4-2)對象繼承

<script>
    function Humans()
    {
       this.clothing=["aaa","bbb","ccc"];
    }
    function Man()
    {
    }
    //Man繼承Humans
    Man.prototype=new Humans();
    var man1=new Man();
    man1.clothing.push("ddd");//數組添加信息
    alert(man1.clothing);
    var man2=new Man();
    alert(man2.clothing);
</script>

打印結果爲:兩次都是一樣的


爲什麼是一樣的那?

    創建子類型的實例時,不能向父類型的結構函數中傳遞參數

解決方案:使用借用構造函數

    思想:

    借用構造函數的基本思想。就是在子類構造函數當中  調用父類構造函數。

    其子類構造的內部通過  apply()  或  call()去調用父類型的構造函數,來實現屬性和方法的繼承。

    


    

    修改代碼如下的 小栗子:實現  實現屬性  和  方法的繼承。進行私有化

<script>
    function Humans()
    {
       this.clothing=["aaa","bbb","ccc"];
    }
    function Man()
    {
        Humans.call(this);
    }
    //Man繼承Humans
   // Man.prototype=new Humans();
    var man1=new Man();
    man1.clothing.push("ddd");//數組添加信息
    alert(man1.clothing);
    var man2=new Man();
    alert(man2.clothing);
</script>

借用構造函數 的一個大的優勢:

    1.可以在子類型構造函數中向父類型構造函數傳遞參數

小實例:


代碼小栗子:

<script>
    function Humans(name)
    {
      this.name=name;
    }
    Humans.prototype.showName="sss";
    function Man()
    {
        Humans.call(this,"mary");
        this.age=38;
    }
    var man1=new Man();
    alert(man1.name);
    alert(man1.age);
</script>
運行結果:

沒有問題。


那麼我們現在有個新的問題:如果我 通過原型鏈給 父類添加一個屬性,那麼又會怎麼樣那?

稍作修改代碼如下:

<script>
    function Humans(name)
    {
      this.name=name;
    }
    //原型鏈方式添加屬性
    Humans.prototype.showName="sss";
    function Man()
    {
        Humans.call(this,"mary");
        this.age=38;
    }
    var man1=new Man();
    alert(man1.name);
    alert(man1.age);
    alert(man1.showName);
</script>
運行結果如下:


showName,undefined  沒有值。爲什麼會這樣那? 又該如何使用 或者 複用父類的方法 或 屬性那那?

接着往下看一種方式

組合繼承:

組合繼承:有時也叫做僞經典繼承

    1.將原型鏈和借用構造函數的技術組合到一塊,發揮二者之長的一種繼承模式。

    2.使用原型鏈實現對原型屬性和方法的繼承,而通過借用構造函數來實現對實例屬性的繼承

修改後的代碼:

<script>
    function Humans(name)
    {
      this.name=name;
    }
    //原型鏈方式添加屬性
    Humans.prototype.showName="sss";
    function Man()
    {
        //調用構造函數實現實例屬性的繼承
        Humans.call(this,"mary");
        this.age=38;
    }
    //繼承Humans
    Man.prototype=new Humans();
    Man.prototype.getAge=function()
    {
        return this.age;
    }
    var man1=new Man();
    alert(man1.name);
    alert(man1.getAge());
    alert(man1.showName);
</script>
運行結果:



補充一點:

如果兩個函數的名稱一樣,則會執行最後一個函數,覆蓋之前的函數。

從上到下執行



發佈了65 篇原創文章 · 獲贊 20 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章