云计算百科
云计算领域专业知识百科平台

爬虫逆行(3)-原型与原型链

爬虫逆行(3)-原型与原型链


前言

在浏览器里面,可以把原型看成浏览器内置对象的创建类,原型链指的是创建的类和它的父类之间的关系
浏览器内置对象拥有固定原生原型链结构,反爬会检测对象之间的原型引用链条,原型上的属性,对比标准浏览器特征;爬虫工具往往会篡改原型链,重写原生原型方法,一旦校验不匹配,就会被识别为爬虫

学习原型与原型链之前我们先了解一下javascript中类的创建与继承

  • 类使用class关键字创建,使用constructor完成参数初始化,类似于python中的__init__构造函数
  • extends完成继承
  • class Person{
    constructor(name) {
    this.name = name;
    }
    sayHello(){
    console.log(`${this.name} say hello`);
    }
    }

    class Student extends Person{
    constructor(name,age) {
    super(name);
    this.age = age;
    }
    introduce(){
    console.log(`${this.name} is ${this.age} years old`);
    }
    }

    var student_1 = new Student('Tommy',18);
    console.log(student_1);
    student_1.sayHello();
    student_1.introduce();

    上面的子类实例里面没有introduce方法,但是成功调用了?然后我们引入了/原型/的概念
    原型:本身是一个普通的对象,用来给别的对象共享属性和方法的,javascript里面类创建的方法默认被传入到了原型里面,所以我们可以直接在子类实例对象里面直接调用到introduce方法。

    console.log(student_1.hasOwnProperty('introduce'));
    console.log(student_1.__proto__.hasOwnProperty('introduce'));
    console.log(student_1.__proto__.__proto__.hasOwnProperty('introduce'));
    console.log(Student.prototype.hasOwnProperty('introduce'));

    这是基于上面代码的拓展,里面_proto__指的是隐式原型,prototype指的就是原型,student_1._proto===Student.prototype即类和其创建的类实例对象是全等的,写两个__proto__就是指该类的父类的隐式原型
    hasOwnproperty:检测一个属性是否为自身所拥有,有就返回true,没有就返回false

    请添加图片描述

    根据上面的输出可以说明,创建的introduce方法,被自动上传在了Student的原型里面,所以我们可以在实例对象student_1里面直接调用

    示例1

    请添加图片描述

    这里说明navigator的userAgent属性不在navigator对象下面,而是在原型上面

    //写一个脚本
    function Navigator(){}
    Navigator.prototype.userAgent = 'xxx'
    navigator = new Navigator()

    我们应该这样补环境

    示例2

    请添加图片描述

    这里说明该属性写在了document的父类的原型里面,dir(document)查看得到document在HTMLDocument里面HTMLDocument在Document里面

    function Document(){}
    Document.prototype.createElement = function(tag_name){
    console.log(tag_name);
    }
    function HTMLDocument(){}
    // 类之间的原型关系绑定,第一个是子类,第二个是父类
    Object.setPrototypeOf(HTMLDocument.prototype,Document.prototype);
    document = new HTMLDocument();

    console.log(document.hasOwnProperty('createElement'));
    console.log(document.__proto__.hasOwnProperty('createElement'));
    console.log(document.__proto__.__proto__.hasOwnProperty('createElement'));

    原型之间的关系就要这样写

    补充

    document里面createElement属性经常检测toString,这个属性必须和浏览器保持一致

    Document.prototype.createElement.toString = function(){
    return 'function createElement() { [native code] }';
    }

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 爬虫逆行(3)-原型与原型链
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!