類和模塊 每一個js的對象都是屬性的集合。相互之間沒有聯繫。 js也能定義對象的類,讓每一個對象都共享某些屬性。 類的成員或者實例包含一些屬性,用來存放或者定義他們的狀態。有些屬性定義了其行爲,(行爲或者稱爲方法) 方法是類定義的,被全部的實例共享。 例如,用一個類來表示複數,同時定義了一些相關的複數運算,一個這個類的實例應當包含這個實例的狀態,即包含複數的實部和虛部,一樣還須要有行爲,即方法,行爲爲複數的加減法運算 js中類的實現是基於原型繼承機制的,若是兩個實例都從同一個原型對象上繼承了屬性, 若是兩個對象繼承自同一原型,每每意味着由同一個構造函數建立並初始化。 js中的類和Java中的類不同!!!! 好吧,完全看不懂書了。。心累 那就大概搜索一下博客得了 https://www.cnblogs.com/TomXu/archive/2012/02/23/2353389.html 發現一個博客,先看看,再說,看樣子寫的很好,還出書了。 貌似寫的很好html
js中類的全部實例對象都從同一個原型對象上繼承屬性 額。暫時到這,剩下的實在看不懂了。。 ┑( ̄Д  ̄)┍ 感受好難。。。 真的很難設計模式
工廠是函數,產品是對象,經過制定其相關要求,批量產生對象,這樣的函數爲工廠方法 一個工廠方法的實例數組
// 一個工廠實例
function range(from, to) {
// 使用Object.create建立一個新的基於該函數原型鏈的一個對象
var r = Object.create(range);
// 存儲着起始和結束位置
r.from = from;
r.to = to;
// 返回這個對象
return r;
}
複製代碼
好啦,一個工廠實例完成,試用一下這個工廠,用來加工生產一批對象瀏覽器
var f1 = range(324, 345);
undefined
f1;
Object { from: 324, to: 345 }
複製代碼
這樣就灰常完美的建立的一個新的對象,而且這個對象是從324到345的 以上這個工廠能批量生產對象,只要制定其範圍,就能批量完成 灰常方便bash
// 一個工廠實例
function range(from, to) {
// 使用Object.create建立一個新的基於該函數原型鏈的一個對象
var r = Object.create(range.methods);
// 存儲着起始和結束位置
r.from = from;
r.to = to;
// 返回這個對象
return r;
}
range.methods = {
// 若是在這個範圍以內則返回true,否false
// 這個方法用於比較數字
includes: function(x) {
return this.from <= x && x <= this.to;
},
// 對於範圍內的每一個整數調用一次f
// 這個方法用作輸出數字範圍
foreach: function(f) {
for(var x = Math.ceil(this.from); x <= this.to; x++) f(x);
},
// 返回表示這個範圍的字符串
toString: function() {
return '(' + this.from + '...' + this.to + ')';
},
}
複製代碼
上方代碼中,是基於range.methods方法爲原型鏈進行建立的,全部建立的對象都基於這個原型,並都繼承這個原型鏈性能
先建立一個變量,用於指向這個對象ui
var r = range(23,5464);
undefined
r;
Object { from: 23, to: 5464 }
複製代碼
而後~繼續 繼續使用其方法this
r.includes;
function includes()
r.includes(2);
false
複製代碼
而後~繼續 繼續嘗試第二個屬性spa
r.foreach(console.log)
複製代碼
好吧(∩_∩) 瀏覽器崩潰了 o(≧口≦)o 輸出太多了 js的性能太很差,常常崩潰,,無語 O__O "…
// range.js 表示類的另一種實現
// 一個構造函數,用以初始化新建立的範圍對象
// 注意,這裏並無新建並返回一個對象,僅僅是將該對象初始化
function Range(from, to) {
// 這兩個屬性不在原型鏈中
this.from = from;
this.to = to;
}
// 添加Range類的原型鏈
Range.prototype = {
includes: function(x) { return this.from <= x && x <= this.to; },
foreach: function (f) {
for ( var x = Math.ceil(this.from); x <= this.to; x++ ) f(x);
},
'toString': function() { return '(' + this.from + this.to + ')'; },
};
複製代碼
好啦,這樣就再次的完成了。 接着執行一下下
var r = Range(34, 45);
undefined
range = Range;
function Range()
var r = range(32, 43);
undefined
r;
undefined
複製代碼
ps 其中有一項約定,是通常狀況下,類第一個字母大寫,函數第一個字母小寫,採用駝峯命名法,這個具備必定分辨
好吧,貌似這本書有點問題,估計是更新的緣由,代碼始終不經過,這點過
var r = new range(23,34);
undefined
r;
{…}
from: 23
to: 34
<prototype>: Object { includes: includes()
, foreach: foreach(), toString: toString()
}
r.includes(33);
true
複製代碼
書中和實際中的是,事實上js不會完成這一轉換,估計在新版本中去掉了,所有代碼以下
// range.js 表示類的另一種實現
// 一個構造函數,用以初始化新建立的範圍對象
// 注意,這裏並無新建並返回一個對象,僅僅是將該對象初始化
var range = function Range(from, to) {
// 這兩個屬性不在原型鏈中
this.from = from;
this.to = to;
}
// 添加Range類的原型鏈
range.prototype = {
includes: function(x) { return this.from <= x && x <= this.to; },
foreach: function (f) {
for ( var x = Math.ceil(this.from); x <= this.to; x++ ) f(x);
},
toString: function() { return '(' + this.from + this.to + ')'; },
};
複製代碼
另外須要在總結一點,prototype和__proto__之間的關係,前者是加到該屬性中,在繼承時爲繼承的原型鏈,後者是繼承的繼承的,即父的父的關係的繼承,一個是往上有一層,一個是兩層,鏈以下
new的含義,new是建立一個空對象,並將其根據的對象的原型添加進入這個空對象的原型
如上圖所示,其中根據new建立的對象的原型鏈是根據new的操做數來進行的。 ![]()
b.constructor();
undefined
複製代碼
因此這樣是能訪問其new的函數的
ps含義constructor爲構造器,真的貼近啊,實際上就是構造器,貌似有一本書是js的設計模式
前提條件是必須是對象,或者函數,或者數組
當且僅當兩個對象繼承自同一原型對象的時候,這個兩個才屬於一個類的實例。 即兩個構造函數建立的實例的prototype是指向同一個原型對象
當原型鏈修改的時候,其子不會發生改變
經過運算符instanceof來進行計算
b instanceof a;
false
複製代碼
對就是上文中的構造器。 依舊這一段代碼
var range = function Range(from, to) {
// 這兩個屬性不在原型鏈中
this.from = from;
this.to = to;
}
// 添加Range類的原型鏈
range.prototype = {
includes: function(x) { return this.from <= x && x <= this.to; },
foreach: function (f) {
for ( var x = Math.ceil(this.from); x <= this.to; x++ ) f(x);
},
toString: function() { return '(' + this.from + this.to + ')'; },
};
複製代碼
其中必須使用new,由於沒有返回值,必須使用new,讓其成爲對象,而操做數爲其原型