当前位置:网站首页>对象的访问机制及其他

对象的访问机制及其他

2022-06-27 00:33:00 InfoQ

 
对象访问机制 
        当访问一个对象的成员时
        如果对象自己本身有, 直接返回结果给你, 停止查询
        如果对象自己本身没有, 会自动去 __proto__ 上访问
        有就返回结果, 停止查询。
利用 prototype 和 __proto__ 和 对象访问机制
        解决了构造函数的不合理
        属性直接写在 构造函数体内
        方法书写在 构造函数的 prototype 上
        使用构造函数创建一个 有属性 有方法 合理的 对象
        prototype作用: 就是为了书写一些方法给该构造函数的实例对象使用

function Person(name, age) {
 this.name = name;
 this.age = age;
 }

 Person.prototype.sayHi = function () { console.log('hello world') }

 // 使用 Person 创建一个对象
 let p1 = new Person('Jack', 18);
 console.log(p1);

 // 当我访问 p1.name 的时候, 自己就有
 console.log(p1.name);
 p1.sayHi();


 // 再次创建一个实例化对象
 let p2 = new Person('Rose', 20);
 p2.sayHi();
        
 
构造函数相关的 this 指向
        1. 构造函数体内的 this 指向
    和 new 关键字连用, this 指向当前实例
        2. 构造函数原型上的方法里面的 this 指向
    方法是依靠实例对象在调用
 面向对象选项卡
1. 抽象内容
        属性 btns、 tabs
      实现点击事件切换的方法
2. 在方法里面实现选项卡
        循环绑定事件以后, 发现 this 指向不再是 实例了
        拿不到 btns 和 tabs
        解决方案1:
          提前保存 this 为一个变量
        解决方案2:
          使用箭头函数
          因为箭头函数没有 this, 外部作用域的 this
      
 function Tabs(ele, options = {}) {
 // 拿到出现选项卡的范围
 this.ele = document.querySelector(ele)
 // 找到 btns
 this.btns = this.ele.querySelectorAll('ul > li')
 // 找到 tabs
 this.tabs = this.ele.querySelectorAll('ol > li')
 // 初始化一下 options
 this.options = options
 this.change()
 }

 Tabs.prototype.change = function () {
 // 操作的是当前实例的 btns 和 tabs
 // this 就是当前实例, 我们就要给 this.btns 的每一个添加点击事件
 this.btns.forEach((item, index) => {
 item.addEventListener(this.options.type || 'click', () => {
 this.btns.forEach((t, i) => {
 t.className = ''
 this.tabs[i].className = ''
 })
 // 给对应的添加类名
 item.className = 'active'
 this.tabs[index].className = 'active'
 })
 })
 }
 new Tabs('.box2', { type: 'mouseover' })
 new Tabs('.box3');

 let t1 = new Tabs('.box', { type: 'click' })
 console.log(t1);
定义:
        1. 每一个函数天生自带一个属性叫做 prototype, 是一个对象
        2. 每一个对象天生自带一个属性叫做 __proto__ 指向所属构造函数的 prototype
        3. 当一个对象, 没有准确的构造函数来实例化的时候, 我们都看作是内置构造函数 Object 的实例。
1. var arr = [] , Array 的实例
2. var obj = {} , Object 的实例
3. var p1 = new Person() , Person 的实例
4. var time = new Date() , Date 的实例
5. var fn = function () {} , Function 的实例
6. Person.prototype , Object 的实例
7. Array.prototype , Objec 的实例
结论:
        任何一个对象开始出发
        按照 __proto__ 开始向上查找
        最终都能找到 Object.prototype
        我们管这个使用 __proto__ 串联起来的对象链状结构, 叫做原型链
        原型链作用: 为了对象访问机制服务

  原型链

        从任何一个对象出发, 按照 __proto__ 串联起来的对象链状结构
        为对象访问机制而存在
  使用方法:数组 扩展一个方法
        在: Array.prototype 上
    如果我想给 函数 扩展一个方法
        在: Function.prototype 上
  
 原型
      函数天生自带 prototype 的属性
        存放一些方法, 供这个构造函数的所有实例使用
 
constructor 属性(构造器)
        只有函数天生自带的那个 prototype 上有
        表示我是哪一个构造函数所自带的 原型对象
        作用: 判断数据类型

  

判断数据类型

        1. typeof
          准确的判断基本数据类型
          缺点: 对于复杂数据类型并不准确
 
2. constructor
      利用原型的属性
          利用对象访问机制
  • instanceof
 使用方法: 对象 instanceof 构造函数
4. Object.prototype.toString.call()
          使用方法: Object.prototype.toString.call(你要检测的数据类型);

了解对象

 数据类型的一种
        以键值对的形式存储数据
        因为 __proto__ 和 原型链 可以访问自己没有的属性
for in 循环
        专门遍历对象
        遍历对象身上的所有属性
        遍历对象身上所有的 可枚举 的属性(包括原型链上的所有 可枚举 属性)
          是一种自定义的属性
对象自己的方法
      
  1. hasOwnProperty()
          查看是不是自己的属性
          使用方法: 对象.hasOwnProperty('你要检测的属性名')
        2. defineProperty() 数据劫持
        一种给对象添加属性的方法
          我可以给一个我设置的属性设置各种各样的行为状态
          使用方法: Object.defineProperty(给哪一个对象添加,  key, {
            添加的设置
          })
原网站

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://xie.infoq.cn/article/3550db3ce4086e0ccec323ae1