一、原型链:JavaScript的"家族继承"机制
你的家谱:你 → 父母 → 祖父母 → 外祖父母 → ... → 最终到“祖先”
在js中,对象的原型链就好像家谱链一样
1)每个对象都有一个隐形的_proto_属性来指向父辈对象(及原型)
2)当访问一个对象的属性或者方法时,如果找不到,就会沿着_proto_属性往上找,直到找到或找到源头(null)
const obj = { name: '小明' };
console.log(obj.toString()); // 输出:"[object Object]"
在上述代码中:
toString() 方法其实不是 obj 自己的,而是从原型链上找的
obj → obj.__proto__ → Object.prototype → Object.prototype.__proto__ → null
在 Object.prototype 上找到了 toString() 方法。
二:什么是补环境
简单来说。现在要在网页中拿走一段代码(破解加解密逻辑)。但这段代码会检测:我是不是在浏览器中运行?有没有window,document,navigator这些浏览器特有的对象?等。。。
如果这个时候运行失败就需要补环境。伪造一个假的浏览器环境。让代码误以为自己真的在浏览器中执行。
三:步骤
1):
// 创建一个空的 window 对象
const fakeWindow = {};
// 创建一个 fakeNavigator 对象
const fakeNavigator = {
userAgent: 'Mozilla/5.0 (假浏览器)...'
};
// 创建一个 fakeDocument 对象
const fakeDocument = {
title: '假网页标题'
};
2):
// 设置 fakeWindow 的原型链,让它看起来像浏览器的 window
fakeWindow.__proto__ = Object.prototype; // window 的原型通常是 Object.prototype
// 设置 fakeNavigator 的原型链,让它继承 Object 的方法
fakeNavigator.__proto__ = Object.prototype;
// 设置 fakeDocument 的原型链
fakeDocument.__proto__ = Object.prototype;
// 将 navigator 和 document 挂载到 window 上
fakeWindow.navigator = fakeNavigator;
fakeWindow.document = fakeDocument;
其他补环境的工具:
puppeter、控制真实的 Chrome 浏览器,避免补环境的麻烦。
jsdom:
在 Node.js 中模拟浏览器的 DOM 环境