一.原型(prototype)有什么用?为什么出现?
function student(name,age){ this.name = name; this.age = age; this.study = function(){ console.log("学习~") } } var stu = new student(); var stu1 = new student();//这样有多少个学生对象,就要多开辟多少个study函数的内存,坐着一样的事情
所以为了节省内存,给他定义一个共享方法,开辟一个空间,所有学生都可以用
function student(name,age){ this.name = name; this.age = age; } //给原型加上属性study,开辟一处空间,可以给所有学生类使用这个方法 student.prototype.study = function(){ console.log("学习~") } var stu1 = new student(); var stu2 = new student();
总结:原型可以节省内存
二、函数,函数实例、函数原型
1.函数:以上面student()来说,它就是函数。
所有函数都有一个特别的属性:
-
prototype
: 显式原型属性(函数独有)
2.函数实例:上面的stu, stu1, stu2这些通过new出来的对象,称为函数实例,或实例对象,函数实例对象等等~
-
所有实例对象都有一个特别的属性:
-
__proto__
: 隐式原型属性
//这里要说明一点,所有函数都有prototype属性,所有实例化对象都有__proto__属性。
//通常情况下,定义函数 function student(){ } //JS默认处理为 var student = new Function() //所以所有函数都是实例化对象,也有__proto__属性 //并且Function本身也是实例化对象,JS默认 var Function = new Function()
结合1,2两点总结:
//所有函数都有prototype和__proto__属性; //所有通过函数实例化的对象,如var stu = new student(),有__proto__属性,但是没有prototype属性,因为prototype属性是函数特有
3、函数原型:
(1)student.prototype称为student函数的原型,它也是一个对象,你可以理解prototype是函数student的一个属性,而student.prototype是一个对象,也称为student原型
(2)C语言中有函数原型是函数声明的概念 :函数原型也叫函数声明,还叫引用说明。其目的是实现先调用函数,后定义函数。
//我认为C语言的函数原型就是函数声明,很贴切。我认为JS也可以这么理解,因为JS可以通过函数原型给函数添加属性,以达到扩展原函数的目的。 function student(name,age){ this.name = name; this.age = age; } student.prototype.study = function(){ console.log("学习~") } //这样岂不是很形象,通过原型,也就是函数重新声明,重新构造一个student函数,让它具有更强大的功能
结合2,3两点谈谈prototype(原型)与__proto__(隐式原型):
其实这两者好像儿子和父亲的关系:student通过prototype重新给自己增加功能,而实例化对象stu(student函数 new出来的对象),通过__proto__指向student.prototype,以达到stu调用student所有属性的目的。
画图效果:
以上总结:父亲通过prototype指向父亲原型,父亲原型通过constructor指向父亲,儿子通过__proto__指向父亲原型。
又可以进一步总结:函数指向对象用prototype指针,对象指向函数用constructor指针,对象指向对象用__proto__指针。
又可以总结为:函数指向原型对象用prototype指针,原型对象指向函数用constructor指针,实例化对象指向原型对象用__proto__指针
三、原型链
1. 原型链(隐式原型链,通过__proto__发挥作用) * 访问一个对象的属性时, * 先在自身属性中查找,找到返回 * 如果没有, 再沿着__proto__这条链向上查找, 找到返回 * 如果最终没找到, 返回undefined * 别名: 隐式原型链 明白了上面的原型的话,原型链就简单了,说白了就是多个原型串在一起,某个实例化对象通过__proto__找它的祖先,看看祖先是否有它需要的属性,有的话就使用,没有的话就undefined。 下面是简易版的原型链:
翻译为:(1)student.prototype === stu.__proto__; student.prototype.construtor === student;student.prototype === student.prototype (2)student.prototype.__proto__===Object.prototype; (3)Object.prototype.constructor===Object; Object.prototype===Object.prototype;Object.prototype.__proto__===null 结合Function(所有函数的祖宗),Object函数,Student自定义函数的原型链:
图像本来很清晰的,编辑的时候。一上传就压缩的模糊了。