詳解JS對象封裝的常用方式
JS是一門面向?qū)ο笳Z言,其對象是用prototype屬性來模擬的,下面,來看看如何封裝JS對象.
常規(guī)封裝
function Person (name,age,sex){ this.name = name; this.age = age; this.sex = sex; } Pserson.prototype = { constructor:Person, sayHello:function(){ console.log('hello'); } }
這種方式是比較常見的方式,比較直觀,但是Person() 的職責(zé)是構(gòu)造對象,如果把初始化的事情也放在里面完成,代碼就會顯得繁瑣,如果放在一個方法里初始化會不會好點呢?
升級版 (常見)
function Person (info){ this._init_(info); } Pserson.prototype = { constructor : Person, _init_ : function(info) { this.name = info.name; this.age = info.age; this.sex = info.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(o, args); var type = typeof res; if (['string', 'number', 'boolean', 'null', 'undefined'].indexOf(type) !== -1) { return o; } return res; }
解釋:
首先通過 var o = {} 構(gòu)造一個空對象.
然后將 構(gòu)造函數(shù)的原型屬性prototype賦值給o 的原型對象__proto__ 。這樣,在執(zhí)行 this.init(info); 這句話的時候,對象 o 就可以在其原型對象中查找_init_ 方法。(原型鏈)。
之后這句話 就是精髓了。
var res = constructor.apply(o,args);
以o為上下文調(dià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 為上下文調(diào)用,o也將擁有自己的 name,age,sex 屬性。
如果在構(gòu)造函數(shù)中,return 復(fù)合類型,包括對象,函數(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); o1.sayHello();
OK 吧
類jQuery 封裝
這種方式是我從 jQuery 那里學(xué)來的。
jQuery 對象具有很強的集成性,可以作為函數(shù)調(diào)用,也可以做為對象調(diào)用,當(dāng)作為函數(shù)調(diào)用的時候,她可以無需 new 而返回它的一個實例,很方便。
先看代碼
var Person = function(info){ return new Person.prototype.init(info); } Person.prototype = { constructor: Person, init:function(){ this.name = info.name. } } Person.prototype.init.prototype = Person.prototype;
這種封裝方式非常巧妙。
將對象的構(gòu)造操作放在函數(shù)的里面,而自己充當(dāng)一個工廠。
不斷調(diào)用 prototype 并不是一個直觀的做法,于是
var Person = function(info){ return new Person.fn.init(info); } Person.fn = Person.prototype = { constructor: Person, init:function(){ this.name = info.name; this.sayHello = function(){ this.makeArray(); } } makeArray:function(){ console.log(this.name); } } // 這句話的作用 // 雖然把makeArray 等常用方法掛載到 Person.prorotype 下面,但還是會被 init 這個實例使用. Person.fn.init.prototype = Person.fn;
最后用 閉包 封裝起來
var Person = (function(window) { var Person = function(name) { return new Person.fn.init(name); } Person.fn = Person.prototype = { constructor: Person, init: function(name) { this.name = name; this.sayHello = function() { this.makeArray(); } }, makeArray: function() { console.log(this.name); } } Person.fn.init.prototype = Person.fn; return Person; })();
測試一下
var p = Person('pawn'); console.log(p); p.sayHello();
object.create();
最后js也提供了一種構(gòu)造對象的方式,object.create(); 可以傳遞一個對象Person,構(gòu)造一個p,并且使p 繼承Person.
var Person = { name: 'pawn', sayHello: function() { console.log(this.name); } } var p = Object.create(Person); console.log(p); p.sayHello();
結(jié)果
可以看到,對象Person的屬性成為了p的原型屬性,也就是說 p 原型繼承自 Person !
我們可以實現(xiàn)一個 Object.create()
Object.create = function(prototype){ function Func(){}; Func.prototype = prototype; var o = new Func(); return o; }
在這里,我們將 Person 作為 構(gòu)造函數(shù)的 原型屬性,就可以構(gòu)造出 以Person 為原型對象的對象.
測試一下
OK
關(guān)于 JS對象封裝的方式就介紹到這里,如有錯誤,望不吝賜教.
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
相關(guān)文章
Next.js路由組使用之組織路由結(jié)構(gòu)示例詳解
這篇文章主要為大家介紹了Next.js路由組使用之組織路由結(jié)構(gòu)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-10-10在服務(wù)端(Page.Write)調(diào)用自定義的JS方法詳解
自從[javascript]自定義MessageBox一文發(fā)布以后,很多網(wǎng)友都來信詢問,如何在服務(wù)端調(diào)用ShowInfo方法,周末休息想了個折中的辦法來實現(xiàn)2013-08-08Bootstrap下拉菜單更改為懸停(hover)觸發(fā)的方法
這篇文章主要為大家詳細介紹了Bootstrap下拉菜單更改為懸停(hover)觸發(fā)的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05JavaScript實現(xiàn)像雪花一樣的Hexaflake分形
這篇文章主要介紹了JavaScript實現(xiàn)像雪花一樣的Hexaflake分形,文中示例代碼非常詳細,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07