1. 程式人生 > 其它 >十五、JavaScript面向物件

十五、JavaScript面向物件

一、面向物件概念

  • 關注物件的形式進行開發,面對JavaScript中物件資料型別

  • 面向物件,是一種程式設計思想、語法、方法、程式碼編寫的方式

  • 面向物件

    • 關注注重物件的操作

      • 可以設定屬性/鍵名

      • 可以設定屬性值/鍵值

      • 可以設定函式

    • 可以將需要執行的程式內容,都定義給物件

    • 呼叫物件的函式,來執行程式

  • 有JavaScript提供好的內建物件,或者別人寫的第三方外掛

  • 也可以自己自定義建構函式,創造一個工具

二、工廠模式建立物件

工廠模式:

  • 以固定的模式,生成物件

  • 輸入引數資料,就給我們建立一個響應的物件出來

 1 function createObj(n, a, s) {
2 // 建立物件 3 const obj = {}; 4 // 給物件新增屬性和屬性值 5 obj.name = n; 6 obj.age = a; 7 obj.sex = s; 8 // 給物件新增函式方法 9 obj.fun = function () { 10 console.log(this.name, this.age, this.sex); 11 } 12 // 返回這個物件 13 return obj; 14 } 15 16 const obj1 = createObj('張三', 18, '男'); 17 console.log(obj1);

三、建構函式創造物件

建構函式:本質還是一個函式,是一個專門生成物件的函式,生成的這個物件,有屬性屬性值,還有函式方法

  • 定義函式時,還是按照原始方法定義函式

  • 呼叫函式時,必須使用 new 來配合呼叫函式

 1 function CreateObj(n, a, s) {
 2   console.log(this);
 3 
 4   this.name = n;
 5   this.age = a;
 6   this.sex = s;
 7   this.fun = function () {
 8     console.log(this);
 9     // console.log(this.name,this.age,this.sex);
10 } 11 } 12 const obj1 = new CreateObj('張三', 18, '男');
  • new 關鍵詞會自動建立一個物件,並且會自動返回這個物件

  • 與 new 一起使用的函式,不用再定義建立物件和返回值物件

  • 所謂的建構函式,本質上就還是一個函式

  • 為了區分建構函式和普通函式,JavaScript約定俗成

    • 建構函式,函式名稱 大駝峰命名法

    • 普通函式,函式名稱 小駝峰命名法

  • this指向

    • 使用 function 定義的函式,this指向,看的是呼叫之前寫的內容

    • 建構函式的 this,指向的都是通過建構函式,建立的物件

  • 建構函式的返回值,一定是一個物件,通過建構函式生成的物件,稱為例項化物件

  • 定義建構函式程式時,不要定義物件,不要定義return

四、原型

prototype:原型

  • 每一個函式天生就具有的自帶的屬性,叫做prototype

  • 以物件的形式,儲存公共的內容

  • 建構函式也是函式,也有 prototype

  • 例項化物件,可以直接指向呼叫建構函式 prototype 空間中的內容

 1 // 通過公共空間 prototype 定義函式方法
 2 function CreateObj(name,age){
 3   this.name = name;
 4   this.age = age;
 5 }
 6 
 7 CreateObj.prototype.fun = function(){
 8   console.log(this.name,this.age);
 9 }
10 
11 const obj1 = new CreateObj('張三' , 18);
12 const obj2 = new CreateObj('李四' , 20);
  • __proto__: 是每個 物件 都天生就具有的屬性

  • prototype:是每個 函式 都天生就具有的屬性,是 物件

  • 例項化物件,也是物件,只不過是通過建構函式生成的例項化物件

  • 此時例項化物件 __proto__ 指向的地址就是建構函式 prototype 記憶體地址

  • 通過 __proto__ 呼叫的就是建構函式 prototype 中的儲存的內容

  • 資料的呼叫和執行

    • 例項化物件在呼叫屬性和函式方法時,優先呼叫例項化物件本身的屬性和函式方法(也就是說例項化物件中有name屬性,prototype中也有name屬性,優先呼叫例項化物件本身的name屬性)

    • 如果呼叫例項化物件本身沒有的屬性,會去 __proto__ 也就是建構函式prototype中找是否有這個屬性

      • 如果有,就呼叫這個屬性

      • 如果都沒有這個屬性,執行結果是undefined

    • 如果想直接呼叫 __proto__ 也就是 建構函式 prototype 中定義的屬性,可以使用語法,例項化物件.__proto__.屬性

  • 實際專案中,prototype中只寫函式方法,不要寫屬性

五、原型鏈

  • prototype:原型物件

    • 每一個函式,天生都具有 prototype

  • __proto__:原型屬性

    • 每一個物件,天生都具有 __proto__

  • JavaScript中每一種資料型別本質上都是物件型別,每一種資料型別實際上都有__proto__屬性

  • 每一個數據型別 / 資料,都可以通過 __proto__ 找到生成這個資料型別的 建構函式的prototype

  • 建構函式,本身也有 __proto__ 可以再找這個建構函式的父級建構函式

  • 最終找到的都是 JavaScript中 頂級建構函式Object(),這個過程就是所謂的原型鏈

六、精確檢驗資料型別的方法

1、Object.prototype.toString

精確檢驗資料型別的方法儲存在 Object() 頂級中的方法

 1 // Object.prototype.toString.call( 要檢查的資料 )
 2 
 3 console.log(Object.prototype.toString.call(true)); // [object Boolean]
 4 console.log(Object.prototype.toString.call(100)); // [object Number]
 5 console.log(Object.prototype.toString.call(100.123));// [object Number]
 6 console.log(Object.prototype.toString.call(1e3)); // [object Number]
 7 console.log(Object.prototype.toString.call(NaN)); // [object Number]
 8 console.log(Object.prototype.toString.call('sting')); // [object String]
 9 console.log(Object.prototype.toString.call(undefined));  // [object Undefined]
10 console.log(Object.prototype.toString.call(null)); // [object Null]
11 console.log(Object.prototype.toString.call([])); // [object Array]
12 console.log(Object.prototype.toString.call({})); // [object Object]
13 console.log(Object.prototype.toString.call(function () { })); // [object Function]
14 console.log(Object.prototype.toString.call(new Date())); // [object Date]
15 console.log(Object.prototype.toString.call(/^\d$/)); // [object RegExp]

判斷資料是否是某個具體的資料型別時,判斷的字串也必須有 [ ]

1 console.log(Object.prototype.toString.call(true) === '[object Boolean]');

2、instanceof

  • instanceof用來判斷A是否為B的例項

  • instanceof檢測的是原型,內部機制是通過判斷物件的原型鏈中是否有型別的原型

1 {} instanceof Object; //true
2 [] instanceof Array;  //true
3 [] instanceof Object; //true
4 "123" instanceof String; //false
5 new String(123) instanceof String; //true

3、constructor

  • 當一個函式F被定義時,JS引擎會為F新增prototype原型

  • 然後在prototype上新增一個constructor屬性,並讓其指向F的引用

  • F利用原型物件的constructor屬性引用了自身

  • 當F作為建構函式建立物件時,原型上的constructor屬性被遺傳到了新建立的物件上

  • 從原型鏈角度講,建構函式F就是新物件的型別

1 ''.constructor == String // true
2 new Number(1).constructor == Number // true
3 true.constructor == Bollean // true
4 new Function().constructor == Function //true
5 new Date().constructor == Date // true
6 new Error().constructor == Error // true
7 [].constructor == Array // true
8 document.constructor == HTMLDoucment // true
9 window.constructor == window //true