关于js 的钩子的说明
功能
- 对指定类的 的属性进行打钩子,注意 不同类的实例都会触发钩子 proto-hook
var ph = require("proto-hook")
var fs = require("fs")
var { readFileSync: _readFileSync, existsSync: _existsSync, readFile: _readFile, exists: _exists } = fs
ph.watchProto(fs, "readFileSync", {
get() {
return function (dir) {
console.log("readFileSync", dir)
return _readFileSync.call(fs, ...arguments)
}
}
})
ph.watchProto(fs, "readFile", {
get() {
return function (dir) {
console.log("readFile", dir)
return _readFile.call(fs, ...arguments)
}
}
})
ph.watchProto(fs, "existsSync", {
get() {
return function (dir) {
console.log("existsSync", dir)
return _existsSync.call(fs, ...arguments)
}
}
})
//其他: /proto.test.js
var {watchProto} = require("./proto")
var debug = require("debug")("test")
debug.enabled = true
class Parent {
set pval(val) {
debug("%cparent.pval set", "red")
this.$$value = val
}
set size(val) {
// return Math.random() * 10 + 10
debug("%cparent.size set", "red")
this.$size = val
}
get size() {
debug("%cparent.size #get", "red")
return this.$size
}
}
class Base extends Parent {//
constructor() {
super()
console.log("Base init")
// console.log('\x1B[33m%s\x1b[0m:', "Base init"); //yellow
}
say() {
}
get name() {
console.log("Base get#name")
console.log(this)
return 30
}
set name(val) {
console.log("Base set.name")
console.log(this)
this.value = 33
}
set attr($var) {
this.$var = $var
}
}
var base = new Base()
watchProto(Base.prototype, "name")
watchProto(Base.prototype, "size")//__proto__
base.size = "base"
var base1 = new Base()
base1.size = "base1"// 钩子被触发
console.log("父属性:%s,%s", base.size, base1.size)
console.log("父属性:%s,%s", base.size, base1.size)
base.pval = "base.pval unhook"
// watchProto(Parent, "pval")
base.pval = "base.pval hook"
console.log(base.pval)
base.name = (Math.random() * 0xffffffffffffff).toString(36)
base1.name = (Math.random() * 0xffffffffffffff).toString(36)
console.log(`子属性:${base.name},${base1.name}`)
base.val = 55
console.log(base.name)
// console.log(Object.getOwnPropertyDescriptor(base.__proto__, "name"))
// console.log(Object.getOwnPropertyDescriptor(Base.prototype, "name"))
// let hasOwnProperty = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty)
/* require("util").inherits(Base, {
prototype: {
say1: () => {
console.log("say")
}
}
}) */
console.clear()
var base0 = {}
Object.defineProperty(base0, "name", {value: "base0"})
watchProto(base0, "attr", {get(val) {console.log(val); return 20} })
watchProto(base0, "attr1", {get(val) {console.log(val); return val} })
base0.attr = 30
console.log(Object.getOwnPropertyDescriptor(base0, "attr"))
console.log("base0.attr:%s", base0.attr)
base0.attr1 = "attr1"
console.log(base0.attr1)
console.log("base0.attr:%s", base0.attr)
console.log(base0.attr1)
console.log(base0)
watchProto(Date.prototype, "getTime", {get(val) {console.log("Date#getTime"); return Date.prototype.getDay} })
console.log(new Date().getTime())
用proxy实现的钩子 见文件 ‘/protoByProxy.test.js’
var { proxyClass, proxyObject } = require("./protoByProxy")
var Array0 = proxyClass(Array)
console.log(new Array0().forEach(v => {
console.log(v)
}))
class M {
constructor() {
this.w = 30
}
get x() {
return this.w
}
set x(val) {
this.w = val
}
}
var obj = {
a: 20
}
var objb = {
set a(val) {
this.val = 30
console.log()
},
val: 50,
get a() {
return this.val
}
}
var hookInstance = {
watchObj(prop, val, that) {
console.log("get", prop, val)
},
beforeObjChang(prop, val) {
console.log("beforeObjChang", prop, val)
},
afterObjChang(prop, val) {
console.log("afterObjChang", prop, val)
}
}
var obj = proxyObject(obj, hookInstance)
console.log(obj.a)
obj.a = 30
var Mp = proxyClass(M, { instanceHook: hookInstance,hookBefore(args){
console.log("构造前",args)
},hookAfter(args,res){
console.log("构造后", args, res)
}})
var mp = new Mp()
console.log(mp.x)
mp.x = 50