catvm/__bak/step.js
Big1moster d843fcb236 dsf
2023-02-06 11:36:48 +08:00

113 lines
4.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

function Person(option) {
//一般传入字面量对象做参数
//new之后自动创建一个空对象把这个对象的地址给this即var this = new Object();
//this给空对象绑定属性和行为
this._init(option);
this.name = option.name;
this.eat = function(food) {
console.log("吃" + food)
}
;
//自动默认return this;如果有存在 return 对象则不返回this若return 非对象则依然return this
}
Person.prototype = {
//所有此对象共享的属性和方法
_init: function(option) {
this.earth = option.earth;
},
run: function(where) {
console.log(this.name + "在" + where + "泡");
}
};
var per = new Person({
name: "dsf"
});
//向构造函数传入字面量对象
per.eat("牛排");
//调用对象方法
一般补环境的几个步骤
比如补Navigator
1先在浏览器环境观察该对象Navigator
能否进行new Navigator,不能的话则在其构造函数定义中抛出异常能的话不抛
查看其原型Navigator.prototype 的属性方法原型链
发现Navigator原型属性方法不能通过原型调用
Navigator.appVersion 会抛出异常
发现 其原型链只有一层即Navigator.prototype.__proto__ === Object.prototype
2在浏览器环境观察其实例对象navigator
查看其属性方法与 原型上的差异发现差不多基本都是继承原型的
3补环境
定义Navigator 构造函数并保护其toString,
定义navigator对象将其原型指向Navigator即navigator.__proto__ = Navigator.prototype;
如果是多层原型的话需要多次指向
补全原型上的属性方法
Navigator.prototype.plugins = [];
Navigator.prototype.languages = ["zh-CN", "zh"];
补全实例上的属性方法不要与继承自原型的属性方法冲突
4代理该对象 navigator
补一个方法如location.reload()
需要看其是在原型上还是实例上这会决定我们是在原型上补还是在实例上补唯一区别
通过浏览器环境观察发现reload是在location实例上定义的
因此我们直接在location实例上补该方法
location = class location{};
//此处必须给个方法名因为toString会默认调用该方法可能会检测该方法名location.reload.toString时
// 会将该方法定义(包括方法定义中的注释)都输出
// egloca.reload.toString()
// 'function reload(){ //此处必须给个方法名因为toString会默认调用该方法可能会检测该方法名\n\n}'
location.reload = function reload(){
};
定义完方法之后需要对方法进行保护
func_set_native(location.reload);
一般补环境的几个步骤
比如补Navigator
1先在浏览器环境观察该对象Navigator
先查看其原型链发现只有一层即 Navigator.prototype.__proto__ 为Object原型
能否进行new Navigator,不能的话则在其构造函数定义中抛出异常能的话不抛
var Navigator = function Navigator() { // 构造函数
throw new TypeError("Illegal constructor");
};
然后保护该方法
catvm.safefunction(Navigator);
然后给其原型一个名字
Object.defineProperties(Navigator.prototype, {
[Symbol.toStringTag]: {
value: "Navigator",
configurable: true
}
}
});
在浏览器查看其实例navigator是否存在存在的话我们也要定义一个
navigator = {};
然后指定其原型
navigator.__proto__ = Navigator.prototype;
此时对比浏览器原型链确定我们原型已经补完接下来就是填充navigator的原型方法属性实例方法属性
对比浏览器上navigator的原型与实例上方法属性的差异将原型上的补到我们原型上实例上的补到实例上两者都有的优先补到原型上
Navigator.prototype.plugins = [];
Navigator.prototype.languages = ["zh-CN", "zh"];
...
然后在最末尾加上代理
navigator = catvm.proxy(navigator);
最终在调试网站js环境代码时根据log一个个补浏览器上输出啥我们就补成啥如果log输出本来就跟浏览器上的
一致则不用动继续去看下一个log
遇到不清楚的属性方法 https://developer.mozilla.org/上查看