prototype原型
我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype。它默认指向一个Object空对象(即称为: 原型对象
)
prototype与constructor
原型对象中有一个属性constructor
, 它指向函数对象
console .log(Date .prototype.constructor===Date ) function Fun ( ) { } console .log(Fun.prototype.constructor===Fun)
显式原型与隐式原型
每个函数function都有一个prototype
,即显式原型(属性)
每个实例对象都有一个__proto__
,可称为隐式原型(属性)
原型就是一个对象,和其他对象没有任何区别,可以通过构造函数来获取原型对象。 和其他对象一样我们可以添加修改删除原型中的属性,也可以修改原型对象的引用。
构造函数. prototype
指向该构造函数的原型对象,我们可以通过__proto__
来访问该属性
对象的隐式原型的值为其对应构造函数的显式原型的值
function MyClass ( ) {} var mc = new MyClass();var mc2 = new MyClass();console .log(MyClass.prototype);console .log(mc.__proto__);console .log(mc2.__proto__);console .log(mc2.__proto__ == MyClass.prototype);
内存结构
function Fn ( ) { } var fn = new Fn() console .log(fn.__proto__)console .log(Fn.prototype===fn.__proto__) console .log(Fn.__proto__ == Function .prototype); Fn.prototype.test = function ( ) { console .log('test()' ) } fn.test()
内存结构图示:
总结:
原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中。
当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用
function MyClass ( ) {} MyClass.prototype.a = 123 ; MyClass.prototype.sayHello = function ( ) { console .log("hello" ); }; var mc = new MyClass();var mc2 = new MyClass();var mc3 = new MyClass();mc.a = "我是mc中的a" ; console .log(mc.a);console .log(mc2.a);mc3.sayHello();
因此以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了。
每一个对象都有原型,包括原型对象也有原型。特殊的是 Object的原型对象没有原型。
检查对象 in
使用in
检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
function MyClass ( ) {} MyClass.prototype.name = "我是原型中的名字" ; var mc = new MyClass();mc.age = 18 ; console .log("name" in mc);
hasOwnProperty()
可以使用对象的hasOwnProperty()
来检查对象自身中是否含有该属性,使用该方法只有当对象自身中含有属性时,才会返回true
function MyClass ( ) {} MyClass.prototype.name = "我是原型中的名字" ; var mc = new MyClass();mc.age = 18 ; console .log(mc.hasOwnProperty("age" ));console .log(mc.hasOwnProperty("name" ));
原型链
基于我们上边所说的,每个对象都有原型对象
原型对象也是对象,所以它也有原型,当我们使用一个对象的属性或方法时,会现在自身中寻找
自身中如果有,则直接使用
如果没有则去原型对象中寻找,如果原型对象中有,则使用
如果没有则去原型的原型中寻找,直到找到Object
对象的原型
Object对象的原型没有原型,如果在Object
原型中依然没有找到,则返回undefined
function MyClass ( ) {} MyClass.prototype.name = "我是原型中的名字" ; var mc = new MyClass();mc.age = 18 ; console .log(mc.__proto__.hasOwnProperty("hasOwnProperty" ));console .log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty" ));console .log(mc.__proto__.__proto__.__proto__);
上图可以看出,如果找不到可以到原型的原型去寻找,找到object以后,则不存在原型
所有函数都是Function的实例(包含Function)
console .log(Function .__proto__===Function .prototype)
console .log(Object .prototype.__proto__)
面试题
问打印结果分别是多少?
function A ( ) {} A.prototype.n = 1 var b = new A()A.prototype = { n: 2 , m: 3 } var c = new A()console .log(b.n, b.m, c.n, c.m)