原型就要说构造函数,什么是构造函数
构造函数和普通函数区别
//1.声明区别上的区别
//--普通函数---
function test(){
//普通函数遵循小驼峰命名写法
}
//--构造函数---
function Person(){
//构造函数命名是大驼峰首字母大写
//但是大驼峰写法不是系统规定的,是人传人最后规定下的,人为定义的
}
//2.使用上的区别
//--普通函数---
//普通函数直接()执行就可以
test()
//--构造函数---
//构造函数如果也直接调用则跟普通函数并未区别
Person()
// 但是通过 new 创建出的函数则就完全不一样,一旦通过new去创建函数,就会隐式生成一个对象并返回
var person = new Person()
var person1 = new Person()
person1.age = 14;
// 每次创建都是一个全新的对象,所以不存在相互映射的关系
console.log(person.age) // => undefined
//等于在Person内,隐式的生成了一个this对象,this就是实例person
var person = new Person(){
// var this = {} 隐式
this.name = '小白'
// return this 隐式
}
person.name // => 小白
//并且手动修改 return 的返回对象 return {} ,那么person = {}
//但手动 return 返回的必须是对象,否则系统将不认默认返回隐式对象
原型就是构建函数,而通过构建函数创建出的叫做实例
function Person(name, age){
this.name = name;
this.age = age
}
var person = new Person('小白',16)
var person1 = new Person('小江',14)
//构造函数 Person 是 perosn 实例的原型
但是这么生成的实例存在缺陷,那就是如果我想 person 和 person1 之间存在关系,比如说我希望person.family 和 person1.family 指向的同一个,毕竟是一个构造函数构建出来的,虽然出厂以后各自过自己的互不干扰,但是毕竟还是一个构建函数出来的,所以这个时候就需要 prototype ,其实每个构造函数被创建的时候,自身都有一个 prototype 属性
Person.prototype.family = '老李家的'
function Person(name, age){
this.name = name;
this.age = age
}
var person = new Person('小白',16)
var person1 = new Person('小江',14)
console.log(person.faily + person.name) // => 老李家的小白
//当 family 被修改时, person.family 和 person1.family 都会被修改
Person.prototype.family = '老张家的'
console.log(person1.faily + person1.name) // => 老张家的小江
prototype 刚被创建出来时是一个 { }
原型链就是通过 prototype 将多个构造函数链接起来,使实例对象能够实用非自身的属性和方法,通过 prototype 链向上查找不属于本身的属性和方法
function FirstName(){
this.firstName = '李'
}
FirstName.prototype = new Family()
function Family(){
this.age = '16'
}
Person.prototype = new FirstName()
function Person(){
this.name = '小白'
}
var person = new Person()
person.age // => 16
总结一下 prototype 、__proto__的关系
prototype 是构建函数/函数创建时候的一个属性,指向一个对象,对象内的属性和方法被该实例对象所共享,初始 prototype 为空对象
__proto__ 是实例可以通过该属性查看该构造函数的原型