- 原型模式是一個創建型的模式
- 創建基類的時候,簡單差異化的屬性放在構造函數中,消耗資源相同的共嗯那個放在基類原型中
對象都是由函數創建,函數也是對象,so,萬物皆對象,so easy !!!想哭。
let obj = {name:'aaa'}
//是下列代碼的語法糖:
let obj = new Object();
obj.name = 'aaa'
- 每個函數都有一個屬性 叫 prototype
- prototype的屬性值是一個對象,默認的只有一個叫做construcor的屬性,指向這個函數本身
- 每個對象都有一個隱藏的屬性__proto__,這個屬性引用了該對象所屬類的prototype
- 自定義函數的prototype是有Object創建,所以它的proto指向的就是Object.prototype
- 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>