今天要分享的是js中的原型,那么先要知道面向对象的概念。
面向对象
1. 创建对象
//字面量创建:
var obj1={name:"admin",age:18 };
//构造函数创建:
var obj2=new Object();
2.自定义构造函数
function createPerson(name){
this.name=name;
this.age=age;
}
var p=new createPerson("admin");
3.new关键字的执行原理
- 自动创建一个对象
- 改变了函数内部的this指向,指向了第一步创建的新对象
- 执行函数内部的代码,并将第一步创建的对象的__ proto __与函数的prototype做了关联。
- 检查当前函数是否主动返回对象,若没有,则返回第一步创建的新对象。
ps:如果在构建函数的时候,使用this找将来的对象,那么这个函数绝对不要正常执行,否则会造成全局污染(因为this指向了window)
ps:通过new出来的对象,叫做实例
4.构造函数创建对象存在的问题
当一个构造函数在多次new的时候,若在函数内部通过this设定了方法,那么多次new以后,会在内存中产生多个相同的功能,产生多个相同的方法,为了节省资源,需修正该问题。
原型
1.原型
1.每个函数都有prototype属性,比如我们上述所说的createPerson,同时,createPerson.prototype是一个对象,叫做原型对象
2.由于createPerson.prototype是一个对象,所以可以给他添加方法和属性,但是这些方法和属性不是给函数本身使用的,即通过函数自身找不到这些方法和属性。
3.那么如何找到这些方法的属性呢,必须通过实例身上的__ proto __找到, __ proto __是实例的属性,我们上述所说的 p. __ proto __ 也是一个对象,叫做隐式原型,是为了标记当前实例的来源函数的原型。
即 p. __ proto __==createPerson.prototype
;
2.原型链
- 一般情况下,一个对象类型的数据,必然会有一个隐式原型(__ proto __),这个隐式原型作为当前对象的父级存在。
-
当前对象的属性或方法的读写规则:
- 读:如果一个对象不具有某个属性或者方法,会顺着他的隐式原型(p.__ proto __ )找父级(createPerson.prototype),找到了可以直接使用该属性或者方法,找不到,继续顺着隐式原型向上找父级,直到找到Object,如果还是没有找到,则抛出null
- 写:直接改写自身,如:createPerson.prototype.show=function(){}
总结一下:
1.prototype:专属于函数的属性,类型为对象,叫做原型对象
作用是为了给将来自身所在的构造函数被new出来
2.__ proto __:专属于对象的属性,类型为对象,叫做隐式原型。
作用: 找父级
特性:
当某个对象自身不具有某个属性和方法的时候,会自动找父级。
当这个对象是被new出来的实例,这个对象的父级(__ proto __)就是当前这个构造函数的prototype。
意味着通过构造函数找到prototype,添加的属性和方法在将来new出来的实例上都可以找到。在prototype这个对象上还有一个属性叫做constructor,他指向该构造函数即:
createPerson.prototype.constructor==createPerson;
p.__ proto __.constructor==createPerson ;
-
构造函数的原型的方法内的this,与构造函数内的this,都指向将来的实例。
3.检测方法
- 1.isPrototypeOf():用于检测两个对象之间是否存在原型关系
Fn.prototype.isPrototypeOf(f); //查看Fn的prototype属性是否是f的原型
- 2.instanceOf运算符:用于检测某实例是否来自于某构造函数
f instanceOf Fn //查看对象f是否是构造函数Fn的实例