前言
大家好 我是歌谣 今天继续给大家带来的是对数字的函数劫持
文件目录
依赖文件
{
"name": "geyaohandvue2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "rollup -cw"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.23.3",
"@babel/preset-env": "^7.23.3",
"rollup": "^2.79.1",
"rollup-plugin-babel": "^4.4.0"
}
}
observe-----array.js
let oldArrayProto=Array.prototype;
export let newArrayProto=Object.create(oldArrayProto)
let methods=['push','pop','shift','unshift','reserve','sort','splice']
methods.forEach(method=>{
newArrayProto[method]=function(...args){
const result=oldArrayProto[method].call(this,...args)
let inserted;
let ob=this.__ob__;
switch(method){
case 'push':
case 'unshift':
inserted=args;
break
case 'splice':
inserted=args.splice(2);
break
default:
break
}
console.log(inserted)
if(inserted){
ob.observeArray(inserted)
}
return result
}
})
observe-index.js
import { newArrayProto } from "./array"
class Observer{
constructor(data){
Object.defineProperty(data,'__ob__',{
value:this,
enumerable:false
})
// data.__ob__=this
if(Array.isArray(data)){
data.__proto__=newArrayProto
this.observeArray(data)
}else{
this.walk(data)
}
}
walk(data){
Object.keys(data).forEach(key=>defineReacttive(data,key,data[key]))
}
observeArray(data){
data.forEach(item=>observe(item))
}
}
export function defineReacttive(target,key,value){
observe(value)
Object.defineProperty(target,key,{
get(){
console.log("用户取值了")
return value
},
set(newValue){
console.log("用户设置值了")
if(newValue===value) return
value=newValue
}
})
}
export function observe(data){
if(typeof data!=='object'||data==null){
return;
}
if(data.__ob__ instanceof Observer){
return data.__ob__
}
return new Observer(data)
// 判断一个对象是否被劫持
}
index.js
import { initMixin } from "./init"
function Vue(options){
this._init(options)
}
initMixin(Vue)
export default Vue
init.js
import { initState } from "./state"
export function initMixin(Vue){
Vue.prototype._init=function(options){
// $options 获取用户的配置
const vm=this
vm.$options=options
initState(vm)
}
}
state.js
import { observe } from "./observe/index"
export function initState(vm) {
const opts = vm.$options
if (opts.data) {
initData(vm)
}
}
function proxy(vm,target,key){
Object.defineProperty(vm,key,{
get(){
return vm[target][key]
},
set(newValue){
vm[target][key]=newValue
}
})
}
function initData(vm) {
let data = vm.$options.data
data=typeof data === 'function' ? data.call(vm) : data
console.log(data)
vm._data = data
observe(data)
for(let key in data){
proxy(vm,'_data',key)
}
}