一、繼承模式
1、傳統形式 --> 原型鏈
缺點:過多地繼承了沒用的屬性
2、借用構造函數
call/apply,可借用別人的方式實現自己的功能。
缺點:不能繼承借用構造函數的原型,且每次構造函數都要多走函數,運行效率偏低
前兩種繼承模式詳情請參考上節--原型、原型鏈、call/apply
3、共享原型
缺點:不能隨便改動自己的原型
Father.prototype.lastName = 'James';
function Father(){}
function Son(){}
function inherit(Target,Origin){
Target.prototype = Origin.prototype;
}
inherit(Son,Father);
var son = new Son();
console.log(son.lastName);//James
4、聖盃模式(豐滿的繼承)
借用中間構造函數F,實現繼承。
function inherit(Target,Origin){
function F(){}
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.constructor = Target;//找到對象的構造器
Target.prototype.uber = Origin.prototype;//找到真正繼承自哪個構造函數
}
Father.prototype.lastName = 'James';
function Father(){}
function Son(){}
inherit(Son,Father);
var son = new Son();
var father = new Father();
//son.__proto__ --> new F().__proto__ -->Father.prototype
更完美的模式:參考下列代碼
var inherit = (function(){
var F = function(){};
return function(Target,Origin){
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.constructor = Target;
Target.prototype.uber = Origin.prototype;
}
}());
Father.prototype.lastName = 'James';
function Father(){}
function Son(){}
inherit(Son,Father);
var son = new Son();
var father = new Father();
二、命名空間:用來管理變量,防止污染全局,適用於模塊化開發
下圖是一種原始的方法,只做參考。
var org = {
department1: {
zhangsan: {},
lisi: {},
wangermazi: {}
}
}
var zhangsan = org.department1.zhangsan;
現代化解決方案:閉包,進行模塊化開發
var name = 'bcd';
var initJack = (function(){
var name = 'abc';
function callName(){
console.log(name);
}
return function(){
callName();
}
}());
initJack();
方法的鏈式調用:
var james = {
basketball: function(){
console.log('Cool~~~!');
//return undefined;
return this;
},
football: function(){
console.log('Crazy~~~!');
return this;
},
badminton: function(){
console.log('Good~~~!');
return this;
}
}
james.basketball().football().badminton();
訪問屬性的另一個方法:
var obj = {name : 'abc'};
obj.name --> obj['name'],中括號裏必須是字符串,直接寫name就成變量了。
var obj = {
city1: {name: 'Beijing'},
city2: {name: 'Shanghai'},
city3: {name: 'Tianjin'},
city4: {name: 'Chongqing'},
sayCity : function(num){
return this['city' + num];
}
}
三、對象的枚舉enumeration:
var obj = {
name : 'abc',
age : 13,
gender : 'male',
height : 180,
weight : 80,
__proto__ : {
lastname : 'James',
__proto__ : Object.prototype
}
}
for(var prop in obj){
if(obj.hasOwnProperty(prop)){
console.log(prop + " " + typeof(prop));
//console.log(obj.prop);//實質爲obj['prop'],相當於訪問prop屬性,打印5個undefined
console.log(obj[prop]);//枚舉裏面必須寫方括號!!!
}
}
for in循環,遍歷對象(包括原型鏈上的屬性,任何手動添加的屬性,但不包括最頂端的Object.prototype的缺省屬性)
obj.hasOwnProperty(prop);(返回布爾值,判斷是否真實的屬於自己)
in:'height' in obj(返回布爾值,屬性必須寫成字符串。in只能判斷此對象能不能調用該屬性,原型鏈上的也返回true)
instanceof:A instanceof B:返回布爾值,看A對象的原型鏈上,有沒有B的原型!!!如下列代碼:
function Person(){}
var person = new Person();
person instanceof Person-->true
person instanceof Object-->true
如何區分數組和對象:
[].constructor;//Array
var obj = {};
obj.constructor;//Object
[] instanceof Array;//true,只能用Array區分
var obj = {};
obj instanceof Array;//false
Object.prototype.toString.call([]);//"[object Array]"
Object.prototype.toString = function(){
//識別this
//返回相應的結果
}
var obj = {};
obj.toString();//"[object Object]"
以上內容屬二哥原創,整理自 "渡一教育Javascript課程" ,一個值得推薦的"渡一教育"。