1. OOP數組
面向對象三大特色: 封裝,繼承,多態瀏覽器
封裝:ide
問題: 構造函數可重用代碼和結構定義,但沒法節約內存函數
爲何: 放在構造函數內的方法定義,每new一次,都會反覆建立副本——浪費內存this
解決: 繼承prototype
繼承:對象
什麼是: 父對象的成員,子對象無需重複建立,就可直接使用繼承
爲何: 代碼重用, 節約內存內存
什麼時候: 只要發現多個子對象,但願擁有共同的方法定義時原型鏈
如何: js中都是經過繼承原型對象來實現繼承關係
原型對象: 集中存儲多個子對象,共有成員的父對象
什麼時候: js中只要實現繼承,都要使用原型對象
如何:
建立: 不用本身建立。買一贈一!
只要建立一個構造函數,都附贈一個原型對象
構造函數的prototype屬性指向原型對象
如何繼承: 不用本身繼承。
new的第二步: 讓新對象自動繼承構造函數的原型對象
本質: 設置新對象的__proto__指向父對象
凡是從__proto__指出的引用,都是繼承關係
咱們作什麼: 決定將那些方法集中添加到原型對象中
構造函數中,再也不包含任何方法定義
調用對象的方法時:
如今子對象本地找方法,
若是找不到,就延__proto__,向父元素查找
內置對象的原型對象:
內置對象: ES標準中規定的,瀏覽器廠商已經實現的對象
11個:
String Number Boolean ——包裝類型
Array Date RegExp Math
Error
Function Object
Global(瀏覽器中被window代替)
其實能new的,都是構造函數
每一個構造函數都有一個原型對象
原型對象中保存着該類型的全部子對象共用的API
問題: 舊瀏覽器不支持新的API
解決: 在該類型的原型對象中添加自定義方法
強調: 在方法內,可用this指代未來調用該方法的.前的對象
捷徑: 在網上搜索: MDN 類型.prototype.方法名
找Polyfill, 直接複製粘貼便可
包裝類型: String Number Boolean
什麼是: 專門保存原始類型的值,並提供操做原始類型值的API
爲何: 原始類型的值自己什麼功能都沒有
什麼時候: 只要用原始類型的值,打.訪問方法或屬性時
如何: 不用本身用!
好比: var n=345.678; n.toFixed(2);
typeof n number
new Number(n).toFixed(2) 345.68
//new Number釋放
var str="hello"; str.replace("o","0");
typeof str string
new String(str).replace("o","0");
//new String釋放
原型鏈(prototype chain):
什麼是: 由多級父元素,逐級繼承,造成的鏈式結構
保存着全部對象,以及對象的成員
控制着對象成員的使用順序:
先自有,再向父級找共用
vs 做用域鏈:
保存全部孤立的變量, 控制着變量的使用順序:
先局部,後全局
自有屬性 vs 共有屬性:
自有屬性: 當前對象本地保存的屬性
共有屬性: 原型鏈中父級對象中的屬性
讀取屬性值: 子對象.屬性名
修改屬性值: 自有屬性: 用子對象.屬性名=值
共有屬性: 必須用父對象.屬性名=值
鄙視: 判斷一個對象是數組, 共有幾種方法: 4種
typeof: 只能區分原始類型和function
不能進一步區分引用類型
1. 判斷原型對象:
//obj.__proto__==Array.prototype
father.isPrototypeOf(child)
判斷father是否是child的父對象
判斷數組: Array.prototype.isPrototypeOf(obj)
2. 判斷構造函數:
//obj.constructor == Array
child instanceof 構造函數
判斷child是不是構造函數new出的子對象
判斷數組: obj instanceof Array
問題: 不夠嚴格: 不但檢查直接父對象,並且檢查整個原型鏈
解決: 驗證對象的class屬性
3. 驗證對象的class屬性:
每一個對象都有一個隱藏的class屬性(不能用.直接訪問)
class屬性的值,在建立對象時就肯定了,用於保存類型名
class屬性不隨後天繼承關係的改變而改變
如何得到class屬性:
惟一的辦法: 調用頂級父對象Object.prototype中的toString()
問題: 每種內置類型的原型對象都重寫了頂級父對象中的toString(),已經再也不返回class屬性值
全部子對象沒法調用到Object.prototype中的toString()
解決: 搶!
要搶的函數.call(對象)
在執行時: 對象.要搶的函數()
判斷對象是否是數組類型:
Object.prototype.toString.call(obj)==="[object Array]"
用obj去搶頂級父對象中的toString(),若是返回"[object Array]" 就說明是數組
4. Array.isArray(obj)
多態:
什麼是: 同一個函數在不一樣狀況下表現出不一樣的狀態
包括:
1. 重載:
2. 重寫(override):
什麼是: 子對象定義了和父對象相同的成員
爲何: 從父對象繼承來的東西,可能很差用
什麼時候: 只要以爲從父對象繼承來的東西,很差用
如何: 在子對象中定義和父對象重名的成員
自定義繼承關係: 3種:
1. 僅修改一個對象的父對象:
//child.__proto__=father
Objext.setPrototypeOf(child,father)
2. 批量修改全部子對象的父對象:
構造函數.prototype=father
時機: 在定義構造函數後,馬上更換