• JavaScript面向对象深入理解原型


     原型模式

    function Person(){
    }
    Person.prototype.name="Ewarm";
    Person.prototype.age="29";
    Person.prototype.job="software Engineer";
    Person.prototype.sayName=function(){
    alert(this.name);
    }
    var person1=new Person()
    //我们可以通过isPrototypeOf()方法来确定对象之间是否存在这种关系,即实例.__proto__是否指向构造函数的原型对象,如果指向那么这个方法返回为ture。
    alert(Person.prototype.isPrototypeOf(person1))//true
    //ECMAScript5增加了一个新方法 Object.getPrototypeOf() 这个方法返回的是实例.__proto__的值,即构造函数原型对象
    
    alert(Object.getPrototypeOf(person1)==Person.prototype)//true 返回实例.__proto__的值
    alert(Object.getPrototypeOf(person1).name) //Ewarm
    

      

    //细心的你们会发现这样每次都是Person.prototype.属性真的好麻烦于是我们出现下面这种

     更简单的原型语法

    function Person(){
    
    }
    Person.prototype={
    name:"Ewarm",
    age:25,
    job:"software engineer",
    sayName:function(){
    alert(this.name)
    }
    
    }
    //注意这里虽然和之前的最终结果相同 但是这里的constructor属性不再指向Person了 原因:每建一个函数,就会同时创建它的prototype对象,这个对象也会自动获得constructor属性,此时通过constructor已经无法确定对象类型了
    var person=new Person()
    alert(person instanceof Object )//ture
    alert(person instanceof Person)//ture
    alert(person.constructor==Person)//false
    alert(person.constructor==Object)//true
    

      

    //但是我们可以通过以下方法来修正constructor

    function(){
    }
    Person.prototype={
    constructor:Person,//相当于复写
    name:"Ewarm",
    age:25,
    job:"software engineer",
    sayName:function(){
    alert(this.name)
    }
    }

    //这样虽然修正了但是,constructor的enmurable属性会变为true 即可枚举 如果要设置回去 可以使用Object.defineProperty(),只适用于ECMAScript5兼容器的浏览器

    原型的动态性

    function Person(){
    }
    var person=new Person()
    Person.prototype={
    constructor:Person,//相当于复写
    name:"Ewarm",
    age:25,
    job:"software engineer",
    sayName:function(){
    alert(this.name)
    }
    }
    person.sayName()//error

    //报错的原因:重写原型对象切断了现有原型与任何之前已经存在的实例之间的联系,他们引用的仍然是最初的原型

    function Person(){}
    var person1=new Person()
    Person.prototype.sayHi=function(){
    alert("hi")
    }
    person1.sayHi()//hi
    //这里相当于添加方法而非重写  

     往原生对象添加方法

    String.prototype.Ewarm=function(text){
    return this.indexOf(text)==0//找到为0
    }
    var message="hello Ewarm"
    alert(message.Ewarm("hello"))//true 

     原型的问题
    //共享所带来的问题 尤其是针对引用类型值的属性

    function Person(){}
    Person.prototype={
    constructor:Person,
    name:"Ewarm",
    age:25,
    job:"software engineer",
    friends:["cch","emon"],
    sayName:function(){
    alert(this.name)
    }
    }
    var person1=new Person()
    var person2=new Person()
    person1.friends.push("tea")
    alert(person1.friends)//"cch","emon","tea"
    alert(person2.friends)//"cch","emon","tea"
    alert(person1.friends==person2.friends)//true
    //组合使用构造函数模式和原型模式可以解决这个问题
    

     如果看不懂 建议挨个敲一遍哦~ 这样更容易理解 

  • 相关阅读:
    判断一下是星期几
    猴子分桃
    免子生免子
    字符串排序
    非关系型数据库(一)
    学习redis简介(一)
    SAVEPOINT
    *****POSTGRESQL文檔
    程序员人生之路(分析的非常透彻!)
    UpperCase for ALL Text Editors
  • 原文地址:https://www.cnblogs.com/Ewarm/p/7740062.html
Copyright © 2020-2023  润新知