一、面向對象
1.對象:
對象是一個整體,對外提供屬性和若干操作。
2.面向對象:
使用對象時,只關注對象提供的功能,不關注其內部細節。比如電腦——有鼠標、鍵盤,我們只需要知道怎麼使用鼠標,敲打鍵盤即可,不必知道爲何點擊鼠標可以選中、敲打鍵盤是如何輸入文字以及屏幕是如何顯示文字的。總之外部沒必要知道其具體工作細節,只需知道如何使用其提供的功能即可,這就是面向對象。
3.JS的對象組成:
JS的對象由方法和屬性構成。
在JS中,有函數、方法、事件處理函數、構造函數,其實這四個都是函數,只是作用不同。函數是獨立的存在,方法屬於一個對象,事件處理函數用來處理一個事件,構造函數用來構造對象。
二、對象定義
1、Object構造函數創建對象
var object=new Object();
object.username="zhangsan";
alert(object.username);
delete object.username;
2、對象字面量
var obj={
“attbuteName”:value,
…:…,
“mothodName”:function(){…this.attbuteName…}
var person = {
firstName:"Bill",
lastName:"Gates",
age:62,
eyeColor:"blue"
};
3、工廠模式
用函數來封裝以特定接口創建對象的細節
function createObject(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
alert(this.name);
};
return o;
}
var p = createObject("光頭強", 50, "伐木工");
特點:
都是Object實例,無法區分所創建對象的類型。
4、構造函數模式
自定義構造函數,創建特定類型的對象,同一個構造函數創建出來的對象屬於一類
function People(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.getName = function() {
alert(this.name);
};
}
var p = new People("光頭強", 55, "伐木工");
特點:
對於一些可以共享且相同的函數方法,卻要多次創建在實例化對象中,佔用內存,且複用性差。
5、原型模式
讓所有的對象實例共享原型對象所包含的屬性和方法,不必在構造函數中定義然後多次在實例對象中創建了,只需要添加給原型即可.
function People() {
}
People.prototype.name = "熊大";
People.prototype.age = 25;
People.prototype.job = "護林員";
People.prototype.getName = function() {
alert(this.name);
};
var p1 = new People();
// 可以指定實例屬性,屏蔽來自原型的屬性值
p1.name = "猴大";
特點:
省略了傳遞給構造函數初始化參數這一環節,導致所有的實例默認都具有相同的屬性值。更大的問題是對於原型上的引用類型屬性,所有的實例之間會共享修改,喪失了獨特性。
6、混合構造函數原型模式
最常見的創建自定義類型方式,構造函數中定義實例屬性,原型對象中添加屬性和方法
function People(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.friends = ["猴大", "猴二"];
}
People.prototype = {
constructor : People,
getName : function() {
alert(this.name);
}
}
var p1 = new People("熊大", 25, "護林員");
var p2 = new People("熊二", 24, "護林員");
var p3 = new People("光頭強", 50, "伐木工");
p1.friends.push("李老闆");
alert(p1.friends);
alert(p2.friends);
特點:
支持向構造函數傳遞參數,每個實例都有自己的一份實例屬性的副本,每個實例共享對方法的引用,最大限度節省內存。
7、動態原型模式
將構造函數和原型對象等定義統一到一個函數中,封裝性更強,並且通過檢測必要情況來決定是否初始化原型,效率更高
function People(name, age, job){
this.name = name;// 人名
this.age = age;// 年紀
this.job = job; // 工作
//方法
if (typeof this.getName!= "function"){
People.prototype.getName= function(){
alert(this.name);
};
}
}
var p = new People("熊大", 29, "護林員");
p.getName();
原型方法的添加只執行一次,對原型所做的修改也能立即在實例中反映,但是需要注意不能使用對象字面量重寫原型,否則會切斷現有實例與新原型的聯繫。
8、寄生構造函數模式
當有特殊需求比如說創建一個具有額外方法的數組,由於不能直接修改Array,就可以使用這個模式。
function SpecialArray(){
//創建數組
var values = new Array();
//添加值
values.push.apply(values, arguments);
//添加方法
values.toPipedString = function(){
return this.join("|");
};
//返回數組
return values;
}
var colors = new SpecialArray("紅色", "藍色", "綠色");
console.log(colors.toPipedString()); // "紅色|藍色|綠色"
9、穩妥構造函數模式
用來創建沒有屬性,不引用this的安全穩妥對象
function People(name, age, job){
//創建要返回的對象
var obj = new Object();
//可以在這裏定義私有變量和函數
//添加方法
obj.getName = function(){
alert(name);
};
//返回對象
return obj ;
}
var p = People("熊大", 29, "護林員");
注意:
- 除了使用getName方法外,沒有其他辦法訪問name的值。
- 與寄生構造函數模式類似,使用穩妥構造函數模式創建的對象與構造函數之間沒有什麼關係,因此instanceof操作符也沒有意義。