摘要:對象封裝的常用方式常規封裝升級版較常見的執行原理解釋說明通過構造一個空對象將構造函數的原型屬性賦值給的原型對象在執行這句話的時候,對象就可以在其原型對象中查找方法。
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()打印其是不用調用任何方法的,而是之直接打印其值
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/52368.html
摘要:對象封裝的常用方式常規封裝升級版較常見的執行原理解釋說明通過構造一個空對象將構造函數的原型屬性賦值給的原型對象在執行這句話的時候,對象就可以在其原型對象中查找方法。 JS 對象封裝的常用方式 1.常規封裝 function Person (name,age){ this.name = name; this.age = age; } ...
摘要:對象封裝的常用方式常規封裝升級版較常見的執行原理解釋說明通過構造一個空對象將構造函數的原型屬性賦值給的原型對象在執行這句話的時候,對象就可以在其原型對象中查找方法。 JS 對象封裝的常用方式 1.常規封裝 function Person (name,age){ this.name = name; this.age = age; } ...
摘要:閉包實現封裝類靜態變量靜態方法正整數私有屬性年齡不是一個正整數一個只能創建個人測試靜態變量測試封裝效果測試靜態函數主要參考設計模式的例子總結可以看到這樣實現了封裝效果。 什么是封裝 封裝就是把一個對象保護起來,使其只提供定義的接口方法,而保護私有的變量。打個比方,游戲中的一個人物對象,它的經驗只有通過打死怪獸這個接口方法來增加。如果可以直接修改經驗就會直接影響到整個游戲的設定。所以這個...
摘要:前言什么這是一篇源碼解讀文章那一定很枯燥不看。通過利用函數,幫你丟棄回調函數,并有力地增強錯誤處理。并沒有捆綁任何中間件,而是提供了一套優雅的方法,幫助您快速而愉快地編寫服務端應用程序。 showImg(https://segmentfault.com/img/bVNQYf?w=1020&h=790); 前言 什么?這是一篇源碼解讀文章 ? 那一定很枯燥!不看。 我把 Koa 的核心實...
閱讀 1331·2019-08-30 15:44
閱讀 1381·2019-08-29 18:42
閱讀 433·2019-08-29 13:59
閱讀 770·2019-08-28 17:58
閱讀 2811·2019-08-26 12:02
閱讀 2414·2019-08-23 18:40
閱讀 2406·2019-08-23 18:13
閱讀 3106·2019-08-23 16:27