持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情
对象访问机制
当访问一个对象的成员时
如果对象自己本身有, 直接返回结果给你, 停止查询
如果对象自己本身没有, 会自动去 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 指向
方法是依靠实例对象在调用
面向对象选项卡
- 抽象内容
属性 btns、 tabs
实现点击事件切换的方法
- 在方法里面实现选项卡
循环绑定事件以后, 发现 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 构造函数
- Object.prototype.toString.call()
使用方法: Object.prototype.toString.call(你要检测的数据类型);
了解对象
数据类型的一种
以键值对的形式存储数据
因为 proto 和 原型链 可以访问自己没有的属性
for in 循环
专门遍历对象
遍历对象身上的所有属性
遍历对象身上所有的 可枚举 的属性(包括原型链上的所有 可枚举 属性)
是一种自定义的属性
对象自己的方法
1. hasOwnProperty()
查看是不是自己的属性
使用方法: 对象.hasOwnProperty('你要检测的属性名')
2. defineProperty() 数据劫持
一种给对象添加属性的方法
我可以给一个我设置的属性设置各种各样的行为状态
使用方法: Object.defineProperty(给哪一个对象添加, key, {
添加的设置
})