当前位置: 首页 > news >正文

爬虫逆向--Day25Day26--原型链补环境

一、文件描述符

属性描述符有两种主要类型:数据描述符存取描述符。你不能同时使用两者。

1. 数据描述符 (Data Descriptor)

描述一个具有值的属性。

  • value:该属性对应的值。默认为 undefined

  • writable:布尔值,表示属性的值(value)是否可以被改变(例如通过赋值运算符)。默认为 false

  • configurable:布尔值,表示该属性的描述符能否被改变,以及该属性能否从对象上被删除。默认为 false

  • enumerable:布尔值,表示该属性是否可枚举(例如是否会出现在 for...in 循环或 Object.keys() 中)。默认为 false

    let student01 = {name: "yuan",age: 18,height: 180
    }// (1) 对象属性的基础操作
    
    console.log(student01)              // { name: 'yuan', age: 18, height: 180 }
    console.log(student01.name)         // yuan
    student01.age = 19
    console.log(student01.age)          // 19
    student01.weight = "70kg"
    console.log(student01.weight)       // 70kg// (2) enumerable:是否可迭代  便利,循环 默认是true
    Object.defineProperty(student01,"weight",{enumerable:false   // 意思就是,我在便利这个对象student01的时候,这个属性weight的key不会被打印出来
    })for (const student01Key in student01) {console.log(student01Key)     // name  age  height
    }/*
    // (3) configurable:是否可配置  默认是true  是可以配置的
    Object.defineProperty(student01,"weight",{enumerable:true,configurable:false    //不可以配置  所以下面就不可以在进行Object.defineProperty在进行配置了,在配置就会报错误
    })//因为上面configurable:false  不可配置,所以这里在配置就会报错误
    Object.defineProperty(student01,"weight",{enumerable:true,configurable:false
    })
    */// (4) writable:value值是否可以改变
    Object.defineProperty(student01,"weight",{enumerable:true,configurable:true,writable:true,    // 是否可写  student01.weight = "60kg"
    })student01.weight = "60kg"       // 对这个weight写入
    console.log(student01.height)   // 180
    console.log(student01.weight)   // 60kg  读取这个weight 这个属性的值  因为不存在所以是undefined// (5) value:属性对应的值
    Object.defineProperty(student01,"weight",{enumerable:true,configurable:true,writable:true,value:"60kg"    // 给一个默认值
    })student01.weight = "70kg"
    console.log(student01.height)       // 180
    console.log(student01.weight)       // 70kg//(6) get方法和set方法
    weight_val = "60kg"
    Object.defineProperty(student01,"weight",{enumerable:true,configurable:true,get:function (){console.log("student01正在获取属性weight")return weight_val},set:function (val){console.log("student01.weight正在赋值")// this.weight = val //  无限递归weight_val =val},// value:""// value不能和get、set混搭
    })console.log(student01.weight)
    student01.weight = "80kg"
    console.log(student01.weight)
    /*
    student01正在获取属性weight
    60kg
    student01.weight正在赋值
    student01正在获取属性weight
    80kg*/

二、原型链

在JavaScript中,每个对象都有一个特殊的属性叫做"prototype"(原型)。它是一个指向另一个对象的引用,在对象之间实现继承关系。

当你访问一个对象的属性或方法时,如果该对象自身没有这个属性或方法,JavaScript引擎会自动去该对象的原型中查找。如果原型中也没有找到,那么会继续在原型的原型中查找,直到找到该属性或方法或者到达原型链的末尾。

在JavaScript中,原型的概念与面向对象编程的继承紧密相关。你可以通过原型来共享属性和方法,从而实现对象之间的继承关系。

案例1:

function Person(name) {this.name = name;
}
​
Person.prototype.greet = function() {console.log("Hello, my name is " + this.name);
};
​
var person = new Person("John");
person.greet(); // 输出:Hello, my name is John
  1. prototype(原型对象)就是一个容器. {},存放公共的方法或者属性给对象使用.

  2. 对象可以直接访问原型对象中的方法和属性.

  3. 原型对象类似Python的类对象(fn.prototype)

原型对象和函数之间的关系.

  • 每个函数都会有一个prototype属性,指向原型对象.

  • 每个原型对象都会有一个constructor属性,指向函数.

  • 总结:每个函数与原型对象之间的关系是互相引用.

img

对象和原型对象和函数之间的关系

  • 函数创建对象var o = new Fn();

  • 对象通过__proto__属性,指向原型对象.

  • 对象可以直接调用原型对象中所有的属性和方法.

  • 对象可以通过原型对象中的constructor属性知道构造函数

  • 总结: 原型对象就是一个容器,帮助函数存放公共方法,以及给函数new出来的对象提供公共方法使用.

img

function Dog(name, age) {this.name = name;//面试题:构造函数中的this指向谁? 答:指向new创建的对象this.age = age;this.sleep = function () {console.log("sleeping")}}// Dog("rain",12) // 普通函数
//构造函数
let alex = new Dog("alex", 36);   // 使用new来创建对象
let eric = new Dog("eric", 35);   // 使用new来创建对象// (1) 函数对象通过prototype容器设置公共属性和方法
Dog.prototype.eat = function (food) {console.log(this.name +"吃"+ food);
}alex.eat("吃骨头")      // alex吃吃骨头
eric.eat("吃肉")       // eric吃吃肉// (2) 对象通过`__proto__`属性,指向原型对象
console.log(alex.__proto__)                     // { eat: [Function (anonymous)] }
console.log(alex.__proto__.constructor.name)    // Dog
console.log(alex.__proto__.constructor)         // [Function: Dog]// 看看能不能理解
console.log(alex.__proto__ === Dog.prototype)   //true
console.log(Dog.prototype)                      // { eat: [Function (anonymous)] }

alex.age = 100
console.log(alex.age)   // 100 先查找自己的空间,找不到,去原型中找
console.log(eric.age)   // 35// 猜一猜1
Dog.prototype.sleep =function (){console.log("prototype sleeping")
}alex.sleep()    // sleeping// 猜一猜2
let zhangSan = new Dog("张三", 35);
Dog.prototype = {fly:function (){console.log("flying...")}
}
// let zhangSan = new Dog("张三", 35);
// zhangSan.fly()
zhangSan.eat("辣条")  // 张三吃辣条
// 类的声明
function Person(name, age,height) {// 不是每个人都一样的需要放到这里this.name = namethis.age = age/* this.eat = function (){console.log(this.name + " 正在吃饭")}*/this.height = height
}// 如果所有的实例化对象都有eat方法和legs_num属性,并且eat方法的逻辑都是一样的,legs_num的值都是一样
// 那么我们就可以把这些共有的不改变的这些属性和方法都放到Person类的prototype空间中去
//类方法
Person.prototype.eat = function () {console.log(this.name + " is eating")
}
// 类属性
Person.prototype.legs_num = 2// 类的实例化一个对象
let p1 = new Person("yuan", 18,175)
// 实例化的属性调用
// console.log(p1.name)
let p2 = new Person("rain", 19,180)
// console.log(p2.name)
// p1.eat()
// p2.eat()
// console.log(p1.legs_num)
// console.log(p2.legs_num)// console.log(p1.height)
// console.log(p2.height)// 函数对象(类对象)调用prototype获取它的原型对象   通过函数找这个函数的原型对象就用prototype
console.log(Person.prototype)       // { eat: [Function (anonymous)], legs_num: 2 }
ptt = Person.prototype   // 给原型对象赋一个变量ptt  这个ptt就是一个原型对象
// 原型对象通过constructor获取该原型对象的函数对象(类对象)
console.log(ptt.constructor)       // [Function: Person]// `__proto__`
// 实例对象通过__proto__直接找到原型对象
console.log(p1.__proto__)                   // { eat: [Function (anonymous)], legs_num: 2 }
console.log(p1.__proto__=== Person.prototype)
console.log(p1.__proto__.constructor)       // [Function: Person]
console.log(p1.__proto__.constructor === p2.__proto__.constructor)

 


 

 

 

http://www.hskmm.com/?act=detail&tid=15850

相关文章:

  • 阻抗匹配技术:信号完整性与功率传输的基石​​
  • 萝卜视频小程序管理系统:多场景适配的短视频商业解决方案
  • 栈与队列专题
  • 读书笔记:为什么你的索引“罢工”了?六种常见原因解析
  • 平面网格材质
  • OSCP备考成功指南:9大实用学习技巧
  • 设备租赁系统:建材租赁行业的高效管理解决方案
  • NOI 2025 题解
  • 迈特海外短剧多语言版 SAAS 开源系统:助力短剧出海,开启全球盈利新赛道
  • 临时测试php文件
  • csv文件中的空行问题
  • 直播点播会议一体,EasyDSS如何用一个平台解决企业所有视频难题?
  • 在 C++ 中实现反射机制并不一定必须使用宏
  • 在CodeBolcks下wxSmith的C++编程教程——使用多个表单(多窗口程序)
  • Windows下Tesseract-OCR的安装与使用
  • 学习 React 前,你必须掌握的 10 个 JavaScript 核心概念
  • 二维下标极大数组(二维 map)
  • PySide6 之自定义弹出框
  • CF932E Team Work
  • HTTP3与HTTP2的性能对比
  • KubeSphere 社区版即将发布:开启云原生新篇章
  • 答题互动网页收藏
  • 芯脉:面向高速接口的SoC架构与完整性设计<3> - 教程
  • vscode插件开发,打包后不生效问题解决
  • streamlit构建dashboard
  • 力扣 338题 比特位计数
  • 企业服务管理是做什么的?-ManageEngine卓豪
  • 学习笔记_在Python中使用微信扫码功能(OpenCV WeChatQRCode)
  • 国标GB28181视频平台EasyCVR如何构建安防监控“中枢神经”?
  • vscode中element-plus组件无属性提示