JS 面向對象之對象的建立

在學習了面向對象,咱們瞭解了面向對象的三大特性:封裝、繼承、多態。下面咱們須要瞭解對象的建立方式:css

1 字面量建立方式

對象有不少描述方式,好比鍵值對(key--value)的集合、字典、工具包。對象的本質是對變量和函數進行封裝,將變量封裝成屬性,函數封裝爲方法;這裏咱們就是採用字典的方式來建立對象,將屬性和方法名做爲keyhtml

1.1 建立一個書對象
 
var book = {
    name:"js入門教學",
    price:"¥34",
    author:"劉忻歡",
    showName: function () {
        console.log(this.name);
    }
}
/*調用對象 */
console.log(book.name);
 

特色:字面量建立方式比較簡單,把方法和屬性寫在{}中,可是當須要建立多個同類型的對象的時候,代碼的重複性就比較高,它不適用於批量的建立同類型的對象。函數

1.2 建立多個書對象
 var book1 = {
        name:"js入門教學",
        price:"¥34",
        author:"劉忻歡",
        showName: function () {
            console.log(this.name);
        }
    }
    var book2 = {
        name:"html+css深刻淺出",
        price:"¥50",
        author:"張某某",
        showName: function () {
            console.log("jjjj");
        }
    }

 

2 內置構造函數建立方式

js內置構造函數有:Object   Function  Date   String   Number   Array  .....工具

建立方式分爲兩步:性能

 /*首先 建立一個空對象*/
    var obj = new Object();

    /*其次  設置屬性|方法*/
    obj.name="內置構造函數建立對象";
    obj.ways = function () {
        console.log("2步");
    }

 

特色:利用內置構造函數建立對象和字面量方式建立同樣,須要建立多個同類型的對象時,會出現大量重複的代碼。學習

 

3 簡單工廠函數建立對象方式

3.1 建立書的工廠函數this

    function createBook(name,author,price){
        /*建立一個空對象*/
        var book = new Object();
        book.name = name;
        book.author = author;
        book.price = price;
        book.log = function () {
            console.log("eee");
        }
        return book;
    }

3.2 建立多個書對象spa

    var book1 =new createBook("三毛流浪記","張樂平","南方出版社");
//         打印書名
        console.log(book1.name);
    var book2 = new createBook("阿衰","貓小樂","雲南出版集團公司");
//       打印book2對象
        console.log(book2);

特色:① 利用工廠函數建立對象,只要經過 new 函數()  就能夠建立出不一樣的對象 。prototype

        ② 可是有多個工廠函數,且屬性和方法相同時,建立出來的對象就沒法識別對象的類型,由於建立對象都是使用Object的原生構造函數來完成的。3d

3.3 多個工廠函數

 function createPerson(name,age,eating){
        var person = new Object();
        person.name = name;
        person.age = age;
        person.eat = function () {
            console.log(eating);
        }
return person; }
function createDog(name,age,eating){ var dog = new Object(); dog.name = name; dog.age = age; dog.eat = function () { console.log(eating); }
return dog; }

構造了建立人和狗的兩個方法,他們的屬性和方法同樣

 var person1 = new createPerson("小明","23","吃米飯");
    var dog1 = new createDog("小小明","2","狗糧");

    console.log(person1);
    console.log(dog1);

打印結果:

 

 

 

 

 

 

 

 

 

 

 

 

問題:咱們沒辦法區分哪一個對象是 createPerson方法建立 ,哪一個是createDog  方法建立

總結:爲何將這種方式叫作工廠呢,由於它的模式和工廠十分類似。工廠的特色:批量生產(原料 --- 加工 --- 產品)

 

4 自定義構造函數建立對象方式

什麼是構造函數:① 構造函數和普通函數本質上沒有區別

                       ② 構造函數一般首字母大寫(這是爲了 人爲的區分)

                       ③ 在調用時,構造函數必需要和 new關鍵字 結合

 

4.1 構造函數的核心過程

                      ① 提供一個構造函數

                      ② 在構造函數內部經過 this  設置屬性和方法

                      ③ 經過 new 函數() 建立對象

/*1 提供一個構造函數*/
    function Person(){
         /* 2 在函數內部經過  this 設置屬性和方法*/
        this.name = "張三";
        this.age = 23;
        this.sex ="男";
    }
    /*3 經過 new 函數() 來建立對象*/
    var zhangsan =new Person();
    console.log(zhangsan);

自定義構造函數建立對象須要咱們完成的核心過程就這三步,可是其內部默認完成的工做其實複雜的多:

內部實現細節:

             ① 默認在內部會建立一個空的對象   var o = new Object();

             ② 默認會把新建立的對象賦值給 this   this = o;

             ③ 默認會設置新建立的對象的原型對象爲當前的原型對象   o.prototype = Person.prototype;

             ④ 默認會設置新建立對象的構造器屬性爲當前構造器屬性    o.constructor = Person

             ⑤ 經過 this設置屬性和方法(這是咱們本身完成的操做)

             ⑥ 默認會返回新建立的對象     return o;

注意點:

          Ⅰ.若是咱們沒寫  return   ,那麼默認返回新建立的對象

          Ⅱ. 若是咱們寫了 return:

                 ⅰ.若是返回的是值類型(null |  undefined | "string" | number...),那麼咱們本身寫的 return 語句會被忽略,返回的仍然是新建立的對象;

                 ⅱ. 若是返回的是引用類型,那麼就會直接返回 咱們寫的 renturn 後面的對象,而內部默認建立的 return 會被忽略。

 

4.2 對注意點的驗證

當返回數值類型:

 /*1 提供一個構造函數*/
    function Person(){
         /* 2 在函數內部經過  this 設置屬性和方法*/
        this.name = "張三";
        this.age = 23;
        this.sex ="男";
        return "zzzzz;
    }
    /*3 經過 new 函數() 來建立對象*/
    var zhangsan =new Person();
    console.log(zhangsan);

輸出結果:

 

 

 

 

 

 

當返回引用類型:

 

  /*1 提供一個構造函數*/
    function Person(){
         /* 2 在函數內部經過  this 設置屬性和方法*/
        this.name = "張三";
        this.age = 23;
        this.sex ="男";
        return Array("zhang",1,3,6);
    }
    /*3 經過 new 函數() 來建立對象*/
    var zhangsan =new Person();
    console.log(zhangsan);

 

輸出結果:

4.3 利用自定義構造函數建立不一樣類型的對象
  function Person(name,age,eating){
        this.name = name;
        this.age = age;
        this.eat = function(){
            console.log(eating);
        }
    }
    function Dog(name,age,eating){
        this.name = name;
        this.age = age;
        this.eat = function(){
            console.log(eating);
        }
    }

    var person1 =new Person("張撒",23,"食物");
    var dog1 =new Dog("阿黃",2,"狗糧");
    console.log(person1);
    console.log(dog1);

    /* 採用類型判斷*/ console.log(person1 instanceof Person); console.log(dog1 instanceof Dog);

輸出結果:

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

注意點:全部的對象都是Object類型,所以全部對象  obj1 instanceof Object  的返回值都是true.

總結:

自定義構造函數建立對象可以區分對象的類型

4.3 構造函數建立對象的問題

 

 function Person(name,age,sex){
        this.name = name;
        this.age = age;
        this.sex =sex;
        this.showName = function () {
            console.log(this.name);
        }
    }
    var person1 = new Person("zhangsan",23,"男");
    var person2 = new Person("zhangsan",22,"女");
    console.log(person1.showName ==person2.showName);  //false
    person1.showName = function () {
        console.log("123");
    }
    person1.showName();   //123
    person2.showName();   //zhangsan

對代碼建立對象結構分析以下:

 

總結:由輸出結果以及結構分析,能夠看出person1.showName  與 person2.showName 是不一樣的,他們各佔一個內存空間,這樣當要建立大量的對象的時候,就會建立出大量一樣的 方法,這樣會浪費性能空間,那麼如何讓不一樣的對象共享同一個方法呢?下一章我將爲你們分析  採用原型對象解決方法共享問題。

 

eating
相關文章
相關標籤/搜索