javascript面向對象(一)
對象其實就是一種引用類型。而對象的值就是引用類型的實例。在JavaScript 中引用類型是一種數據結構,將數據和功能組織在一塊兒。javascript
它也常被稱作爲類,但JavaScript 中卻沒有類的概念。雖然JavaScript 是一門面向對象的語言,卻不具有傳統面嚮對象語言所支持的類和接口等基本結構。html
對象的建立以及經常使用操做
-
使用new運算符java
var user = new Object(); //使用new運算符建立一個對象 user.name = '李銘'; //給對象添加屬性 user.age = 21; user.address = '四川成都';
-
對象字面量(JSON方式)編程
var user = { name:'王五', age:22, address:'四川成都' };
-
簡單方式(傳統賦值方式)數據結構
var user = {}; user.name = '王五'; //給對象添加屬性 user.age = 22; user.address = '四川成都';
-
屬性的調用函數
對於對象屬性的調用有兩種方式:post
調用方法以下:測試
alert(user.name + " " +user.age);this
-
//返回 '
王五
四川成都'spa另外一種方法:
alert(user['name'] + " " +user['age']);
-
//返回 '
王五
四川成都' -
添加方法
var user = { name:'王五子', //給對象添加屬性 age:22, address:'四川成都', showInfo:function(){//添加一個方法 alert(this.name+" "+this.age+" "+this.address); }, showHello:showHello//將對象外部的方法添加到對象 }; function showHello(){ alert("Hello!"); } user.showInfo();//調用方法 user.showHello();
javascript面向對象(二)
建立對象
咱們知道,要建立一個對象咱們能夠用以下代碼:
var user = new Object(); user.name = '趙六'; user.age = 22; user.address = '四川成都';
用這樣的方法建立對象比較簡單直觀,也是JavaScript種建立對象最基本的方法。可是這樣就有一個問題,若是咱們須要建立多個對象,
那麼我就得寫不少重複的代碼。好比咱們想建立另外一個對象user1,咱們就得從新將上面的代碼從新寫一遍,這在實際開發過程當中是不合適的,
這樣若是對象過多,代碼量將大大增長。
爲了解決這樣的問題,咱們可使用一種叫作工廠模式的方法,這種方法 就是爲了解決實例化對象產生大量重複代碼的問題。
工廠模式
function create(name, age) { var obj = new Object(); obj.name = name; obj.age = age; obj.show = function () { return this.name +' '+ this.age; }; return obj; } var obj1= create('bclz', 30); //第一個實例 var obj2= create('bcxb', 20); //第二個實例 alert(obj1.show()); alert(obj2.show());
從上面的代碼咱們能夠看出,工廠模式解決了實例化時代碼大量重複的問題,但又出現了一個問題,那就是識別問題,咱們根本沒法弄清楚他們究竟是哪一個對象的實例。好比
alert(typeof obj1); //Object alert(obj1 instanceof Object); //true
以上代碼標明obj1是Object對象,可是咱們沒法知道具體是哪個對象建立的。
構造函數(構造方法)
function User(name, age) { //構造函數模式 this.name = name; this.age = age; this.show = function () { return this.name + ' '+this.age; }; }
建立對象的時候用new運算符就能夠了:
var user1 = new User('bclz', 30); //第一個實例 var user2 = new User('bcxb', 20); //第二個實例
如今咱們就能夠檢測user1或者user2是否是屬於User。
alert(user1 instanceof User);//true
可見,使用構造函數的方法,即解決了重複實例化的問題,又解決了對象識別的問題。
要建立User對象的新實例,就要使用new操做符,使用這個方式構建實例對象,會通過下面4個步驟:
1.建立一個新對象;
2.將構造函數的做用域給新對象(所以this指向的這個新對象)。
3.執行構造函數內的代碼在(爲新對象添加屬性);
4.返回新對象。
不過須要注意下面兩個問題:
構造函數也是函數
構造函數與函數的惟一區別,就是調用方式的不一樣,不過,構造函數畢竟也是函數,不存在什麼特殊的定義構造函數的語法。
任何函數,只要經過new操做符來調用,就能夠把它看做是構造函數;而任何函數,若是不經過new操做符調用,它就和普通函數沒有什麼區別,例如前面定義的User:
//看成構造函數調用
var user1 = new User('bclz', 30); user1.show(); //bclz 30; //看成普通函數調用 User('bclz', 30); window.show(); //bclz 30;
結果上沒有什麼區別,只是你們能夠看到,看成普通函數調用的話,函數裏this對象的指向,實際上是指向的window全局對象。而經過new關鍵字調用,this指向的則是新對象而已,因此,其實還能夠這麼來寫:
var o = new Object(); User.call(o,'bclz', 30); o.show();
經過函數方法call來從新定義對象的做用域,這裏很少作解釋,講到函數細節時再仔細介紹這種方法,這裏只是說明能夠改變對象的做用域的,其實就是改變this的指向
構造函數的問題
構造函數的模式雖然好,可是並不是沒有缺點。構造函數最大的問題就是,每一個方法都要在實例上從新建立一次。在前面的例子中,user1和user2中都有一個show方法,若是咱們執行如下語句:
alert(user1.show==user2.show);//結果返回的是false
結果返回的是false,這就說明方法其實也是一種引用地址。若是咱們一樣重複建立了多個對象,那麼每一個對象中的方法都會在內存中開闢新的空間,
這樣浪費的空間就比較多。要解決這個問題,咱們就須要用到實例屬性或者方法的共享。 咱們可使用一種變通的方式,來達到咱們想要的效果,也就是讓show方法再也不重複建立
function User(name, age) { this.name = name; this.age = age; this.show = show; } function show(){ alert(this.name + ' ' + this.age); }
將show方法移到外部,至關於show方法成了一個全局函數,而後再到User構造函數內部去引用show方法,這樣User內部的this.show都指向了同一個全局函數show,
所以,咱們實例化的user1和user2就實現了共享,能夠再次調用:
alert(user1.show==user2.show);//結果返回的是true
可是這只是一個測試,若是你要讓更多的屬性或者方法實現共享,那不是要定義更多的全局函數或者變量,這種方式是不科學也不可行的。所以,咱們須要引入另一個javascript面向對象的重要概念原型
Javascript 面向對象編程(一):封裝
把兩個屬性封裝在一個對象裏面。可是,這樣的寫法有兩個缺點,一是若是多生成幾個實例,寫起來就很是麻煩;二是實例與原型之間,沒有任何辦法,能夠看出有什麼聯繫。
例子:
var cat1 = {}; // 建立一個空對象
cat1.name = "李密昂"; // 按照原型對象的屬性賦值
cat1.age= "20
var cat2 = {};
cat2.name = "三毛";
cat2.age= "19";
那麼問題來了,咱們能夠寫一個函數,解決代碼重複的問題嗎?固然能夠。
function Cat(name,color){
return {
name:name,
age:age
}
}
而後調用函數:
var cat1 = Cat("李密昂","20");
var cat2 = Cat("三毛","19");
構造函數模式
所謂"構造函數",其實就是一個普通函數,可是內部使用了this變量。對構造函數使用new運算符,就能生成實例,而且this變量會綁定在實例對象上。
原型對象如今能夠這樣寫:
function Cat(name,color){
this.name=name;
this.age=age;
}
生成實例對象:
var cat1 = new Cat("李銘","20");
var cat2 = new Cat("三毛","19");
alert(cat1.name); // 李銘
alert(cat1.age); // 20
這時cat1和cat2會自動含有一個constructor屬性,指向它們的構造函數。
alert(cat1.constructor == Cat); //true
alert(cat2.constructor == Cat); //true
Prototype模式
Javascript規定,每個構造函數都有一個prototype屬性,指向另外一個對象。這個對象的全部屬性和方法,都會被構造函數的實例繼承。
這意味着,咱們能夠把那些不變的屬性和方法,直接定義在prototype對象上。
function Cat(name,age){
this.name = name;
this.age= age;
}
Cat.prototype.type = "貓科動物";
Cat.prototype.eat = function(){alert("吃老鼠")};
生成實例:
var cat1 = new Cat("李銘","20");
var cat2 = new Cat("三毛","19");
alert(cat1.type); // 貓科動物
cat1.eat(); // 吃老鼠
指向prototype對象「
alert(cat1.eat == cat2.eat); //true
(未完待續。。。。。)