博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS之理解原型和原型链
阅读量:7120 次
发布时间:2019-06-28

本文共 2686 字,大约阅读时间需要 8 分钟。

原型与原型链

一.在了解原型之前需要提前了解的。
  • 1.工厂模式:创建一个函数,用特定的接口创建对象的细节。

    //现在要创建两个包含 “name”和“age”的对象,let tom ={name:"Tom",age:16}let lily = { name : "Lily",age:18}……//所示数量足够具大 ,对象足够大 ,会花费大量的时间。下面的工厂模式能 很好的解决这一问题
    //工厂的就是只流水线不是所有都是要人工,节约人力成本。  function person(name,age){      let  obj = {}; //创建一个对象 ;      obj.name = name ; //为对象添加细节      obj.age = age ;      obg.sayHello= function (){        alert ("Hello"+this.name)      };      return obj;} //返回这个对象   let tom = person("Tom",16);  let lily = person("Lily",18)
    • 工厂函数的优势:避免的大量的重复代码;
    • 工厂函数的劣势:其创建的对象不能标志为一种特定的类型,没有解决对象识别的问题,不知道对象的类型。构造函数能很好的解决这个问题。
  • 2.构造函数:自定义构造函数,可以自定义对象类型的属性和方法。

    function Person(name,age){         this.name = name ; //为对象添加细节      this.age = age ;      this.sayHello= function (){        alert ("Hello"+this.name)      };  let tom = new Person("Tom",16);  let lily =new Person("Lily",18)
    • new的过程做了三件事创建了一个对象;this指向这个对象;返回这个对象;
    • 两个实例对象都有一个属性constructor(构造函数),指向Person;这就是可以通过constructor判断对象类型的原理。
    • 存在的问题:构造函数的每个方法都要在实例上重新创建一遍,虽然函数名是一样的,但是不相等的。

二.原型模式
  • 1.如下,与构造函数模式不同的是,原型模式的每个实例都是访问同一属性同一函数,,函数不用重新创建。

    function Person () {   this.x = 100;}Person.prototype.name = 'Tom';Person.prototype.age = 18;Person.prototype.sayHello =  function (){  alert(`Hello${this.name}`)}let Tom = new Person()Tom.sayHello()
  • 2.原型对象

    • ①每个函数数据类型(普通函数,类)上,都有一个属性,叫prototype,是一个对象,这个函数指向函数的原型对象;
    • prototype这个对象上,自带一个属性,constructor指向当前这个类;
    • ③当为实例添加属性时,这个属性会屏蔽原型对象中保存的同名属性,但是事实阻止访问,并没有修改那个属性,若将同名的实例属性设置为null,同样会屏蔽,但是若用delete,则可以删除实例属性,可以重新访问原型中的属性。

      alert(Tom.age);  //18let Tom.age = 20;alert(Tom.age); //20delete Tom.age;alert(Tom.age); //18

      clipboard.png

    • ④属性分为两种,来自实例(或者是构造函数)或是原型,原型上的属性和方法都是共有的,构造函数中的属性方法都是私有的,构造函数中的this都是实例。为什么私有属性(来自实例的属性)的查找等级要高呢?这就涉及到原型链。
  • 3.原型链:每个对象数据类型(普通对象,prototype,实例)都有一个属性,叫做__proto__

    • 比如我们console.log(Tom.age)的查找过程是怎样的呢?①首先在私有空间内查找age属性,私有空间的属性包括自身的属性和从类那里继承的属性,
    • ②找不到的话:通过__proto__去当前实例所属类的原型上进行查找,找到的话,说明是共有属性;
    • ③还找不到的话:继续通过__proto__去当前实例所属类的原型进行查找,找不到将继续通过__proto__一直找到Object
      clipboard.png
    • ④曲线代表Person的原型对象;曲线中,实例Tom通过__proto__指向Tom所属类(Person)的原型(Person Prototype);曲线③中,Person的原型对象通过__proto__找到Person对象的所属类,也就是Object(函数也是对象类,万物皆对象),指向它的原型(ObjectPrototype) ;曲线5中,指向Obeject所属类的原型,它的类就是它自己,所以此时不在有__proto__整个属性查找结束,这就是原型链的查找过程。
      clipboard.png
    • ⑤通过hasOwnProperty来判断属性,这个方法就是通过④中的查找过程,在基类Object中找到的。 判断属性是否在对象上“name” in Tom,其中in的查找过程也是通过上述的查找过程。

      function hasPrototypeProperty(object,attr){   return !object.hasOwnProperty(attr) && (attr in object);}
  • 4.关于原型需要注意的几点

    • ①使用简单原型语法的时候,注意constructor的指向问题,

      Person.prototype={  //此时constructor指向Object构造函数   name : 'Tom',   age:18}Person.prototype={  //此时constructor指向Person   constructor:Person,   name : 'Tom',   age:18}
    • ②添加和修改原型的属性和方法都能立即在所有对象实例中反应出来(即使先创建实例后修改原型);但是如果重写整个原型对象,创建在前的实例并不能获得重写后的属性或方法。这是因为重写原型之后是新生成原型对象,和声明在前的任何已经存在的实例都没有关系。

转载地址:http://vwsel.baihongyu.com/

你可能感兴趣的文章
拷贝继承
查看>>
[解题报告]Codeforces 105D Entertaining Geodetics
查看>>
Mongo之架构部署(Replica Sets+Sharding)
查看>>
小程序(一)
查看>>
POJ 2689
查看>>
java 继承 String类
查看>>
开始gentoo之旅
查看>>
自动化测试(三)
查看>>
PHP获取访客ip、系统、浏览器等信息[转]
查看>>
的记录
查看>>
CSS之设置p段落中的文字与页面左侧缩进两个字符!...
查看>>
给Android SDK设置环境变量
查看>>
迷茫的世界
查看>>
返回固定数据的web服务器
查看>>
视频信息查看,帧信息查看
查看>>
【python+flume+kafka+spark streaming】编写word_count入门示例
查看>>
PLSQL Developer简单使用教程
查看>>
浅谈分布式计算的开发与实现(二)
查看>>
linux下的chromedriver驱动器配置实例(含代码)
查看>>
spring2.5.6不兼容jdk8
查看>>