对js原型及构造函数的相关理解
一、js中的原型
创建(声明)一个函数,浏览器在内存中会创建一个对象。
每个函数都默认会有一个属性prototype指向了这个对象,就是说prototype的属性的值就是这个对象。
此对象就是该函数的原型对象,简称函数的原型。
这个原型也默认有一个属性constructor指向了这个函数,就是说constructor属性的值是该函数。
原型对象主要作用是继承
二、构造函数
当用new创建对象时,这个对象会存在一个默认不可见的属性去指向构造函数的原型对象;
这个属性用prototype表示,并且没办法直接访问到。
function Person () {} // 构造函数
Person.prototype.name = "zhangsan"; // 添加属性
Person.prototype.callName = function () { // 添加方法
console.log(this.name);
}
var p1 = new Person(); // p1虽然使用Person的构造函数,但是已经和他没关系了
console.log(p1.name); --> zhangsan // 能取到值
p1.callName() --> zhangsan
p1.name = "lisi"; // 可以修改,但是不能修改到prototype,也再也取不到之前的值了
console.log(p1.name); --> lisi
p1.callName() --> lisi
console.log(Person.name); --> zhangsan
Person.callName() --> zhangsan
var p2 = new Person(); // p1 p2 两个没关系,互不干扰;他们都是Person的实例,都有constructor属性,指向的都是Person
三、相关的属性
1)prototype
存在于构造函数(其他函数中也存在,只是不关注)指向构造函数的原型对象。
2)constructor
存在原型对象中,指向的是这个构造函数。
Person.prototype.constructor === Person --> true
如果给给原型增加对象字面量,
Person.prototype = {
name: "zhangsan",
age: 20
}
那么constructor将不再指向该构造函数。
Person.prototype.constructor === Person --> false
如果你非要constructor指向你的构造函数呢,那么应该在原型中增加constructor的指向,如
Person.prototype = {
constructor : Person //让constructor重新指向Person函数
}
3)_proto_
之前说到prototype是不可访问的,但是在个别浏览器(Chrome和Firefox,IE不支持)中是提供访问方式的;
但是尽量不要用,因为会改变这个对象的继承原型链。
4)hasOwnProperty()
判断属性是否是自己添加的返回true,如果是原型中或者没有这个属性那么返回false
5)in
判断属性是否存在这个对象中,先在该对象中找,再去原型找,找不到才返回false