写点什么

对象的访问机制及其他

作者:Jason199
  • 2022 年 6 月 26 日
  • 本文字数:2424 字

    阅读完需:约 8 分钟

对象的访问机制及其他

 对象访问机制

        当访问一个对象的成员时

        如果对象自己本身有, 直接返回结果给你, 停止查询

        如果对象自己本身没有, 会自动去 __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

      利用原型的属性

          利用对象访问机制

  1. instanceof

使用方法: 对象 instanceof 构造函数

4. Object.prototype.toString.call()

          使用方法: Object.prototype.toString.call(你要检测的数据类型);

了解对象

数据类型的一种

        以键值对的形式存储数据

        因为 __proto__ 和 原型链 可以访问自己没有的属性

for in 循环

        专门遍历对象

        遍历对象身上的所有属性

        遍历对象身上所有的 可枚举 的属性(包括原型链上的所有 可枚举 属性)

          是一种自定义的属性

对象自己的方法

        1. hasOwnProperty()

          查看是不是自己的属性

          使用方法: 对象.hasOwnProperty('你要检测的属性名')

        2. defineProperty() 数据劫持

        一种给对象添加属性的方法

          我可以给一个我设置的属性设置各种各样的行为状态

          使用方法: Object.defineProperty(给哪一个对象添加,  key, {

            添加的设置

          })

发布于: 刚刚阅读数: 3
用户头像

Jason199

关注

还未添加个人签名 2022.04.29 加入

一条努力上岸的咸鱼

评论

发布
暂无评论
对象的访问机制及其他_js_Jason199_InfoQ写作社区