JS 對象封裝的經常運用體式格局
1.通例封裝
function Person (name,age){
this.name = name;
this.age = age;
}
Pserson.prototype = {
constructor:Person,
say:function(){
console.log('hello everyone!');
}
}
2.升級版 (較罕見)
function Person (example){
this._init_(example);
}
Pserson.prototype = {
constructor : Person,
_init_ : function(example) {
this.name = example.name;
this.age = example.age;
}
say:function(){
console.log('hello everyone');
}
}
3.new 的實行道理
var myNew = function(constructor, args) {
var obj = {};
obj .__proto__ = constructor.prototype;
var res = constructor.apply(obj , args);
var type = typeof res;
if (['string', 'number', 'boolean', 'null', 'undefined'].indexOf(type) !== -1) {
return obj ;
}
return res;
}
詮釋申明: 經由過程var obj = {} 組織一個空對象. 將組織函數的原型屬性prototype賦值給obj 的原型對象__proto__
,在實行 this.init(example); 這句話的時刻,對象 obj 就能夠在其原型對象中查找_init_ 要領。(原型鏈)。
var res = constructor.apply(obj,args);
以obj為上下文挪用函數,同時將參數作為數組通報。那末,
this._init_(example);
就會被 obj 實行
函數
_init_ : function(example) {
this.name = example.name;
this.age = example.age;
}
以 obj 為上下文挪用,o也將具有本身的 name,age屬性。
如果在組織函數中,return 複合範例,包含對象,函數,和正則表達式,那末就會直接返回這個對象,不然,返回 obj
var type = typeof res;
if(['string','number','boolean','null','undefined'].indexOf(type) !== -1){
return obj;
}
return res;
舉例
function Person(name) {
this.name = name;
}
Person.prototype.say = function() {
console.log(this.name);
}
var jack = myFriend(Person, ['jack ']);
console.log(jack );
jack.say();
4.類jQuery 封裝
jQuery 對象具有很強的集成性,能夠作為函數挪用,也能夠做為對象挪用,當作為函數挪用的時刻,能夠無需 new 而返回一個實例。
代碼
var Person = function(info){
return new Person.prototype.init(info);
}
Person.prototype = {
constructor: Person,
init:function(){
this.name = example.name.
}
}
Person.prototype.init.prototype = Person.prototype;
- 這類封裝體式格局異常奇妙。 將對象的組織操縱放在函數的內里,而本身充任一個工場。 不停挪用 prototype 並非一個直觀的做法,因而
var Person = function(example){
return new Person.fn.init(example);
}
Person.fn = Person.prototype = {
constructor: Person,
init:function(){
this.name = info.name;
this.say = function(){
this.makeExp();
}
}
makeExp:function(){
console.log(this.name);
}
}
// 雖然把makeArray 等經常運用要領掛載到 Person.prorotype 下面,但照樣會被 init 這個實例運用.
Person.fn.init.prototype = Person.fn;
最後用 閉包 封裝起來
var Person = (function(win) {
var Person = function(name) {
return new Person.fn.init(name);
}
Person.fn = Person.prototype = {
constructor: Person,
init: function(name) {
this.name = name;
this.say = function() {
this.makeExp();
}
},
makeExp: function() {
console.log(this.name);
}
}
Person.fn.init.prototype = Person.fn;
return Person;
})()
舉例:
var people = Person('jack');
console.log(people);
people.say();
object.create();
一種組織對象的體式格局, 能夠通報一個對象Person,組織一個people,而且使people 繼續Person.
var Person = {
name: 'jack',
say: function() {
console.log(this.name);
}
}
var people = Object.create(Person);
console.log(people);
people.say();
對象Person的屬性成為了people的原型屬性,也就是說 people 原型繼續自 Person !
我們能夠完成一個 Object.create()
Object.create = function(prototype){
function Fun(){};
Fun.prototype = prototype;
var obj = new Fun();
return obj;
}
申明:
將 Person 作為 組織函數的 原型屬性,就能夠組織出 以Person 為原型對象的對象.
Object.create(原型); 建立一個繼續該原型的實例對象
關於此要領的一些注意事項:
(1)若傳參為Object.prototype,則建立的原型為Object.prototype,
- 和 new Object()建立的對象是一樣的 Object.create(Object.prototype) <==>new
Object();
(2)若傳參為空 或許 null,則建立的對象是沒有原型的,
- 致使該對象是沒法用document.write()打印會報錯,
由於document.write()打印的道理是挪用Object.prototype.toString()要領,
該對象沒有原型,也就沒有該要領,所以document.write()沒法打印
由此延長的知識點: 援用值都也是算作是對象, 所以都能夠用document.write()打印; 原始值numebr, boolean,
string都有本身對象的包裝類, 藉助此機制也是能夠用document.write()打印出的;
但undefined 和 null既不是援用值,也沒有對應的包裝類, 所以應當沒法打印的,但人人會發明這兩個值也是但是用document.write()打印的, 由於這兩個值被設定為特別值,
document.write()打印其是不必挪用任何要領的,而是之直接打印其值