在學習了面向對象,咱們瞭解了面向對象的三大特性:封裝、繼承、多態。下面咱們須要瞭解對象的建立方式:css
對象有不少描述方式,好比鍵值對(key--value)的集合、字典、工具包。對象的本質是對變量和函數進行封裝,將變量封裝成屬性,函數封裝爲方法;這裏咱們就是採用字典的方式來建立對象,將屬性和方法名做爲keyhtml
var book = { name:"js入門教學", price:"¥34", author:"劉忻歡", showName: function () { console.log(this.name); } } /*調用對象 */ console.log(book.name);
特色:字面量建立方式比較簡單,把方法和屬性寫在{}中,可是當須要建立多個同類型的對象的時候,代碼的重複性就比較高,它不適用於批量的建立同類型的對象。函數
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"); } }
js內置構造函數有:Object Function Date String Number Array .....工具
建立方式分爲兩步:性能
/*首先 建立一個空對象*/ var obj = new Object(); /*其次 設置屬性|方法*/ obj.name="內置構造函數建立對象"; obj.ways = function () { console.log("2步"); }
特色:利用內置構造函數建立對象和字面量方式建立同樣,須要建立多個同類型的對象時,會出現大量重複的代碼。學習
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 方法建立
總結:爲何將這種方式叫作工廠呢,由於它的模式和工廠十分類似。工廠的特色:批量生產(原料 --- 加工 --- 產品)
什麼是構造函數:① 構造函數和普通函數本質上沒有區別
② 構造函數一般首字母大寫(這是爲了 人爲的區分)
③ 在調用時,構造函數必需要和 new關鍵字 結合
① 提供一個構造函數
② 在構造函數內部經過 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 會被忽略。
當返回數值類型:
/*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);
輸出結果:
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.
總結:
自定義構造函數建立對象可以區分對象的類型
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