先看如下構(gòu)造函數(shù)
function Fn() {
// this -> f1
this.x = 100;
this.getX = function () {
// this -> 需要看getX執(zhí)行的時候才知道
console.log(this.x);
}
}
var f1 = new Fn; // -> 此處()可省略
f1.getX(); // 方法中的this -> f1 -> 100
var ss = f1.getX;
ss(); // this -> window -> undefined
在構(gòu)造函數(shù)模式中,
new Fn執(zhí)行,如果Fn中不需要傳遞參數(shù)的話,后面的"()"可以省略。this的問題: 在類中出現(xiàn)的
this.xxx = xxx;中的this都是當(dāng)前類的實例,而某一個屬性值(方法),方法中的this需要看方法執(zhí)行的時候,前面是否有".",才能知道this是誰。
- 類有普通函數(shù)的一面,當(dāng)函數(shù)執(zhí)行的時候,
var num其實只是當(dāng)前形成的私有作用域中的私有變量而已,它和我們的f1這個實例沒有任何的關(guān)系;只有this.xxx = xxx;才相當(dāng)于f1這個實例增加了私有的屬性和方法,才和f1有關(guān)系。
function Fn() {
var num = 10;
this.x = 100; // f1.x = 100;
this.getX = function () { // f1.getx = function() {...}
console.log(this.x);
}
return 100;
return {a: '1'};
}
var f1 = new Fn();
console.log(f1.num); // undefined
- 在構(gòu)造函數(shù)模式中,瀏覽器會默認的把實例返回(返回的是一個對象數(shù)據(jù)類型);如果我們自己手動寫了return返回,這是分為兩種情況:
第一種情況: 是返回的是基本數(shù)據(jù)類型,那么當(dāng)前的實例是不會改變的,例如return 100;此時f1還是Fn()類的實例。
第二種情況: 如果返回的是引用數(shù)據(jù)類型的值,當(dāng)前的實例會被返回的引用數(shù)據(jù)替換了,例如return {a: '1';}, 此時f1就不再是Fn()的實例了,而是{a: '1'};。
console.log(f1);
- 檢測某一個實例是否屬于這一個類,可以使用instanceof
console.log(f1 instanceof Fn); // -> true
console.log(f1 instanceof Array); // -> false
console.log(f1 instanceof Object); // -> true 因為所有的實例都是對象數(shù)據(jù)類型的
// 而每一個對象數(shù)據(jù)類型,而每一個對象數(shù)據(jù)類型都是Object這個內(nèi)置類的一個實例,所以f1也是它的一個實例
// 對于檢測數(shù)據(jù)類型來說,typeof有自己的局限性,它不能細分Object下的對象、數(shù)組、正則等。
var a = [];
console.log(a instanceof Array); // -> true 說明a是一個數(shù)組
function Fn() {
this.x = 100;
this.getX = function () {
console.log(this.x);
}
}
var f1 = new Fn();
var f2 = new Fn();
- f1和f2都是Fn這個類的一個實例,都擁有x和getX兩個屬性,但是這兩個屬性是各自的私有的屬性,所以:
console.log(f1.getX === f2.getX); // -> false
// in: 檢測某一個屬性是否屬于這個對象,attr in object,不管是私有的還是公有的屬性,只要存在,用in來檢測都是true
console.log('getX' in f1); // true -> 是它的屬性
// hasOwnProperty: 用來檢測某一個屬性是否為這個對象的"私有屬性",這個方法只能檢測私有的屬性
console.log(f1.hasOwnProperty('getX')); // true
思考:檢測某一個屬性是否是該對象的"公有屬性"?
function hasPublicProperty(obj, attr) {
if (attr in obj && !obj.hasOwnProperty(attr)) {
return true;
}
return false;
}
console.log(hasPublicProperty(f1, 'getX')); // -> false