珠峰js筆記1.2(原型鏈模式)
{ 單例模式
物件資料型別的作用:
把描述同一個事物的屬性和方法放在一個記憶體空間下,起到了分組的作用,這樣不同事物之間的屬性即使屬性名相同,相互也不會發生衝突
-> 我們把這種分組編寫程式碼的模式叫做 “單例模式”
-> 在單例模式中我們把 person1 叫做 “名稱空間”
var person1 = { name: 'rose', age: 20 };
單例模式是一種專案開發中經常使用的模式,因為專案中我們可以使用單例模式來進行 “模組化開發”(大的專案,需要多人協作開發,把專案分成幾個功能模組,同時開發,最後合併)
// 公共方法
var utils = {
select: function(){ }
}
// 頁面模組中的 change()方法 -> tab 選項卡變化
// 搜尋模組中的 change() 方法 -> 搜尋內容變化
// 解決衝突,用單例模式
var tabRender = {
change: function() {
utils.select(); // 呼叫公共方法
this.showCt(); // 呼叫同一名稱空間的方法
// 最好用 this, change 方法呼叫的時候,tabRender.change(); this 就是 tabRender
//如果名稱空間需要要改名,這裡用 this 就很方便
}
showCt: function(){ }
}
{ 工廠模式
var jsPerson1 = {
name: 'rose',
age: 23,
action: function(){
console.log('my name is '+ this.name);
}
}
以上程式碼,如果是 n 個人呢,需要重複寫 n 次
單例模式雖然解決了分組的作用,但是不能實現批量的生產
function createPerson(name,age){
var person = {};
person.name = name;
person.age = age;
person.action = function(){
console.log('my name is '+ this.name);
}
return person; // 返回物件
}
var p1 = createPerson('jack',33);
p1.action();
把實現同一件事情的相同的程式碼放到一個函式中,以後如果再想實現這個功能,只需要執行當前函式即可 -> “ 函式封裝”
-> 低耦合高內聚: 減少頁面中的冗餘程式碼,提高程式碼的重複利用率
js 是一門輕量級的指令碼語言, html css 不屬於程式語言,屬於標記語言
所有的程式語言都是面向物件開發的 -》 類的繼承、封裝、多型
繼承:子類繼承父類中的屬性和方法
多型:當前方法的多種形態,->後臺語言中,多型包含過載和重寫
“js中不存在過載”,方法名一樣的話,後面的會把前面的覆蓋,最後只保留一個
js中有一個操作類似過載但不是過載,可以根據傳遞引數的不一樣,實現不同的功能
function sum(num){
if(typeof num ==='undefined'){
return 0;
}
return num;
}
{ 建構函式模式
建構函式模式的目的就是為了建立一個自定義類,並且建立這個類的例項
建構函式模式和工廠模式的區別
1 執行的時候
– 普通函式執行 -> createJsPerson()
– 建構函式模式工-> new CreateJsPerson() ( 約定俗成,大寫)
通過 new 執行後, CreateJsPerson就是一個類了,返回值 是 類的一個例項
2 函式程式碼執行的時候
都形成一個私有的作用域,然後形參賦值->預解釋->程式碼從上到下執行
不同:在程式碼執行之前,不用手動建立物件,瀏覽器會預設的建立一個物件型別的值,(這個物件就是當前類的一個例項 ) 建構函式模式中,不用建立 obj 物件,用 this,代表當前例項,分別把屬性名和屬性值傳給當前例項, 也不用 return ,最後瀏覽器會預設的把當前例項返回
// 建立一個數組
var arr = []; // 字面量方式
var ary = new Array(); // 例項建立的方式,建構函式模式執行的方式
使用一個未宣告的變數
console.log(window.x); // undefined
console.log(x); // 報錯
js中所有的 類 都是函式資料型別
的,所有的 例項 都是物件資料型別
的
this 問題: 在建構函式模式中,類中出現 this.xxx = xxx; 其中 this 指的是當前類的一個例項
在建構函式模式中,不同例項的方法是不一樣的
console.log( p1.action === p2.action) ; // false
在類中給例項增加的屬性(this.xxx = xxx) 屬於當前例項的私有屬性,例項和例項之間是單獨的個體,所以私有的屬性之間是不相等的
在建構函式模式中, 使用 var res = CreatePerson(‘jack’, 22); // 這樣寫是普通函式執行,因為沒有 return, 所以 res 的值為 undefined; 並且 CreatePerson 這個方法中的 this 是 window
function Fn(){
this.x = 100;
this.getX = function(){
console.log( this.x);
}
}
var f1 = new Fn;
f1.getX(); // this -> f1 結果 100
var ss = f1.getX;
ss(); // this -> window 結果 undefined
1.在建構函式模式中, new Fn() 執行,如果不需要傳參,後面的小括號可以省略
2.this問題:在類中出現的 this.xxx = xxx 中的 this 都是當前類的例項,而某一個屬性(方法)中的 this ,需要看方法執行的時候,前面是否有 . (點),才能知道 this 是誰
3.在 Fn 中,新增 var num = 10; 最後 console.log( f1.num ); 結果: undefined
類有普通函式的一面,當函式執行的時候,var num 其實只是當前形成的私有作用域中的私有變數而已,它和例項沒有任何的關係,只有 this.xxx = xxx 才相當於給例項增加私有的屬性和方法
4.在 Fn 中,手動新增 return
在建構函式模式中,瀏覽器會預設的將例項返回,是一個物件資料型別的值
如果手動寫了 return
a) return 100; 返回的是一個基本資料型別的值,當前例項不變
b) return {…}; 返回的是一個引用資料型別的值,當前例項會被手動寫的返回的值替換,f1 就不是 Fn 的例項了,而是物件 { … }
5.檢測某一個例項是否屬於這個類 instanceof
console.log(f1 instanceof Fn); // true
console.log(f1 instanceof Array); // false
console.log(f1 instanceof Object); // true
因為所有的例項都是物件資料型別的,而每一個物件資料型別都是 Object 這個內建類的一個例項,所以 f1 也是 Object 的一個例項
instanceof 用處: 對於檢測資料型別來說, typeof 有自己的侷限性,不能細分 object 下的物件、陣列、正則
var arr = [];
console.log( arr instanceof Array); // true 說明是陣列
6.屬性檢測
in: 檢測某一個屬性是否屬性這個物件,私有和公有屬性,只要存在,用 in 來檢測都是 true
hasOwnProperty: 檢測某一屬性是否為這個物件的私有屬性,這個方法只能檢測出私有的屬性
console.log('in:', 'getX' in f1); // true
console.log('hasOwnProperty:', f1.hasOwnProperty('getX')); // true
思考:檢測某一屬性是否為公有屬性
function hasPublicAttr(obj, attr){
return (attr in obj) && !obj.hasOwnProperty(attr);
}
7 isPrototypeOf
控制檯: dir( Object.prototype) 回車