原型模式

  • 原型模式是一個創建型的模式
  • 創建基類的時候,簡單差異化的屬性放在構造函數中,消耗資源相同的共嗯那個放在基類原型中

對象都是由函數創建,函數也是對象,so,萬物皆對象,so easy !!!想哭。

let obj = {name:'aaa'} 
//是下列代碼的語法糖:
let obj = new Object();
obj.name = 'aaa'
  1. 每個函數都有一個屬性 叫 prototype
  2. prototype的屬性值是一個對象,默認的只有一個叫做construcor的屬性,指向這個函數本身
  3. 每個對象都有一個隱藏的屬性__proto__,這個屬性引用了該對象所屬類的prototype
  4. 自定義函數的prototype是有Object創建,所以它的proto指向的就是Object.prototype
  5. Object.prototype的__proto__指向的是null

instanceof

  • instanceof運算符的第一個變量是一個對象,暫時稱爲A,第二個變量一般是一個函數,暫時稱爲B
  • instanceof的判斷規則是:沿着A的__proto__這條線來找,同時沿着B的prototype這條線來找,如果兩條線能找到同一個引用,即同一個對象,那麼就返回true。如果找到終點還未重合,則返回false。
console.log(Object instanceof Function) //true
console.log(Function instanceof Object) //true
console.log(Function instanceof Function) //true

原型鏈

  • 訪問一個對象的屬性時,先在基本屬性中查找,如果沒有,再沿着proto這條鏈向上找,這就是原型鏈
  • hasOwnPropertyk可以區分一個屬性到底是自己的還是從原型中找到

原型優勢

  • 可以隨意擴展
  • 可以重寫繼承的方法
<canvas id="canvas" width="1000" height="600"></canvas>
    <script>
        let canvas = document.getElementById("canvas");
        let ctx = canvas.getContext('2d');
        let circles = [];
        function Circle(x,y,radius){
            this.x = x;
            this.y = y;
            this.radius = radius;
            circles.push(this);
        }
        function getRandomColor(){
            let rand = Math.floor(Math.random()*0xFFFFFFF).toString(16);
            //let rand = Math.floor(Math.random()*16777215).toString(16);等效寫法
            if(rand.length == 6){
                return "#"+rand;
            }else {
                return getRandomColor()
            }
        }
        Circle.prototype.update = function(){
            this.radius--;
            if(this.radius>0) return true;
        }
        Circle.prototype.render = function(){
            ctx.beginPath();
            ctx.arc(this.x,this.y,this.radius,0,2*Math.PI);
            ctx.fillStyle = getRandomColor();
            ctx.fill();
        }
        canvas.onmousemove = function(event){
            new Circle(event.clientX,event.clientY,50)
        }
        setInterval(function(){
            ctx.clearRect(0,0,1000,600)
            circles.forEach((circle)=>{circle.update() && circle.render()});
        },13)
    </script>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章