zoukankan      html  css  js  c++  java
  • Javascript高级程序设计--读书笔记之理解原型对象

    先上一段代码和关系图

         function Person(){}
         Person.prototype.name = "Nic"
         Person.prototype.age = 22
         Person.prototype.job= "Software Engineer"
         Person.prototype.sayName = function(){
             alert(this.name)
         }
        var person1 = new Person();
        var person2 = new  Person();
         alert(person1.sayName == person2.sayName)     //true

                                                                                                                               图1

    开始进入正题

           无论什么时候,只要创建了一个新的函数,就会根据特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性是一个指向protopype属性所在函数的指针,拿上面的代码来说,Person.prototype.constructor指向Person。通过这个构造函数我们还可以继续为原型对象添加其他属性和方法。

           创建自定义的构造函数之后其原型对象只会默认取得constructor属性;至于其他方法都是从Object继承而来的。当调用一个构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型属性ES5中管这个指针叫[[Prototype]]。虽然在脚本中没有标准的方式访问[[Prototype]],但是在Firefox、Safari、Chrome在每个对象上都支持一个属性_proto_;这个连接存在于实例与构造函数的原型对象之间,而不是存在与实例与构造函数之间。图1 就展示了各个对象之间的关系

    再来一段代码

    function Person(){
      
    }
    Person.prototype.name = "Nic"
    Person.prototype.age= 29
    
    var person1 = new Person()
    var person2 = new Person()
    person1.name = "Greg"
    alert(person1.name)   //"Greg" 来自实例
    alert(person1.name)   //"Nic"  来自原型
    
    delete person1.name
    alert(person1.name)   //"Nic" 来自原型

      上面这段代码说明了,可以通过对象实例访问到原型里的值,但是不能通过对象实例重写原型的值。如果我们添加了一个属性,而该属性和原型对象的属性重名,我们就在该实例中创建该属性,并且屏蔽原型中的那个属性,可以通过delete删除实例的的属性,从而让我们重新访问原型的属性

    我们再再来一段代码

    function Person(){
    
    }
    var friend = new Person()
    Person.prototype.sayHi = function(){
      alert("Hi")
    }
    friend.sayHi()   //"Hi"  (没有问题!)
    
    Person.prototype = {
      constructor:Person,
      name:"Nic",
      sayHi:function(){
         alert(this.name)
      }
    }
    friend.sayHi()   //"Hi" (还是"Hi")

    上述代码说明两个问题

    1.实例与原型之间的关系是松散的调用firend.sayHi()会先在实例中搜索,没有找到就会去原型中搜索,因为实例和原型之间的连接仅仅是一个指针而不是一个副本,因此可以获得原型中更新后的sayHi属性,

    2.如果我们重写整个原型对象那么情况就不一样了。我们知道调用构造函数时会为实例添加一个指向最初原型的指针[[Prototype]],而把原型修改为另一个对象就等于切断了构造函数与最初原型之间的联系

    看图

    重写原型对象之前

                                                                                               图2

    重写原型对象之后

                                                                                                              图3

  • 相关阅读:
    一起谈.NET技术,验证.NET强命称的思路和实例 狼人:
    一起谈.NET技术,基于SQL Server 2008 Service Broker构建企业级消息系统 狼人:
    一起谈.NET技术,一句代码实现批量数据绑定[下篇] 狼人:
    一起谈.NET技术,晚绑定场景下对象属性赋值和取值可以不需要PropertyInfo 狼人:
    一起谈.NET技术,Silverlight 2.5D RPG游戏技巧与特效处理:(六)流光追影 狼人:
    一起谈.NET技术,ASP.NET下用URLRewriter重写二级域名 狼人:
    这样覆写Object类的toString方法对吗
    【Cocos2DX 】初窥门径(7)无限地图滚动
    poj2975——Caesar密码
    [置顶] poi最简单易学解析xls代码
  • 原文地址:https://www.cnblogs.com/Qqqing/p/11410131.html
Copyright © 2011-2022 走看看