JavaScript学习记录十四

创建对象三种方式:
    
    //1  字面量的方式
    //2  调用系统的构造函数
    //3  自定义构造函数方式

    * 1.开辟空间存储对象
    * 2.把this设置为当前的对象
    * 3.设置属性和方法的值
    * 4.把this对象返回

    //实例对象
    var per1={
      name:"卡卡西",
      age:20,
      sex:"男",
      eat:function () {
        console.log("吃臭豆腐");
      },
      readBook:function () {
        console.log("亲热天堂");
      }
    };

    //调用系统的构造函数
    var per2=new Object();
    per2.name="大蛇丸";
    per2.age=30;
    per2.sex="男";
    per2.eat=function () {
      console.log("吃榴莲");
    };

    //自定义构造函数
    function Person(name,age,sex) {
      this.name=name;
      this.age=age;
      this.sex=sex;
      this.play=function () {
        console.log("天天打游戏");
      };
    }
    var per=new Person("雏田",18,"女");

工厂模式常见对象

    * 共同点:都是函数,都可以创建对象,都可以传入参数
    *
    * 工厂模式:
    * 函数名是小写
    * 有new,
    * 有返回值
    * new之后的对象是当前的对象
    * 直接调用函数就可以创建对象
    *
    * 自定义构造函数:
    * 函数名是大写(首字母)
    * 没有new
    * 没有返回值
    * this是当前的对象
    * 通过new的方式来创建对象

    function createObject(name,age) {
      var obj=new Object();
      obj.name=name;
      obj.age=age;
      obj.sayHi=function () {
        console.log("您好");
      };
      return obj;
    }
    function Person(name,age) {
      this.name=name;
      this.age=age;
      this.sayHi=function () {
        console.log("您好");
      };
    }
    var per1=new Person("小红",20);
    var per2=createObject("小明",20);

实例对象和构造函数之间的关系

    * 实例对象和构造函数之间的关系:
    * 1. 实例对象是通过构造函数来创建的---创建的过程叫实例化
    * 2.如何判断对象是不是这个数据类型?
    *  1) 通过构造器的方式 实例对象.构造器==构造函数名字
    *  2) 对象 instanceof 构造函数名字
    *  尽可能的使用第二种方式来识别,为什么?原型讲完再说

通过构造函数创建对象的问题

function myEat() {
  console.log("吃大榴莲");
}
var myEat=10;
function Person(name,age) {
  this.name=name;
  this.age=age;
  this.eat=myEat;
}
var per1=new Person("小白",20);
var per2=new Person("小黑",30);

console.dir(per1);
console.dir(per2);
console.log(per1.eat==per2.eat);true   →10
//通过原型来解决---------数据共享,节省内存空间,作用之一

解决:通过原型来添加方法解决数据共享的问题

    function Person(name,age) {
      this.name=name;
      this.age=age;
    }
    //通过原型来添加方法,解决数据共享,节省内存空间
    Person.prototype.eat=function () {
      console.log("吃凉菜");
    };

    var p1=new Person("小明",20);
    var p2=new Person("小红",30);
    console.log(p1.eat==p2.eat);//true

    console.dir(p1);
    console.dir(p2);

原型
    * 实例对象中有__proto__这个属性,叫原型,也是一个对象,这个属性是给浏览器使用,不是标准的属性----->__proto__----->可以叫原型对象
    * 构造函数中有prototype这个属性,叫原型,也是一个对象,这个属性是给程序员使用,是标准的属性------>prototype--->可以叫原型对象
    *
    * 实例对象的__proto__和构造函数中的prototype相等--->true
    * 又因为实例对象是通过构造函数来创建的,构造函数中有原型对象prototype
    * 实例对象的__proto__指向了构造函数的原型对象prototype

这一段和上面那一段接着,为原型的设置和使用
    console.dir(p1);
    console.dir(p2);
    console.dir(Person);
    p1.__proto__.eat();//吃凉菜
    console.log(p1.__proto__==Person.prototype);//true

面向过程的编程思想和面向对象的编程思想

  function ChangeStyle(btnObj, dvObj, json) {
    this.btnObj = btnObj;
    this.dvObj = dvObj;
    this.json = json;
  }
  ChangeStyle.prototype.init = function () {
    //点击按钮,改变div多个样式属性值
    var that = this;
    this.btnObj.onclick = function () {//按钮
      for (var key in that.json) {
        that.dvObj.style[key] = that.json[key];
      }
    };
  };


  //实例化对象


  var json = {"width": "500px", "height": "800px", "backgroundColor": "blue", "opacity": "0.2"};
  var cs = new ChangeStyle(my$("btn"), my$("dv"), json);
  cs.init();//调用方法

面向对象,一部分
  document.getElementById("btn").onclick=function () {
      document.getElementById("dv").style.backgroundColor="yellow";
  };

原型复习

    function Person(sex,age) {
      this.sex=sex;
      this.age=age;
    }
    //通过原型添加方法
    Person.prototype.sayHi=function () {
      console.log("打招呼,您好");
    };
    var per=new Person("男",20);
    console.log(per.__proto__.constructor==Person.prototype.constructor);true
    console.dir(Person);//构造函数的名字

    var per2=new Person("女",30);
    console.log(per.sayHi==per2.sayHi);true

构造函数、实例对象、原型对象

    //原型的作用之一:共享数据,节省内存空间,需要共享的数据就可以写原型中,不需要共享的数据可以写在构造函数中

//    //通过构造函数实例对象,并初始化
//    var arr=new Array(10,20,30,40);
//    //join是方法,实例对象调用的方法
//    arr.join("|");
//    console.dir(arr);
//    //join方法在实例对象__proto__原型
//    console.log(arr.__proto__==Array.prototype); true

    * 构造函数可以实例化对象
    * 构造函数中有一个属性叫prototype,是构造函数的原型对象
    * 构造函数的原型对象(prototype)中有一个constructor构造器,这个构造器指向的就是自己所在的原型对象所在的构造函数
    * 实例对象的原型对象(__proto__)指向的是该构造函数的原型对象
    * 构造函数的原型对象(prototype)中的方法是可以被实例对象直接访问的

原型的用法-手动修改构造器

function Student(name, age, sex) {
      this.name = name;
      this.age = age;
      this.sex = sex;
    }
    简单的原型写法
    Student.prototype = {
      //手动修改构造器的指向
      constructor:Student,
      height: "188",
      weight: "55kg",
      study: function () {
        console.log("学习好开心啊");
      },
      eat: function () {
        console.log("我要吃好吃的");
      }
    };

    var stu=new Student("段飞",20,"男");
    stu.eat();
    console.log(stu.__proto__.height);  188
    console.dir(Student);
    console.dir(stu);

原型中添加的方法是可以相互调用的

    function Animal(name,age) {
      this.name=name;
      this.age=age;
    }
    //原型中添加方法
    Animal.prototype.eat=function () {
      console.log("动物吃东西");
      this.play();
    };
    var dog=new Animal("小苏",20);
    dog.eat();

对象使用属性或方法,查找策略(构造函数   原型)

    * 实例对象使用的属性或者方法,先在实例中查找,找到了则直接使用,找不到则,去实例对象的__proto__指向的原型对象prototype中找,找到了则使用,找不到则报错

    function Person(age,sex) {
      this.age=age;//年龄
      this.sex=sex;
      this.eat=function () {
        console.log("构造函数中的吃");
      };
    }
    Person.prototype.sex="女";
    Person.prototype.eat=function () {
      console.log("原型对象中的吃");
    };


    var per=new Person(20,"男");
    console.log(per.sex);//男
    per.eat();
    console.dir(per);

为内置对象添加方法

     *注意:这里方法的调用不需要通过__proto__直接就可以实现调用

    String.prototype.myReverse=function () {
      for(var i=this.length-1;i>=0;i--){
        console.log(this[i]);
      }
    };
    var str="abcdefg";
    str.myReverse();


    //为Array内置对象的原型对象中添加方法
    Array.prototype.mySort=function () {
      for(var i=0;i<this.length-1;i++){
          for(var j=0;j<this.length-1-i;j++){
              if(this[j]<this[j+1]){
                  var temp=this[j];
                this[j]=this[j+1];
                this[j+1]=temp;
              }//end if
          }// end for
      }//end for
    };

    var arr=[100,3,56,78,23,10];
    arr.mySort();
    console.log(arr);


    String.prototype.sayHi=function () {
      console.log(this+"哈哈,我又变帅了");
    };

    //字符串就有了打招呼的方法
    var str2="小杨";
    str2.sayHi();

将局部变量设置为全局变量

    //把局部变量给window就可以了

    函数的自调用---自调用函数
    一次性的函数--声明的同时,直接调用了
    (function (win) {
      var num=10;//局部变量
      //js是一门动态类型的语言,对象没有属性,点了就有了
      win.num=num;
    })(window);
    console.log(num);

案例:把随机数对象暴露给全局对象window

      *注意最后一行,原型方法的调用。

      *设置为全局的语法,易搞错。这样设置外部如果要使用必须new,如果通过new来设置外部,可以直接调用。下边有案例

      *自调函数一定要加上结尾的分号

    通过自调用函数产生一个随机数对象,在自调用函数外面,调用该随机数对象方法产生随机数
    (function (window) {
      产生随机数的构造函数
      function Random() {
      }
      在原型对象中添加方法
      Random.prototype.getRandom = function (min,max) {
        return Math.floor(Math.random()*(max-min)+min);
      };
      把Random对象暴露给顶级对象window--->外部可以直接使用这个对象
      window.Random=Random;
    })(window);
    实例化随机数对象
    var rm=new Random();
    调用方法产生随机数
    console.log(rm.getRandom(0,5));
    console.log(Random.prototype.getRandom(0,5));

案例:随机方块

  <style>
    .map{
      width: 800px;
      height: 600px;
      background-color: #CCC;
      position: relative;
    }
  </style>
</head>
<body>
<div class="map"></div>
<script src="common.js"></script>
<script>
  //产生随机数对象的
  (function (window) {
    function Random() {
    }
    Random.prototype.getRandom=function (min,max) {
      return Math.floor(Math.random()*(max-min)+min);
    };
    //把局部对象暴露给window顶级对象,就成了全局的对象
    window.Random=new Random();
  })(window);//自调用构造函数的方式,分号一定要加上


  //产生小方块对象
  (function (window) {
    //console.log(Random.getRandom(0,5));
    //选择器的方式来获取元素对象
    var map=document.querySelector(".map");

    //食物的构造函数
    function Food(width,height,color) {
      this.width=width||20;//默认的小方块的宽
      this.height=height||20;//默认的小方块的高
      //横坐标,纵坐标
      this.x=0;//横坐标随机产生的
      this.y=0;//纵坐标随机产生的
      this.color=color;//小方块的背景颜色
      this.element=document.createElement("div");//小方块的元素
    }
    //初始化小方块的显示的效果及位置---显示地图上
    Food.prototype.init=function (map) {
      //设置小方块的样式
      var div=this.element;
      div.style.position="absolute";//脱离文档流
      div.style.width=this.width+"px";
      div.style.height=this.height+"px";
      div.style.backgroundColor=this.color;
      //把小方块加到map地图中
      map.appendChild(div);
      this.render(map);
    };
    //产生随机位置
    Food.prototype.render=function (map) {
      //随机产生横纵坐标
      var x=Random.getRandom(0,map.offsetWidth/this.width)*this.width;
      var y=Random.getRandom(0,map.offsetHeight/this.height)*this.height;
      this.x=x;
      this.y=y;
      var div=this.element;
      div.style.left=this.x+"px";
      div.style.top=this.y+"px";
    };

    //实例化对象
    var fd=new Food(20,20,"green");
    fd.init(map);
    console.log(fd.x+"===="+fd.y);

    
  })(window);
</script>

猜你喜欢

转载自blog.csdn.net/qq_34117624/article/details/82890725