一、什么是原型
函数的原型对象
在javascript中,我们创建(声明)一个函数a,那么浏览器就会在内存中创建一个对象b。这个对象b就是函数a的原型对象,这个原型对象b默认会有一个属性constructor指向这个函数a(意思就是说:constructor属性的值是函数a)
声明的函数会有一个默认的属性叫prototype,而且浏览器会创建一个对象,这个对象就是函数的原型对象,prototype属性指向这个对象
注意:原型对象默认只有属性constructor,其他都是从object继承而来,暂时不考虑
function person() {
}
console.log(person.prototype) //打印值是一个对象
使用构造函数创建对象
把一个函数作为一个构造函数(理论上任何函数都可以作为构造函数)使用new创建对象的时候,那么这个对象就会存在一个默认的不可见的属性,来指向构造函数的原型对象.这个不可见的属性一般用[[prototype]]来表示,只是这个属性没有办法直接访问到
function person() {
}
var p = new person();
console.log(person.prototype)
console.log(p)
使用new会创建一个对象,在这个对象有一个属性[[prototype]] ,[[prototype]]指向原型对象
<script>
function person() {
}
//可以使用person.prototype直接访问到原型对象
//给person函数的原型对象添加一个属性name,并且值是 张三
person.prototype.name = "张三"
person.prototype.age = "18"
var p1 = new person();
/*访问p1对象的属性name,虽然在p1对象中我们没有明确添加属性name,
但是p1的[[prototype]]属性指向的原型中有name属性,所以这个地方就可以访问到属性name的值*/
console.log(p1.name); //张三
var p2 = new person();
console.log(p2.name); //张三 都是从原型中找到的,所以都一样
console.log(p1.name === p2.name); //ture
//由于不能修改原型中的值,则这种情况就直接在p1中添加了一个新属性name,然后在p1中无法再访问到原型中的属性
p1.name = "李四";
console.log(p1.name);//李四
console.log(p2.name);//张三
</script>
二、与原型相关的几个属性和方法
1. prototype属性
prototype存在于构造函数中(其实任意函数中都有,只是不是构造函数的时候prototype我们不关注),他指向这个构造函数的原型对象
2. constructor属性
constructor属性存在于原型对象中,他指向了构造函数
function person() {
};
console.log(person.prototype.constructor === person);//true
var p1 = new person();
//使用instanceof操作符可以判断一个对象的类型
//typeof一般用来获取简单类型和函数,
//引用类型一般使用instanceof,因为引用类型用type,总是返回object
console.log(p1 instanceof person) //true
我们根据需要,可以person.prototype属性指定新的对象,来作为person的原型对象
但是这个时候有个问题,新的对象的constructor属性则不再指向person构造函数了
<script>
function person() {
}
person.prototype = {
name: "四月",
age: 20
}
var p1 = new person();
console.log(p1.name);//四月
console.log(p1 instanceof person)//true
console.log(person.prototype.constructor === person)//false
//如果constructor对你很重要,你应该在person.prototype中添加这样一行代码:
person.prototype = {
constructor: person //让constructor重新指向person函数
}
</script>
3. hasOwnProperty()方法
我们访问一个对象的属性的时候,这个属性有可能来自对象本身,也有可能来自这个对象的[[prototype]]属性指向的原型
hasOwnProperty()方法,可以判断一个属性是否来自对象本身
<script>
function person() {
}
person.prototype.name = "四月"
var p1 = new person();
p1.sex = "男"
//sex属性是直接在p1上添加的,所以是true
console.log(p1.hasOwnProperty("sex"));
//name是在原型上添加的,所以是false
console.log(p1.hasOwnProperty("name"));
//age属性不存在所以也是false
console.log(p1.hasOwnProperty("age"));
</script>
组合原型模型和构造函数模型创建对象
构造函数方法内部封装属性,原型对象内封装方法