趁著等服務端接口的一點點時間嘹裂,網(wǎng)上看了幾個關于js對象封裝的例子,自己再重新手敲一遍上忍,總結一下,溫故而知新诱咏。(大艾斯鎮(zhèn)樓)
JS是一門面向對象語言,其對象是用prototype屬性來模擬的缴挖,下面袋狞,來看看如何封裝JS對象。
常規(guī)封裝
function Person(name, age, sex){
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype = {
constructor: Person,
sayHello: function(){
console.log('hello);
}
}
這種方式是比較常見的映屋,比較直觀苟鸯,但是Person()的職責是構造對象,如果把初始化的事情放在里面完成棚点,代碼就會顯得繁瑣早处,如果放在一個方法里初始化會不會好點呢?
升級版(常見)
function Person(info){
this._init_(info);
}
Person.prototype = {
constructor: Person,
_init_: function(info){
this.name = name;
this.age = age;
this.sex = sex;
},
sayHello: function(){
console.log('hello');
}
}
可是,說到這里就發(fā)現(xiàn),name,age,sex 并沒有在Person里面申明,哪來的呢???
new 的執(zhí)行原理
new 的執(zhí)行過程可以用下面一個函數(shù)來代替
var myNew = function(constructor, args){
var o = {};
o.__proto__ = constructor.prototype;
var res = constructor.apply(0, args);
var type = typeof(res);
if(['string', 'number', 'boolean', 'null', 'undefined'].indexOf(type) !== -1){
return o;
}
return res;
}
解釋:
首先通過 var o = {} 構造一個空對象.
然后將 構造函數(shù)的原型屬性prototype賦值給o 的原型對象proto 瘫析。這樣砌梆,在執(zhí)行 this.init(info); 這句話的時候,對象 o 就可以在其原型對象中查找init 方法贬循。(原型鏈)咸包。
之后這句話 就是精髓了。
var res = constructor.apply(o,args);
以o為上下文調用函數(shù)杖虾,同時將參數(shù)作為數(shù)組傳遞烂瘫。那么,
this._init_(info);
這句話就會被 o 執(zhí)行奇适, 函數(shù)
_init_ : function(info) {
this.name = info.name;
this.age = info.age;
this.sex = info.sex;
}
以 o 為上下文調用坟比,o也將擁有自己的 name,age,sex 屬性。
如果在構造函數(shù)中嚷往,return 復合類型葛账,包括對象,函數(shù)间影,和正則表達式注竿,那么就會直接返回這個對象茄茁,否則魂贬,返回 o 。
var type = typeof res;
if(['string','number','boolean','null','undefined'].indexOf(type) !== -1){
return o;
}
return res;
測試一下
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log(this.name);
}
var o1 = myNew(Person, ['pawn']);
console.log(o1); //{name: pawn}
o1.sayHello(); //pawn
OK裙顽,大功告成付燥!
此外,再補充幾點愈犹,
只有函數(shù)才有prototype屬性,這個屬性值為一個object對象键科,
實例對象時沒有這個屬性的闻丑,實例對象通過proto這個內部屬性([[prototype]])來串起一個原型鏈的,通過這個原型鏈可以查找屬性勋颖,方法嗦嗡,
通過new操作符初始化一個函數(shù)對象的時候就會構建出一個實例對象,函數(shù)對象的prototype屬性指向的對象就是這個實例對象的原型對象饭玲,也就是proto指向的對象
所有構造器/函數(shù)的proto都指向Function.prototype侥祭,它是一個空函數(shù)(Empty function)
Number.__proto__ === Function.prototype // true
Boolean.__proto__ === Function.prototype // true
String.__proto__ === Function.prototype // true
Object.__proto__ === Function.prototype // true
Function.__proto__ === Function.prototype // true
Array.__proto__ === Function.prototype // true
RegExp.__proto__ === Function.prototype // true
Error.__proto__ === Function.prototype // true
Date.__proto__ === Function.prototype // true
JavaScript中有內置(build-in)構造器/對象共計12個(ES5中新加了JSON),這里列舉了可訪問的8個構造器茄厘。剩下如Global不能直接訪問矮冬,Arguments僅在函數(shù)調用時由JS引擎創(chuàng)建,Math次哈,JSON是以對象形式存在的胎署,無需new。它們的proto是Object.prototype窑滞。如下
Math.__proto__ === Object.prototype // true
JSON.__proto__ === Object.prototype // true
Function.prototype也是唯一一個typeof XXX.prototype為 “function”的prototype琼牧。其它的構造器的prototype都是一個對象。如下
console.log(typeof Function.prototype) // function
console.log(typeof Object.prototype) // object
console.log(typeof Number.prototype) // object
console.log(typeof Boolean.prototype) // object
console.log(typeof String.prototype) // object
console.log(typeof Array.prototype) // object
console.log(typeof RegExp.prototype) // object
console.log(typeof Error.prototype) // object
console.log(typeof Date.prototype) // object
console.log(typeof Object.prototype) // object
相信都聽說過JavaScript中函數(shù)也是一等公民哀卫,那從哪能體現(xiàn)呢障陶?如下
console.log(Function.prototype.__proto__ === Object.prototype) // true
最后Object.prototype的proto是誰?
Object.prototype.__proto__ === null // true
已經(jīng)到頂了聊训,為null抱究。
時間有限,未完待續(xù)带斑。鼓寺。。