核动力 发表于 2023-8-22 13:17:16

13 JavaScript关于prototype(超重点)

13 JavaScript关于prototype(超重点)
prototype是js里面给类增加功能扩展的一种模式.
写个面向对象来看看.
function People(name, age){
    this.name = name;
    this.age = age;
    this.run = function(){
      console.log(this.name+"在跑")
    }
}

p1 = new People("张三", 18);
p2 = new People("李四", 19);

p1.run();
p2.run();我现在代码写完了. 突然之间, 我感觉好像少了个功能. 人不应该就一个功能. 光会吃是不够的. 还得能够ooxx. 怎么办?直接改代码?可以. 但不够好. 如果这个类不是我写的呢? 随便改别人代码是很不礼貌的. 也很容易出错. 怎么办?我们可以在我们自己代码中对某个类型动态增加功能. 此时就用到了prototype.
function People(name, age){
    this.name = name;
    this.age = age;
    this.run = function(){
      console.log(this.name+"在跑")
    }
}

// 通过prototype可以给People增加功能
People.prototype.xxoo = function(){
    console.log(this.name+"还可以xxoo");
}

p1 = new People("张三", 18);
p2 = new People("李四", 19);

p1.run();
p2.run();

p1.xxoo();
p2.xxoo();能看到一些效果了是吧. 也就是说. 可以通过prototype给我们的对象增加一些功能.
接下来. 聊几个重要的概念.

[*]构造器
构造一个对象的函数. 叫构造器.
function People(){//这个东西就是构造器 constractor

}

var p = new People(); // 调用构造器
p.constractor == People; // true
[*]原型对象
每一个js对象中. 都有一个隐藏属性__proto__指向该对象的原型对象. 在执行该对象的方法或者查找属性时. 首先, 对象自己是否存在该属性或者方法. 如果存在, 就执行自己的. 如果自己不存在. 就去找原型对象.
function Friend(){
    this.chi = function(){
      console.log("我的朋友在吃");
    }
}
Friend.prototype.chi = function(){
    console.log("我的原型在吃")
}

f = new Friend();
f.chi(); // 此时. 该对象中. 有chi这个方法.同时, 它的原型对象上, 也有chi这个方法.
// 运行结果:
// 我的朋友在吃
[*]prototype和__proto__有什么关系?
在js中. 构造器的prototype属性和对象的__proto__是一个东西.都是指向这个原型对象.
f.__proto__ === Friend.prototype   // true
[*]原型链
这个比较绕了. 我们从前面的学习中, 了解到. 每个对象身体里. 都隐藏着__proto__也就是它的原型对象. 那么我们看哈, 原型对象也是对象啊, 那么也就是说. 原型对象也有__proto__属性.
类似于.....这样:
f.__proto__.__proto__打印出来的效果是这样的:

此时. 又出现一堆看不懂的玩意. 这些玩意是什么?这些其实是Object的原型.
f.__proto__.__proto__ === Object.prototype所以, 我们在执行f.toString()的时候不会报错. 反而可以正常运行. 原因就在这里.
执行过程:先找f对象中是否有toString. 没有, 找它的原型对象.原型对象中没有, 继续找原型对象的原型对象. 直至你找到Object的原型为止. 如果还是没有. 就报错了.
f.hahahahahahah()// 报错. 综上, 原型链是js 方法查找的路径指示标.
5. 我们用原型链能做什么?(每日一恶心)
我们来看一段神奇的代码.
(function(){debugger})();这样一段代码可以看到. 浏览器进入了debugger断点.
那么这段代码的背后是什么呢?注意. 在js代码执行时. 每一个function的对象都是通过Function()来创建的. 也就是说. 函数是Function()的对象.
function fn(){}
console.log(fn.proto.constructor); // ƒ Function() { }
这样一段代码可以看到. 浏览器进入了debugger断点.
那么这段代码的背后是什么呢?注意. 在js代码执行时. 每一个function的对象都是通过Function()来创建的. 也就是说. 函数是Function()的对象.
function fn(){}
console.log(fn.__proto__.constructor); // ƒ Function() { }函数就是Function的对象. 那么. 我们可以通过Function来构建一个函数.
new Function('debugger')();OK. 这东西对我们来说有什么用.上代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
   

</head>
<body>
    有内鬼. 终止交易
</body>
</html>haha.js中的内容如下:
function txsdefwsw() {
    var r = "V", n = "5", e = "8";

    function o(r) {
      if (!r) return "";
      for (var t = "", n = 44106, e = 0; e < r.length; e++) {
            var o = r.charCodeAt(e) ^ n;
            n = n * e % 256 + 2333, t += String.fromCharCode(o)
      }
      return t
    }

    try {
      var a = ["r", o("갯"), "g", o("갭"), function (t) {
            if (!t) return "";
            for (var o = "", a = r + n + e + "7", c = 45860, f = 0; f < t.length; f++) {
                var i = t.charCodeAt(f);
                c = (c + 1) % a.length, i ^= a.charCodeAt(c), o += String.fromCharCode(i)
            }
            return o
      }("@"), "b", "e", "d"].reverse().join("");
      !function c(r) {
            (1 !== ("" + r / r).length || 0 === r) && function () {
            }.constructor(a)(), c(++r)
      }(0)
    } catch (a) {
      setTimeout(txsdefwsw, 100);
    }
}页面跑起来没什么问题. 但是会无限debugger;
解决方案:

[*]找到断点出. 右键-> never pause here;
[*]写js hook代码;
var x = Function; // 保留原来的Function
Function = function(arg){
        arg = arg.replace("debugger", "");
        return new x(arg);
}

var qiaofu_function_constructor = (function(){}).__proto__.constructor;
(function(){}).__proto__.constructor = function(arg){
        console.log("我爱你大大");
        if(arg ==='debugger'){
                return function(){}
        } else {
                return new qiaofu_function_constructor(arg);
        }
}
[]
__proto__
构造器.prototype
function jiami(){

}
jiami.prototype.md5 = function(){}
jiami.prototype.aes = function(){}
jiami.prototype.encrypt = function(){}
var s = new jiami();
s.md5();
来源:https://www.cnblogs.com/zczhaod/p/17647961.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 13 JavaScript关于prototype(超重点)