原型 (又名: 原型空间 原型对象)
什么是原型?
- => 每一个函数 天生拥有一个属性 prototype, 他的属性值是一个 对象;
- => 我们通常把这个对象叫做 这个函数的原型(空间|对象)
- => 原型这个对象中 有一个属性 叫做 constructor, 这个属性表示的是: 当前这个 原型 是那个 函数的原型
- 如何使用原型中的属性?
- => 每一个对象 天生拥有一个属性 proto (前后都是两个下划线)
- => 这个属性指向 自己构造函数 的原型
function Person() { }
// 向 Person 函数的原型(对象)上 添加一个属性 age, 值为 18
Person.prototype.age = 18
Person.prototype.name = '千锋'
Person.prototype.fn = function () {
console.log('我是添加在 Person 函数的原型对象上 的一个函数')
}
Person.prototype.abc = '我是添加到 Person 函数的原型上的一个字符串, 你可以通过 Person 创建出来的对象上的 __proto__ 查看'
let p1 = new Person()
/**
* 使用 new 结合 Person() 这个过程叫做 构造函数的实例化, 最终会得到一个对象
* 在我们当前案例中, 是将这个对象放在 变量 p1 里边
*
* 所以有些开发管这个 p1 叫做 实例化对象, 实例对象, 本质上依然是一个对象
*/
// console.log(p1.__proto__)
console.log(p1.__proto__ === Person.prototype)
/**
* __proto__ 属性指向自己构造函数的原型
*
* 因为 p1 这个对象的构造函数 是 Person
*
* 那么也就是说, p1.__proto__ 实际指向的就是 Person 这个函数的原型
*/
原型的作用
把构造函数中 公共方法(函数) 提取出来, 放在原型中。为什么要这样做?构造函数的原型上的方法或者属性, 在每一个实例化对象中都能正常访问。
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.fn = function () {
console.log('我是添加在 Person 函数的原型对象上 的一个函数')
}
let p1 = new Person('QF001', 18)
console.log(p1.__proto__)
let p2 = new Person('QF002', 28)
console.log(p2.__proto__)
/**
* 对象的访问规则
* 访问对象的某一个属性时, 会先在对象本身去查找, 找到就直接使用, 如果没有找到
*
* 那么会去 对象的 __proto__ 中查找, 找到就使用, 如果没有找到
*
* 那么会去这个对象(原型) 的 __proto__ 查找
*
* 直到查找到 JS 的顶层对象 Object.prototype, 如果还没找到 就不在向上查找
*/
console.log(p1)
console.log(p1.fn)
p1.fn()
console.log(p1.abc) // undefined
扩展内置构造函数
- new Object()
- new Array()
- new RegExp()
- new String()
js 内的数据结构类
- 在 JS 中, 任何一个数组, 他的构造函数都是 Array
- 在 JS 中, 任何一个对象, 他的构造函数都是 Object
/**
* 需求: 在 数组上扩展一个方法, 要求, 所有数组都能使用
*/
// Array.prototype.abc = function () {
// console.log('我是扩展在 Array 构造函数的原型上的一个函数')
// }
// let arr = [1, 2, 3, 4, 5]
// // console.log(arr.__proto__)
// arr.abc()
/**
* 需求: 在 数组上扩展一个方法 getMax, 作用是求出数组中的最大值, 并且要求所有数组都能使用
*/
let arr = [1, 2, 3, 4, 5]
let arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Array.prototype.getMax = function () {
// console.log(this)
// 函数的 this 指向是 他的调用者, 所以我们可以通过 this, 拿到数组中的值
let max = this[0]
for (let i = 1; i < this.length; i++) {
if (this[i] > max) {
max = this[i]
}
}
console.log(max)
}
arr.getMax()
arr2.getMax()