// 一、定義變量arrayProto接收Array的prototype
// 二、定義變量arrayMethods,經過Object.create()方法繼承arrayProto
// 三、從新封裝數組中push,pop等經常使用方法。(這裏咱們只封裝咱們須要監聽的數組的方法,並不作JavaScript原生Array中原型方法的重寫的這麼一件暴力的事情)
// 四、其餘js數組變化監聽方法
// 1,得到數組的原型
const
arrayProto =
Array.
prototype
const
arrayMethods =
Object.
create(
arrayProto)
const
newArrProto = []
const
method = [
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
]
method.
forEach(
function (
method) {
// 原生Array的原型方法
let
original =
arrayMethods[
method];
// 將push,pop等方法從新封裝並定義在對象newArrProto的屬性上
// 這裏須要注意的是封裝好的方法是定義在newArrProto的屬性上而不是其原型屬性
// newArrProto.__proto__ 沒有改變
newArrProto[
method] =
function
mutator() {
console.
log(
'監聽到數組的變化啦!');
// 調用對應的原生方法並返回結果(新數組長度)
return
original.
apply(
this,
arguments);
}
});
// 將咱們要監聽的數組的原型指針指向上面定義的空數組對象
// newArrProto的屬性上定義了咱們封裝好的push,pop等方法
var
list = [
1,
2]
list.
__proto__ =
newArrProto;
list.
push(
3);
// 監聽到數組的變化啦! 3
// 這裏的list2沒有被從新定義原型指針,因此這裏會正常執行原生Array上的原型方法
let
list2 = [
1,
2];
list2.
push(
3);
// 3
// 另外還有es6實現的方式
class
NewArray
extends
Array {
constructor(...
args) {
super()
}
push(...
args) {
console.
log(
"監聽數組的變化")
return
super.
push(...
args)
}
}
let
list3 = [
1,
2];
let
arr =
new
NewArray(...
list3);
console.
log(
arr)
// (2) [1, 2]
arr.
push(
3);
// 監聽到數組的變化啦!
console.
log(
arr)
// (3) [1, 2, 3]