js基础-原型

1、定义:我们创建的函数都有一个prototype(原型)属性,该属性是一个对象,
         原型模式声明中多了两个属性(自动生成)。
构造函数:
      function Box(name,age){
this.name = namw;//实例属性
         this.age = age; //实例属性
this.run = function (){ //实例方法
  return this.name + this.age + "运行中..."
        }
      }
       var box1 = new Box("张三",25);
       var box2 = new Box("张三",25);
       console.log(box1.run == prp2.run);//false (实例方法的引用地址具有唯一性,不可能一样)
          
原型:即共享,共享即引用地址一致
      function Prp() {}//字面量方式创建更有封装效果
       Prp.prototype.name = "原型";  //原型属性
        Prp.prototype.address = "云南";//原型属性
        Prp.prototype.run = function () {//原型方法
        return "原型名:" + this.name + "原型地址:" + this.address
       }
        var prp1 = new Prp();//实例化
        var prp2 = new Prp();
        console.log(prp1.run == prp2.run);//true(原型方法的引用地址保持一致(区别实例方法))
        alert(prp1.__proto__);//__proto__这个属性是一个指针,指向prototype原型对象,可获取但是无法获取具体信息
alert(prp1.constructor);//构造属性(用于被原型指针定位并得到构造函数本身,即实例对象对应的原型对象)
   注:__proto__和constructor可辅助理解后台工作原理,不用掌握
2、判断一个对象是否指向该构造函数的原型对象:isPrototypeOf();
   console.log(Prp.prototype.isPrototypeOf(prp1));//true  只要实例化对象就自动指向
3、原型模式的执行流程
1)先查找构造函数实例里的属性或方法,若有就返回
2)若构造函数实例里没有,则去他的原型对象找,有就返回。
3)对象实例可访问保存在原型中的值不能访问通过对象实例重写原型中的值
eg.
     prp1.name="重庆";
        console.log(prp1.name);//重庆(就近原则,这里是实例属性,并未修改原型属性)
        console.log(prp2.name);//原型(原型里的值)
4)若要prp1也访问到原型里的值,只需将属性删除,即
        delete prp1.name;//这里删除的是实例属性,不是原型属性
        console.log(prp1.name);//原型中的name
Prp.prototype.name = "原型11";//覆盖原型中的属性
3、判断属性在原型里还是在函数的实例里:hasOwnProperty()
  console.log(Prp.hasOwnProperty('name'));//true(判断实例中是否存在指定属性)
        console.log(prp1.hasOwnProperty(name));//false
4、in操作符:不管属性在实例中还是原型中,in会在通过对象能访问给定属性时返回true,
**** 即判断实例中或原型中是否存在属性。****
console.log('name' in prp2);//true(name属性可以访问)
5、判断原型中是否存在属性
function Prp() {
          Prp.prototype.name = "原型";
          Prp.prototype.address = "云南";
          Prp.prototype.run = function () {
            return "原型名:" + this.name + "原型地址:" + this.address
          }
        }
        function isProperty(obj,property) {//判断原型中是否存在属性
          return !obj.hasOwnProperty(property) && (property in obj);
        }
        var isprp1 = new Prp();
        console.log(isProperty(isprp1,'name'));//true
        console.log(isProperty(isprp1,'age'));//false
6、字面量方式创建原型 
function Prp1(){};//字面量方式创建原型更有封装效果
        Prp1.prototype={//相当于原型被重写了
          name:"张三",
          age:15,
          address:"四川",
  run: function f() {
            return "原型名:" + this.name + "原型地址:" + this.address
          }
        }
7、字面量方式创建原型对象:constructor不指向实例,指向Object
     var prp0 = new Prp1();
        console.log(prp0 instanceof Prp1);//true
        console.log(prp0 instanceof Object);//true
        console.log(prp0.constructor == Prp1);//false
        console.log(prp0.constructor == Object);//true
/*字面量方式指向实例:*/
        Prp1.prototype = {
          constructor: Prp1
        }
8、****解决穿参合引用共享的问题:不共享的使用构造函数,共享的使用原型模式*****
      function Gz(name, age) {//构造函数(不共享,保持独立)
          this.name = name;
          this.age = age;
          this.family = ['哥哥', '姐姐', '妹妹', '弟弟'];
        }
        Gz.prototype = {//原型模式,共享
          constructor:Gz,//指向
          run:function () {
            return this.name+','+this.age+','+this.family
          }
        }
***动态原型模式***
        function Gzhs(name, age) {//构造函数(不共享)
          this.name = name;
          this.age = age;
          this.family = ['哥哥', '姐姐', '妹妹', '弟弟'];
          if (typeof this.run != "function") {
       //判断后仅在第一次调用时初始化,没必要实例化一次就初始化一次,且实现了封装和共享,但是属性独立
          Gzhs.prototype.run = function () {
              return this.name + ',' + this.age + ',' + this.family
          }
        }
      }
        var hs1 = new Gzhs("张三",50);//实例化
        console.log(hs1.run());//张三,50,哥哥,姐姐,妹妹,弟弟
9、寄生构造函数=工厂模式+构造函数 (通用模式)
function Box(name,age){
  var obj = new Object();
  obj.name = name;
  obj.age = age;
  obj.run = function(){
   return this.name +this.age + "运行中..."
  }
   return obj
}
var box1 = new Box("张三",50);//实例化
console.log(box1.run());
posted on 2019-06-17 09:22  小虾米吖~  阅读(176)  评论(0编辑  收藏  举报