封装
构造函数存在问题
js可以通过构造函数进行封装,但存在浪费内存问题
每创建新的对象引用数据类型就开辟新的空间
原型
构造函数通过原型分配函数是所有对象所共享的
每一个构造函数都有一个prototype属性,指向另一个对象,也称为原型对象
构造函数和原型对象的this都指向实例化对象
js封装后可以面向对象编程
例如写一个数组扩展函数
const arr=[1,2,3]
Array.prototype.max=function(){return Math.max(...this)//展开运算符
} //this指向arr,无需添加参数arr.max()//3
constructor属性
每个原型对象里都有constructor属性
该属性指向原型对象的构造函数,
构造函数.prototype.constructor === 构造函数 //返回 true
添加公共属性时:
1.如果是追加
function fn(){}fn.proptotype.sing=function(){
} //属于追加操作console.log(fn.prototype)
不会丢失constructor(知道爸爸是谁)
2.如果直接赋值
function fn(){}fn.proptotype={//proptotype属于对象sing: function(){},dance: function(){}
}
不难理解,constructor会丢失
解决方案:(也是constructor的应用)
function fn(){}fn.proptotype={ //重新指回构造函数constructor: fn,sing: function(){},dance: function(){}
}
constructor由于new出新的实例对象
__proto__
所有对象都有__proto__,指向原型prototype,形成原型链,里面有constructor
实例对象.__proto__.constructor===构造函数
继承
原型继承(存在隐患)
const Person = {eyes: 2,head: 1}function Woman() {}function Man() {}Woman.prototype = PersonMan.prototype = PersonWoman.prototype.constructor = Woman //防止丢失Woman.prototype.constructor = Man const red = new Woman()const blue = new Man()console.log(red)
上图可知,Person公共部分在__proto__中,指向对象原型
这里有个问题
Woman.prototype = PersonMan.prototype = Person
prototype指向了同一个person对象,地址相同,如果给Women添加公共属性,会添加到person中,就会成为使用对象的公共属性
解决:
不要使用同一对象,但不同对象里包含相同属性和方法(结构相同)
需要构造函数
function Person(){this.eyes = 2this.head = 1}function Woman() {}function Man() {}Woman.prototype = new Person()Man.prototype = new Person()Woman.prototype.constructor = WomanWoman.prototype.constructor = Man const red = new Woman()const blue = new Man()
原型链
__proto__: 基于原型对象的继承使得不同构造函数的原型对象关联在一起,形成一种链状结构(对象一定具有__proto__)
实例对象.__proto__ =>构造函数.prototype.__proto__=>Object.prototype.__proto__=>null
原型链是一种查找规则
对象原型的意义在于为对象成员查找机制提供一条路线,从自身开始查找对象原型的原型
例如:Array.prototypr.map() (没有原型链就不能使用此公共方法)
instanceof运算符
检测构造函数的prototype属性是否在某个实例对象的原型链上