01_原型
- 每一个函数 都有一个属于自己的原型
- 作用:
我们会在原型内部放一些公共的方法, 目的不是为了让构造函数去使用, 而是为了让实例化对象去使用
02_万物皆对象
/**
* JS 中, 万物都可以都可以称为对象
* 对象:
* 含义1: 一种数据格式 {key: value, key2: value2}
* 含义2: 某一类事务的实例 (某一类内容中的 真实个体)
*
*
* const arr = [1, 2, 3]
* const arr1 = [1, 2, 3, 4]
* const arr2 = [1, 2]
* 这个 arr1 就是 Array 这一类内容中的 某一个 真实个体, 数组也可以算作一个对象(Array 这一类事务中的一个个体)
*
* const fn = () => {console.log(1)}
* const fn2 = () => {console.log(2)}
* const fn3 = () => {console.log(3)}
* 函数也是一个对象(属于 Function 这一类事务中的一个个体)
*
* 如果一个数据 [] 那么他就是Array 这个对象中的某一个个体
* 如果一个数据 {} 那么他就是Object 这个对象中的某一个个体
* 如果一个数据 function(){} 那么他就是 Function 这个对象中的某一个个体
*/
const arr1 = [1, 2, 3]
const arr2 = new Array(4, 5, 6)
03_原型链
/**
* 原型链
*
* 查找对象的某一个属性:
* 先在对象内部开始查找, 找到直接使用, 然后停止查找
* 如果没有找到, 会找对象的 obj.__proto__, 如果找到直接使用, 然后停止查找
* 如果这里没找到, 会继续去对象的 __proto__ 查找, 找到直接使用, 然后停止查找
* 如果还是没找到, 会继续向上查找
* ...
* 直到找到顶层作用对象 Object.prototype, 找到就是用, 找不到 undefined
*/
function Person (name) {
this.name = name
}
Person.prototype.sayHi = function () {
console.log(100)
}
const p = new Person('QF001')
// console.log(p)
/**
* 问题1: p 的 __proto__ 指向谁?
* + p 是 Person 的实例化对象
* + __proto__ 指向自身构造函数的原型
* + p.__proto === Person.prototype
*
* 问题2: Person 的 __proto__ 指向谁?
* + Person 是构造函数, 本质上函数
* + 只要是一个函数, 他就是 Function 的实例
* + Person.__proto__ 指向了 他的构造函数的原型, 构造函数是 Function, 那么构造函数的 原型 Function.prototype
* + Person.__proto__ === Function.prototype
*
* 问题3: Person.prototype 的 __proto__ 指向谁?
* + Person.prototype 其实就是 构造函数 Person 的原型对象, 本质上就是对象
* + 只要是一个 对象, 他就是 Object 的实例
* + Person.prototype.__proto__ 指向了 他的构造函数的原型, 构造函数 Object, 那么构造函数的原型 Object.prototype
*
* 问题4: Function 的 __proto__ 指向谁?
* + Function 是构造函数, 本质上就是一个函数
* + 只要是一个函数, 他就是 Function 的实例
* + Function.__proto__ 指向了 他的构造函数的原型, 构造函数 Function, 那么 构造函数的原型 Function.prototype
* + Function.__proto__ === Function.prototype
*
* 问题5: Function.prototype 的 __proto__ 指向了谁?
* + Function.prototype 其实就是 构造函数 Function 的原型对象, 本质上是对象
* + 只要是一个对象, 他就是 Object 的实例
* + Function.prototype.__proto__ 指向了 他的构造函数的原型, 构造函数 Object, 那么构造函数的原型 Object.prototype
* + Function.prototype.__proto__ === Object.prototype
*
* 问题6: Object 的 __proto__ 指向了谁?
* + Object 是一个构造函数, 本质上还是一个函数
* + 只要是一个函数, 那么他的构造函数 就是 Function
* + Object.__proto__ 指向了他的构造函数的原型, 他的构造函数是 Function, 那么构造函数的原型 Function.prototype
* + Object.__proto__ === Function.prototype
*
* 问题7: Object.prototype 的 __proto__ 指向了谁?
* + Object.prototype 是构造函数 Object 的原型对象, 本质上就是一个对象
* + 但是重点: Object.prototype 是 JS 顶层的对象
* + Object.prototype.__proto__ === null
*/
04_判断数据类型
* 判断数据类型
* 1. typeof 判断基本数据类型
*
* 2. constructor 可以判断 当前数据的 构造函数 是谁
* 问题1: 能够判断引用数据类型
* 但是! 这个属性其实就是对象内的一个属性
* 我们可以拿到这个对象, 然后修改他的属性值
* 问题2: 不能判断 undefined 和 null
*
* 3. instanceof 可以判断 左边的构造函数是否等于右边的构造函数
* 语法: 检测的数据 instanceof 构造函数
* 问题: 不能判断 undefined 和 null
*
* 4. Object.prototype.toString.call(要判断的数据结构)
* Object 这个构造函数的 原型内部 有一个 toString 的方法
* 这个方法能够帮我们将数据结构转为字符串的形式 '[object 数据结构]'
*
* 我们在使用的时候 如果需要判断其他数据类型, 需要使用 .call这个方法改变内部 this 指向
*
* 这个方法任何数据类型都能准确判断(推荐使用)
*/