详解原型对象
本帖最后由 thinkyou 于 2022-1-12 23:23 编辑一.了解原型对象之前我们得先了解什么是工厂函数.构造函数用法
1.工厂函数
问:什么是工厂函数?
答:用来创建多个对象
function person(name,age){
let p = {}
p.name = name
p.age = age
return p
}
let p1 = person('张三',10)
let p2 = person('李四',20)
let p3 = person('王五',40)
我们用了这个函数可以批量创建对象,每次调用传递参数,把值添加进对象里面然后return返回这个对象.这就像一个工厂一样可以批量创建对象.
但是工厂函数需要创建对象,必须要有返回值,而且工厂函数适应用于小型项目
那么我们就需要用构造函数了,可以比工厂函数更简洁的代码而且不需要写return
2.构造函数
function Person(name, age) {
this.name = name
this.age = age
}
let p1 =new Person('张三', 10)
let p2 =new Person('李四', 20)
let p3 =new Person('王五', 40)
console.log(p1, p2, p3)
现在我们不需要返回值,并且代码更加简洁了,注意构造函数需要加new关键字调用,构造函数首字母大写便于区分普通函数和构造函数.
问:如果构造函数里面每一个对象都有一个相同的方法我们会怎么办
解析1:
function Person(name, age) {
this.name = name
this.age = age
this.dine = function () {
console.log('吃饭');
}
}
let p1 = new Person('张三', 10)
let p2 = new Person('李四', 20)
let p3 = new Person('王五', 40)
console.log(p1, p2, p3)
console.log(p2.dine == p1.dine);
我们添加一个方法,这样确实可以让他们每个对象都有一个dine的方法,但是我们比较了一个p2和p1的方法是否相等的时候结果却返回的是false
结果为false证明他们并不是相等的,为什么呢?因为我们每次新建一个对象的时候他都会在内存中开辟空间单独用来存储,所以造成了每一个对象里面都有dine方法,
并且都是不同的内存地址,我们比较p2和p1是否相等其实比较的是内存中的地址是否相等.那么我们这个方法就存在一个弊端:
存在过多的资源浪费明明我们创建了一个一模一样的方法你缺给我每个对象里面都保存了一个.
解析2:我们现在要解决资源浪费的问题,让所有对象都用这一个一模一样的方法
let obj = {
f1 : function () {
console.log('吃饭');
}
}
function Person(name, age) {
this.name = name
this.age = age
this.dine = obj.f1();
}
let p1 = new Person('张三', 10)
let p2 = new Person('李四', 20)
let p3 = new Person('王五', 40)
console.log(p1, p2, p3)
console.log(p2.dine == p1.dine);
我们控制台查看一下
现在我们的p2和p1dine相等了说明他们共用一个方法
但是我们在构造函数外声明了obj变量,这个变量是全局的,如果是多人开发的大型项目你不能保证你的同事没有声明过和你一样的变量,过多的声明全局变量很容易造成全局变量污染问题
所以我们的原型对象就有了
3.原型对象
同时 解决内存浪费问题 + 全局变量污染问题
了解原型对象:
其实创建函数的时候,系统会自动帮我们创建一个与之对应的对象,称之为原型对象。
接下来我们来使用它
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.dine = function () {
console.log('吃饭');
}
let p1 = new Person('张三', 10)
let p2 = new Person('李四', 20)
let p3 = new Person('王五', 40)
console.log(p1, p2, p3)
console.log(p2.dine == p1.dine);
prototype,属于构造函数,指向原型对象
每个函数都默认会有一个属性 prototype 指向了这个对象
所以我们用原型对象就可以轻松解决内存浪费问题 + 全局变量污染问题
问:prototype指向原型对象,那有没有原型对象指向构造函数或者是指向实例对象呢?
答:有,
原型对象.constructor → 自身对应的构造函数
构造函数.prototype →原型对象
实例对象.__proto__ →自身构造函数的原型对象
实例对象就是调用构造函数之后创建的对象
prototype:属于构造函数的
constructor属于原型对象的
__proto__属于实例对象的
看起来是不是感觉很复杂,不要慌大哥来教你,画个图就简简单单了
自己ps画的
但是这个属性__proto__是已经不用的很多浏览器也是不显示的但是我们可以了解他的底层原理,可以查看官方文档
__proto__扩展链接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
算了太晚了睡觉了不写了,其实到这里了说一下原型链是最好的,大家可以评论区讨论讨论
原型链其实就是 : 每一个实例对象都有自己的原型,而原型也是对象,也有自己的原型。以此类推,形成链式结构,称之为原型链。
给大家看看原型链的图吧
原型链图示:自己画的
我老师画的
大家感觉那个好呢哈哈
整理匆忙,关机睡觉了 学习了,适合打基础 感谢分享 这个有点复杂,当初都学晕了。 感谢大佬分享 不明觉厉 感谢大佬分享 感谢楼主分享,期待更新
页:
[1]