重学前端:原型和原型链梳理
基础知识重新学习,若有不对欢迎指正,感恩。
什么是构造函数?
在js里,使用__new__关键词调用的函数就是构造函数。
let p1 = new Person('zs',6,'男','basketball')
为什么要用构造函数?
达到封装目地,抽象出函数功能。
//没有封装
var p1 = { name: 'zs', age: 6, gender: '男', hobby: 'basketball' };
var p2 = { name: 'ls', age: 6, gender: '女', hobby: 'dancing' };
//通过构造函数模式封装
function Person(name,age,gender,hobby){
this.name = name
this.age = age
this.gender = gender
this.hobby = hobby
this.getName = function(){
return this.name
}
}
let p1 = new Person('zs',6,'男','basketball')
p1.getName(); // zs
let p2 = new Person('ls',6,'女','dancing')
什么是原型对象(prototype)?
函数(包括构造函数)天生自带一个prototype属性,他是一个指针,指向的是一个对象。
let p1 = new Array()
p1.prototype //返回的是一个对象
为什么需要原型对象(pototype)?
因为js没有直接通过面向对象继承父类的语法,所以设计了原型这个模式来实现对象的继承。
function Person(name,age,gender,hobby){
this.name = name
this.age = age
this.gender = gender
this.hobby = hobby
this.getName = function(){
return this.name
}
}
let p1 = new Person('zs',6,'男','basketball')
p1.getName = function(){return this.age}
p1.getName() //6
let p2 = new Person('ls',6,'女','dancing')
p2.getName() //ls
上述代码每个Person实例对象都有一份__getName__方法的拷贝,在程序抽象上是不划算的,所以引入的prototype【原型对象】,把原型对象当作一个公共的区域,所有同一个类的实例对象都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中。方便后期,以提升效率。
function Person(name,age,gender,hobby){
this.name = name
this.age = age
this.gender = gender
this.hobby = hobby
}
Person.prototype.getName = function(){
return this.name
}
let p1 = new Person('zs',6,'男','basketball')
p1.getName() //zs
let p2 = new Person('ls',6,'女','dancing')
p2.getName() //ls
//修改person的getName方法
Person.prototype.getName = function(){
return this.name+this.age
}
p1.getName() //zs6
什么是原型链?
对于一个构造函数A,继承自一个构造函数B,现在A的实例a对象想调用B构造函数定义的方法怎么办呢?
所以js内置对于所有对象内置了一个属性 __ proto __ ,这个属性的指针指向__构造函数的prototype__,而构造函数也是对象,也有__ proto __ 属性指向构造函数的构造函数(一般是顶层是Object),所以规定顶层的Object的prototype是null,所以当一个实例对象要使用某一个方法时,如果本身找不到,会从自身的构造函数的prototype对象里面找,一层层的,直到找到Object.prototype对象里面,如果还没有就是null。上述过程就是原型链。

令人疑惑(需要注意)的原型链
- Function.__ proto __ === Function.prototype //因为Function这个函数是由自身构造的。
- Function.prototype.__ proto __ === Object.prototype // Function.prototype这个对象是有Object这个函数对象构造出来的
- Object.__ proto __ === Function.prototype //因为在js中 内置的函数对象Object(函数是一等公民)所以是函数构造的
原型链的总结
对于一个构造函数function Foo()
原型链是
Foo>Function.prototype>Object.prototype>null
对于这个构造函数的实例foo
原型链是
foo>Foo.prototype>Object.prototype>null