1. 程式人生 > >JavaScript學習記錄十四

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>