ecmascript有兩種開發模式:1.函式式(過程化),2.物件導向(oop)。物件導向的語言有乙個標誌,那就是類的概念,而通過類可以建立任意多個具有相同屬性和方法的物件。但是,ecmascript沒有類的概念,因此它的物件也與基於類的語言中的物件有所不同。
二.建立物件
建立乙個物件,然後給這個物件新建屬性和方法。
var box = new object(); //建立乙個object物件
box.name = 'lee'; //建立乙個name屬性並賦值
box.age = 100; //建立乙個age屬性並賦值
box.run = function () ;
alert(box.run()); //輸出屬性和方法的值
以上這種方式,是建立單個物件的方式.如果,我們要是想建立多個物件,那麼我們就必須用到函式傳遞引數的方式.
為了解決多個類似物件宣告的問題,我們可以使用一種叫做工廠模式的方法,這種方法就是為了解決例項化物件產生大量重複的問題。
function create(name,age)
return obj
}var box = create("咖啡",255)
box.run()//輸出咖啡255
工廠模式解決了重複例項化的問題,但還有乙個問題,那就是識別問題,因為根本無法搞清楚他們到底是哪個物件的例項。
alert(typeof box1); //object
alert(box instanceof create) //false
ecmascript中可以採用建構函式(構造方法)可用來建立特定的物件。型別於object物件。
function create(name,age)
}var box = new create("咖啡",30)
box.run()//輸出咖啡30
alert(box instanceof create) //true
使用建構函式的方法,即解決了重複例項化的問題,又解決了物件識別的問題,但問題是,這裡並沒有new object(),為什麼可以例項化box(),這個是**來的呢?
使用了建構函式的方法,和使用工廠模式的方法他們不同之處如下:
1.建構函式方法沒有顯示的建立物件(new object());
2.直接將屬性和方法賦值給this物件;
3.沒有renturn語句。
建構函式的方法有一些規範:
1.函式名和例項化構造名相同且大寫,(ps:非強制,但這麼寫有助於區分建構函式和普通函式);
2.通過建構函式建立物件,必須使用new運算子。
既然通過建構函式可以建立物件,那麼這個物件是**來的,new object()在什麼地方執行了?執行的過程如下:
1.當使用了建構函式,並且new 建構函式(),那麼就後台執行了new object();
2.將建構函式的作用域給新物件,(即new object()建立出的物件),而函式體內的this就代表new object()出來的物件。
3.執行建構函式內的**;
4.返回新物件(後台直接返回)。
3.原型
我們建立的每個函式都有乙個prototype(原型)屬性,這個屬性是乙個物件,它的用途是包含可以由特定型別的所有例項共享的屬性和方法。邏輯上可以這麼理解:prototype通過呼叫建構函式而建立的那個物件的原型物件。使用原型的好處可以讓所有物件例項共享它所包含的屬性和方法。也就是說,不必在建構函式中定義物件資訊,而是可以直接將這些資訊新增到原型中。
function box() {} //宣告乙個建構函式
box.prototype.name = 'lee'; //在原型裡新增屬性
box.prototype.age = 100;
box.prototype.run = function () ;
var box1 = new box();
var box2 = new box();
alert(box1.run == box2.run); //true,方法的引用位址保持一致
為了讓屬性和方法更好的體現封裝的效果,並且減少不必要的輸入,原型的建立可以使用字面量的方式:
function box() {};
box.prototype =
};使用建構函式建立原型物件和使用字面量建立物件在使用上基本相同,但還是有一些區別,字面量建立的方式使用constructor屬性不會指向例項,而會指向object,建構函式建立的方式則相反。
var box = new box();
alert(box instanceof box);
alert(box instanceof object);
alert(box.constructor == box); //字面量方式,返回false,否則,true
alert(box.constructor == object); //字面量方式,返回true,否則,false
但利用字面量的形式,我們就會發現,它的建構函式就不是box了,它的結果返回的是乙個false
ps:字面量方式為什麼constructor會指向object?因為box.prototype={};這種寫法其實就是建立了乙個新物件。而每建立乙個函式,就會同時建立它prototype,這個物件也會自動獲取constructor屬性。所以,新物件的constructor重寫了box原來的constructor,因此會指向新物件,那個新物件沒有指定建構函式,那麼就預設為object。
原型的宣告是有先後順序的,所以,重寫的原型會切斷之前的原型。
function box() {};
box.prototype =
};box.prototype = ;
var box = new box(); //在這裡宣告
alert(box.run());
後寫的原型會覆蓋掉原來的原型,另外如果是字面量的形式存在name屬性,建構函式也存在name的話,那麼就會是字面量形式的原型優於建構函式的屬性
function box()
box.prototype =
}var box = new box()
alert(box.name) //咖啡1
原型物件不僅僅可以在自定義物件的情況下使用,而ecmascript內建的引用型別都可以使用這種方式,並且內建的引用型別本身也使用了原型。
alert(array.prototype.sort); //sort就是array型別的原型方法
alert(string.prototype.substring); //substring就是string型別的原型方法
string.prototype.addstring = function () ;
alert('lee'.addstring()); //使用這個方法
原型模式建立物件也有自己的缺點,它省略了建構函式傳參初始化這一過程,帶來的缺點就是初始化的值都是一致的。而原型最大的缺點就是它最大的優點,那就是共享。
原型中所有屬性是被很多例項共享的,共享對於函式非常合適,對於包含基本值的屬性也還可以。但如果屬性包含引用型別,就存在一定的問題:
function box() {};
box.prototype =
};var box1 = new box();
box1.family.push('哥哥'); //在例項中新增'哥哥'
alert(box1.run());
var box2 = new box();
alert(box2.run()); //共享帶來的麻煩,也有'哥哥'了
ps:資料共享的緣故,導致很多開發者放棄使用原型,因為每次例項化出的資料需要保留自己的特性,而不能共享。
為了解決構造傳參和共享問題,可以組合建構函式+原型模式:
function box(name, age) ;
box.prototype =
};
JavaScript關於物件導向(OOP)上
物件導向程式設計 object oriented programming oop 是一種程式設計范型,同時也是一種程式開發的方法。物件指的是類的例項。它將物件作為程式的基本單元,將程式和資料封裝其中,以提高軟體的重用性 靈活性和擴充套件性 物件導向的特徵 主要四部分如下 繼承 封裝多型 抽象繼承是實...
JavaScript物件導向
方法一 建構函式法 function cat cat.prototype.showname function var cat new cat cat.name tom cat.showname tom 它用建構函式模擬 類 在其內部用this關鍵字指代例項物件。類的屬性和方法,還可以定義在建構函式的...
javaScript物件導向
code 類lecture構造器 使用兩個字串函式,name和teacher function lecture name,teacher 類lecture的方法,生成乙個顯示該課程資訊的字串 lecture.prototype.display function 類schedule的構造器 使用乙個l...