類和模塊 類和原型 工廠方法 構造函數 constructor

類和模塊
每一個js的對象都是屬性的集合。相互之間沒有聯繫。
js也能定義對象的類,讓每一個對象都共享某些屬性。
類的成員或者實例包含一些屬性,用來存放或者定義他們的狀態。有些屬性定義了其行爲,(行爲或者稱爲方法)
方法是類定義的,被全部的實例共享。
例如,用一個類來表示複數,同時定義了一些相關的複數運算,一個這個類的實例應當包含這個實例的狀態,即包含複數的實部和虛部,一樣還須要有行爲,即方法,行爲爲複數的加減法運算
js中類的實現是基於原型繼承機制的,若是兩個實例都從同一個原型對象上繼承了屬性,
若是兩個對象繼承自同一原型,每每意味着由同一個構造函數建立並初始化。
js中的類和Java中的類不同!!!!
好吧,完全看不懂書了。。心累
那就大概搜索一下博客得了
https://www.cnblogs.com/TomXu...
發現一個博客,先看看,再說,看樣子寫的很好,還出書了。
貌似寫的很好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的
以上這個工廠能批量生產對象,只要制定其範圍,就能批量完成
灰常方便函數

Math.ceil 天花板函數

一個完整的工廠方法

// 一個工廠實例
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方法爲原型鏈進行建立的,全部建立的對象都基於這個原型,並都繼承這個原型鏈性能

來,嘗試一下這個函數

先建立一個變量,用於指向這個對象this

var r = range(23,5464);
undefined
r;
Object { from: 23, to: 5464 }

而後~繼續
繼續使用其方法spa

r.includes;
function includes()
r.includes(2);
false

而後~繼續
繼續嘗試第二個屬性prototype

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__之間的關係,前者是加到該屬性中,在繼承時爲繼承的原型鏈,後者是繼承的繼承的,即父的父的關係的繼承,一個是往上有一層,一個是兩層,鏈以下

此處輸入圖片的描述
若是使用__proto__則以下
此處輸入圖片的描述
這兩個有區別,不能會混爲一談,一個是往子添加原型,一個是往父添加原型。
試用基本木有問題,過

new的含義,new是建立一個空對象,並將其根據的對象的原型添加進入這個空對象的原型
此處輸入圖片的描述
如上圖所示,其中根據new建立的對象的原型鏈是根據new的操做數來進行的。
b.constructor();
undefined
 因此這樣是能訪問其new的函數的

ps含義constructor爲構造器,真的貼近啊,實際上就是構造器,貌似有一本書是js的設計模式

前提條件是必須是對象,或者函數,或者數組

構造函數和類標識

當且僅當兩個對象繼承自同一原型對象的時候,這個兩個才屬於一個類的實例。
即兩個構造函數建立的實例的prototype是指向同一個原型對象

當原型鏈修改的時候,其子不會發生改變

經過運算符instanceof來進行計算

b instanceof a;
false

constructor屬性

對就是上文中的構造器。
依舊這一段代碼

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,讓其成爲對象,而操做數爲其原型
此處輸入圖片的描述
此處輸入圖片的描述
此處輸入圖片的描述
明天是js的Java式繼承
https://www.iming.info/archiv...

相關文章
相關標籤/搜索