函数的prototype解析

1、函数的prototype属性

   (1) 每个函数都有一个prototype属性,它默认指向一个Object空对象。(称为原型对象)

    例1:console.log(typeof Date.prototype,Date.prototype);

    运行结果显示:


    例2:定义一个新的函数:function Fun(){  }

    console.log(Fun.prototype);

    运行结果显示为:

                    

    可以看出,例1,2都指向了默认的Object空对象。那么什么是空对象?就是没有后定义(fun())自己的属性。

    (2)原型对象中有一个属性constructor,它指向函数对象。

    可以验证一下:

    console.log(Date.prototype.constructor === Date);   //结果为true

    console.log(Fun.prototype.constructor === Fun);//结果为true

    示意图如下:




    当我们给原型对象添加属性(一般为方法),目的是让实例对象去访问。

    例如:Fun.prototype.test = function(){console.log("test()");}

               var fun = new Fun();//创建实例fun

fun.test();//输出test()

    2、给原型对象添加属性(一般为方法)

    作用:函数中的所有实例对象,自动拥有原型中的属性或方法。

    3、显式原型与隐式原型

    (1)每个函数function都有一个prototype,即显示原型。(默认指向一个空的Object对象)
        可参考上例2。
        其中,prototype属性是在函数创建之后自动添加的。

    (2)每个实例对象都有一个__proto__,可称为隐式原型。

         可以通过 console.log(fun.__proto__); 来验证实例fun的__proto__属性。

        其中,__proto__属性是在实例创建完之后自动添加的。

    (3)对象的隐式原型的指对应其构造函数显式原型的值。

         可以通过 console.log(fun.__proto__ === Fun.prototype);//结果为true  来验证。


    通过上图可以看出实例对象调用原型方法的内部过程。

    4、原型链

    当访问对象的属性时,先在自身属性中查找,找到就返回;如果没有,则沿着__proto__这条链向上寻找,找到则返回。如果最后没有找到,则返回undefined。结构图如下:


    首先在在fun中查找test1,可以在fun实例对象中找到test1方法,并返回结果test1;接下来找test2方法,先在自身中查找,不能找到,则查看__proto__属性,查找隐式原型对象,找到则返回test2;然后是查找toString方法,自身和根据隐式原型属性的隐式原型对象中都没有,然后根据Object的隐式原型属性找隐式原型对象则可以找到。最后找test3,可以知道自身、自身的隐式原型对象以及Object的隐式原型对象中都找不到,则返回undefined。可以知道原型链是按照隐式原型寻找的。原型链的本质就是隐式原型链。

    补充:(1)函数的显示原型指向的对象默认是Object的空对象。(但Object不满足,因为object.__proto__=null)

    例:console.log(Fun.prototype instanceof Object);//结果为true
   console.log(Object.prototype instanceof Object);//结果为false

   console.log(Function.prototype instanceof Object);//结果为true

    (2)所有函数都是Function的实例(包含Function本身)

    例:console.log(Function.__proto__ === Function.prototype);//结果为true

    (3)Object的原型对象是原型链的尽头

    例:console.log(Object.prototype.__proto__);//结果为null

    5、原型链的属性

       (1)读取对象属性值时,会自动到原型链中查找。

       (2)设置对象属性值时,不会查找原型链,如果当前对象中没有此属性,则直接添加并且设置其值。

        例:         Fun.prototype.a = 'aaa';
var fun1 = new Fun();
console.log(fun1.a);//结果为aaa
var fun2 = new Fun();
fun2.a = 'bbb';

console.log(fun1.a,fun2.a);//结果为aaa bbb

        (3)方法一般定义在原型中,属性一般通过构造函数定义在对象本身上。

        例:        function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.setName = function(name){
this.name = name;
};
var p1 = new Person("Tom",12);
p1.setName("Bob");
console.log(p1);

var p2 = new Person("Helen",18);
p1.setName("Tina");
console.log(p2);

console.log(p1.__proto__ === p2.__proto__);//结果为true

        结果显示为:

                                            





    

             

    


    


  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值