淺談JS物件導向

wq93發表於2018-08-16

物件導向的基本概念

一、 物件導向的概念

物件導向是一種思維方式,把解決問題的關注點放在瞭解決問題所需要的一些列的物件上

程式導向的概念

程式導向也是一種思維方式,把解決問題的關注點放在瞭解決問題的每一個詳細的步驟上!

概念補充

行為 說明
宣告 告訴編譯器/解析器有這個變數存在,這個行為是不分配記憶體空間的,在JavaScript中,宣告一個變數的操作為:var a;
定義 為變數分配記憶體空間,在C語言中,一般宣告就包含了定義,比如:int a;,但是在JavaScript中,var a;這種形式就只是宣告瞭。
初始化 在定義變數之後,系統為變數分配的空間記憶體儲的值是不確定的,所以需要對這個空間進行初始化,以確保程式的安全性和確定性
賦值 賦值就是變數在分配空間之後的某個時間裡,對變數的值進行的重新整理操作(修改儲存空間內的資料)

陣列的index of方法

indexOf在陣列中查詢元素,找到了返回索引,沒找到返回-1
舉個栗子:
var arr = [{}, [], /s/];
console.log(arr.indexOf({}));    //-1
console.log({}==={})    //false    字面量就是在建立物件    兩個空物件是不相等的
正確寫法:
var obj = {};
var arr = [];
var reg = /s/;
var arr = [obj, arr ,reg ];
console.log(arr.indexOf(obj));
複製程式碼

物件導向的概念

物件導向就是一種思維方式,將解決問題的關注點放在解決問題所需要的一系列的物件上

程式導向概念

程式導向就是一種思維方式,將解決問題的關注點放在解決問題的每一個詳細步驟上

物件導向和麵向過程的關係

物件導向就是對程式導向的封裝,有了物件導向,也不能忘記程式導向!

什麼是物件,什麼是js物件

萬物皆物件 無序的鍵值對兒集合

物件導向的三大特性

  • 封裝 將屬性和方法封裝在物件內實現某些功能,在物件外部暴露一些介面,外部在使用物件的時候,只需要關心介面的使用,不需要關心物件內部的功能的具體實現
  • 繼承 自己沒有的,別人有,拿過來用,就是繼承
  • 多型 父類指標指向子類的物件,js中沒有多型

建立物件的方式

  1. 字面量
var obj = {key: value, key: value};
複製程式碼
  1. 內建建構函式
var obj = new Object();
複製程式碼
  1. 自定義建構函式
function Test(){}
var obj = new Test();
複製程式碼

建構函式

概念

構造也是一個函式,他是用來初始化物件的!

建構函式的特點

  1. 首字母大寫
  2. 和new關鍵字一起使用
  3. 不需要手動寫返回值

建構函式的執行過程

  1. 使用new關鍵字建立物件
  2. 呼叫建構函式,將建構函式內的this指向new建立出來的物件
  3. 使用this為物件新增成員
  4. 預設的返回建立出來的物件

建構函式的注意事項

  • 如果手動給建構函式寫返回值:
    1. 如果返回的是值型別,不會對返回值有任何的影響
    2. 如果返回的是引用型別,則返回這個引用型別的資料,之前建立的物件會被拋棄
  • 如果把建構函式當做普通函式來呼叫,那麼函式中的this就指向window,返回值和普通函式一樣

原型

概念

建構函式在建立出來的時候,系統會預設的幫建構函式建立並且關聯一個空的物件,這個物件就是原型

作用

在原型中的所有的成員,可以被何其關聯的建構函式所建立的所有例項共享!!

原型的訪問方式

  1. 建構函式.prototype
  2. 例項 .proto (不推薦使用,因為是非標準的屬性)

原型的使用方式

  1. 利用物件的動態特性為原型物件新增成員
  2. 直接替換建構函式的原型屬性(手動新增 constructor:函式名 屬性)

注意事項

  1. 一般將方法放在原型當中,屬性放在物件裡
  2. 當使用物件訪問屬性的時候,會現在物件中進行查詢,如果沒有就會去原型中查詢
  3. 替換原型的時候需要注意,替換之前建立的物件和替換之後建立的物件的原型不一致

原型鏈

物件都有原型,原型也是物件,所以原型也有原型,這樣就形成了一個鏈式結構,稱作原型鏈

屬性搜尋原則

  1. 當使用物件訪問屬性的時候,會現在物件自身進行查詢,如果有,就直接使用
  2. 如果沒有,就去物件的原型中進行查詢,如果有,就直接使用
  3. 如果沒有,就沿著原型鏈依次向上查詢,直到找到,如果到null還沒有找到,就會出問題

注意: 屬性在設定的時候,不遵守屬性搜尋原則,只會在自身進行查詢,如果有就修改,如果沒有就新增

繼承的實現方式

  1. 混入式繼承(mix-in)for-in
  2. 原型繼承 2.1. 利用混入的方式為原型物件新增成員,以實現繼承 2.2. 直接將物件的原型替換,實現繼承
  3. 經典繼承 Object.create()
function myCreate(obj){
    if(Object.create){
        return Object.create(obj);
    }else{
        function F(){}
        F.prototype = obj;
        return new F();
    }
}
複製程式碼

Object.prototype的成員

  • constructor
  • hasOwnProperty
  • isPrototypeOf
  • propertyIsEnumerable
  • toString
  • toLocaleString
  • valueOf []==![] {}==!{}
  • proto

instanceof關鍵字

物件  instanceof 建構函式
複製程式碼

判斷建構函式的原型是否在物件的原型鏈上

Function的使用

  1. 沒有引數建立的是空函式
  2. 傳一個引數,這個引數會被作為函式體
  3. 傳多個引數,前面的引數都是函式的形參名,最後一個引數為函式體
var 函式名 = new Function(arg1....argN, methodBody);
//函式名.name 為anonymous
複製程式碼

eval的使用

將字串轉成js程式碼並執行

eval(符合js語法規範的字串)
複製程式碼

Function和eval的異同

都可以將字串轉換成jsdaima Function建立出來的是函式,需要手動呼叫才能執行 eval會直接執行

都存在如下問題:

  1. 執行效率問題
  2. 安全性問題

函式的原型鏈

函式也是物件,所以函式也有原型

Function是js中所有函式的建構函式,包括Function自己

完整的原型鏈

argumnets物件

函式內部的一個物件,是一個偽陣列,在函式呼叫的時候,會將所有的實參依次存入這個偽陣列中

  • length 可以表示傳入的實參的個數
  • callee 指向arguments物件所在的函式

函式物件的成員

  • arguments 函式內部的arguments物件
  • caller 函式的呼叫環境,如果是在全域性呼叫就是null,如果是在某個函式中呼叫,那就是那個函式
  • length 形參個數
  • name 函式的名
var fn = function(){};

過載  overload  js中沒有

//JS模擬其他語言的函式過載概念
function test(){
    if(arguments.length ==1){
        //功能程式碼
    }else if(arguments.length==2){
       //功能程式碼 
   }
   ......
}

//函式名相同,引數列表不同
var obj = {
    sayHi:function(){},
    sayHi:function(a){},
    sayHi:function(a, b){}
}
複製程式碼

相關文章