post11原型对象总结

原型对象总结

①我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype,这个是构造函数的显式原型;每次由var aaa=new 构造函数(){}创建新实例对象aaa,它都会有一个属性proto代表隐式原型;函数对象对应一个空Object对象,这个对象就是我们说的原型对象;

②注意:构造函数fun实例化的aaa,它总会有一个隐式原型对象(属性proto) 的总会指向构造函数fun的显示原型对象,即prototype属性指向的那个对象。从而prototype对象中出现的任何函数都可以由实例化的对象直接使用。并且在函数prototype属性指向的那个对象(显式原型对象)中,有一个constructor属性,这个属性又指向了函数对象。即函数对象fun.prototype.constructor===fun;

③普通函数中的prototype没有作用,但是如果是以构造函数的形式调用的时候,同一个构造函数创建的对象会有同一个隐藏的属性(这个属性就是对象的隐式原型,指向构造函数的显式原型),那就是一个公共的区域,所有同构造函数(类)的实例都可以访问到这个原型对象(访问方式:proto

④根据《悟透JavaScript》中,记载了new操作创建对象的三步骤:
1、创建一个新对象a=new 构造函数fun(){}
2、将对象a的隐式原型的值(proto的值,代表了实例对象指向的隐式原型对象)赋值为构造函数的显式原型(prototype属性的值,代表了所指向的显示原型的内存地址,通过原型继承,可以使用构造函数fun.prototype指向的显式原型对象的任何属性)
3、再将对象a设置为this参数,调用的构造函数,初始化成员设置。

⑤原型链的继承方法:创建一个子“类“,即后代的空构造函数;将空构造函数的prototype属性指向父类构造的对象:
function Person(name){this.name=name} //父类构造函数
function children(){}// 后代空构造函数
children.prototype=new Person(){}
//子类的prototype属性指向父类的一个对象
即继承的核心是:子类的函数对象–显式原型的值是父类的一个实例对象

⑥变量指向构造函数对象和变量指向实例对象的图解–}
eTzMmq.md.png

由上图:构造函数的显式原型这个属性的值会等于实例对象的隐式原型这个属性的值,即指向内存相同;fun.prototype的值===obj.proto
并且隐式原型和显示原型的指向又会是一个新的内存地址,若一直沿隐式原型链向上寻找(所有构造函数的对象,即函数对象,都有一个隐式原型proto属性指向一个空Object对象,会指向Object函数对象的显示原型指向的对象,直到找到Object的原型对象),总会寻找到Object的原型对象,就是原型链的尽头(因为这个Object的原型对象的隐式原型是null);它存在部分内置方法如toString();

⑦Function函数对象的特殊性质,这个函数对象有一个隐式原型属性:proto这个属性总会指向构造函数的显式原型对象,即命名function prototype;然后这个原型对象的显式原型对象(此对象无隐式原型)又会指向回Function,代表Function是由自身构造创建的。

⑧ 且由于实例对象的proto隐式原型属性指向的是构造函数的显示原型属性指向的对象,这个对象是一个空的Object对象;且空Object对象存在一个隐式原型属性指向了Object函数对象的prototype显示原型属性,这里注意Object函数对象还是Function的实例,但它们间的关系已经不影响隐式原型链,因为空Object的原型对象就是原型链的尽头。

⑨instanceof方法,判断A instanceof B可以做到判断实例对象A是否是函数对象B的实例,判断的依据是:函数B的显示原型对象是否在A的原型链上面
返回true和false;
例:function Foo(){}
var f1=new Foo();
console.log(f1 instanceof Object)//true 因为Object的prototype在fn的隐式原型链
(由下图:Foo构造函数和Object都有一个显示原型属性,且都在实例对象f1的原型链上)
eTzQ00.png

例如:一个构造函数 function MyClass(){ }
var mc=new MyClass();
var mc2=new MyClass();
console.log(mc2.proto==MyClass.prototype);//true

⑩我们可以将对象中共有的区域,统一的设置到原型对象中
例如像MyClass的原型添加属性a
MyClass.prototype.a=123;
即是将所有MyClass构造的对象,都存在一个原型属性a 属性值123;
也可以在原型添加方法,效果一样,若本身找不到,则在原型找方法;
原型即一个公共区域,可以将共有的方法保存到:构造函数.原型.方法=function(){}

例如:
    Person.prototype.sayName=function(){alert("Hello");};
    这样做 所有指向构造原型内存地址的对象(所有由构造函数构造的对象)
    都存在一个原型方法来提供重复使用,而不会影响到全局作用域,就可以使每个对象都具有这些属性和方法;作用是:若当前对象自身找不到指定的属性的时候,会在原型对象上面去找 是否原型有这个属性,若找到的话,就会使用原型对象上的属性和对应属性值。

⑩①检查对象/原型对象中是否有对应属性:

in检查:                           
    console.log("name" in  对象名)
只检查对象自身是否有对应的属性: 
    console.log(对象名.hasOwnProperty("name"));//假设自身有name属性;若检查 :console.log(对象名.__proto__.hasOwnProperty("name"));则返false,因name只是自身属性;
只检查原型对象是否有对应的属性:  
    console.log(对象名.isOwnProperty("name"));

⑩②原型对象总结:
若我们使用一个对象的属性或方法的时候,会在自身中寻找,自身中如果有则直接使用;
如果没有则去原型对象中找,如果原型对象中存在,则直接使用,不然则找原型对象的原型对象,直到找到Object对象的原型
若是在Object对象的原型是最后一级,若还是没有找到,则返回undefined