Object.defineProperty()
- Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
- 参数:
- obj: 需要定义属性的对象
- prop: 要定义或修改属性的名称或symbol
- descriptor: 要定义或修改的属性描述符 - 返回值:
-
- 被传递给函数的对象
Object.setPrototypeOf()
- Object.setPrototypeOf()方法设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或 null。
- 参数:
- obj: 要设置其原型的对象
- prototype: 该对象的新原型(一个对象 或null)
function isObject (target) {
return typeof target === 'object' && null !== target
}
let oldProto = Array.prototype
let protoMethods = Object.create(oldProto)
let methods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']
methods.forEach(method => {
protoMethods[method] = function (...args) {
let inserted
switch (method) {
case 'push':
case 'unshift':
inserted = args
break
case 'splice':
inserted = args.slice(2)
break
}
observeArray(inserted)
oldProto[method].apply(this, args)
}
})
function observeArray(arr) {
for(let i=0;i<arr.length;i++) {
let item = arr[i]
observe(item)
}
}
function observe (target) {
if (!isObject(target)) {
return target
}
if (Array.isArray(target)) {
observeArray(target)
Object.setPrototypeOf(target, protoMethods)
}else {
Object.keys(target).forEach(key => {
defineReactive(target, key, target[key])
})
}
}
function defineReactive (obj, key, value) {
observe(value)
Object.defineProperty(obj, key, {
get() {
console.log('get')
return value
},
set(newValue) {
console.log('set')
if (newValue !== value) {
observe(newValue)
value = newValue
}
}
})
}
let obj ={
arr: [1,2,3,4, {d: 5}],
name: 'zs',
age: 18,
a: {
b: 100
}
}
observe(obj)
obj.arr.push(6)
obj.arr.splice(2, 0 ,8)
console.log(obj.arr)