★JS继承
①原型链继承–单继承
(要在new之后添加属性)
function Animal() {
this.name = null;
this.sex = null;
this.sleep = function () {
return "睡觉";
};
this.eat = function () {
return "吃";
}
this.indexof = function () {
console.log("索引");
}
}
function Dog() {
this.type = "犬科";
}
//原型链继承 继承完成之后 __proto__
Dog.prototype = new Animal();
②构造继承——多继承
构造继承子类的实例是自身而不是它的父类
function People() {
this.name = arguments[0];
this.sex = arguments[1];
this.eat = function () {
return this.name + "正在吃饭!";
}
}
function Student() {
this.score = arguments[0];
this.writezuoye = function () {
return this.name + "写作业";
}
}
//构造继承不能继承父类的原型方法和属性
Student.prototype.work = function () {
return this.name + "跑步";
}
function smallchildren(name, sex, score) {
/* People.call(this,name,sex);*/
People.apply(this, [name, sex]);
Student.call(this, score);
}
var small = new smallchildren("毛豆", "男", 487);
console.log(small instanceof People);//false
console.log(small instanceof smallchildren);//true
console.log(small);
console.log(small.eat());
console.log(small.writezuoye());
③实例继承
function f1() {
this.name = null;
this.sleep = function () {
return "睡觉";
}
}
function f2() {
var f = new f1();
return f;
}
var fchild = new f2();
console.log(fchild);
console.log(fchild instanceof f2);//false
console.log(fchild instanceof f1);//true
var ff = f2();
④组合继承
既是子类的实例又是父类的实例
function Mutou() {
this.name = arguments[0];
this.make = function () {
return "制作" + this.name;
}
}
function Bandeng(name) {
Mutou.call(this, name);
}
Bandeng.prototype = new Mutou();
var ban = new Bandeng("板凳");
console.log(ban);
console.log(ban.make());
console.log(ban instanceof Bandeng);
console.log(ban instanceof Mutou);
console.log(window);
☆设计模式
①工厂模式—最终返回一个对象
function work(name, sex) {
//函数里面封装对象 返回对象
var obj = new Object();
//设置相关属性
obj.name = name;
obj.sex = sex;
obj.sleep = function () {
return "正在睡觉!";
}
return obj;
}
var object = work("毛豆", "男");
console.log(typeof object);
②构造函数模式
function bullet() {
this.width = 20;
this.height = 15;
this.speed = 10;
this.g = 9.8;
this.flymove = function () {
}
}
var b = new bullet();
console.log(b);
③原型模式
* 以原型模式开发
* 原型链模式开发会导致不同的对象之间数据共享
function person() {
}
person.prototype.sleep = function () {
return "睡觉";
}
person.prototype.name = "张三";
var p = new person();
console.log(p);
var p1 = new person();
console.log(p1);
④构造模式 + 原型链模式
function f1() {
this.name = "毛豆"
}
f1.prototype.sleep = function () {
return "睡觉"
}
var f = new f1();
console.log(f);
⑤单例模式 返回为一个对象
var obj = (function () {
var newobj;
function getobj() {
//实例化对象 返回对象
if (newobj == undefined) {
newobj = new factory();
}
return newobj;
}
//创建对象的实例
function factory() {
//对象的封装
this.name = "";
this.sex = "";
this.sleep = function () {
}
}
return {
getObj: getobj
}
})();
console.log(obj.getObj());
★贪吃蛇
this._snack=[["red",3,1,null],["yellow",2,1,null],["yellow",1,1,null]];
//0号位蛇头 _snack[0][1] _snack[0]蛇头 _snack[0][1]坐标
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{
margin: 0;
padding: 0;
}
.map{
width: 900px;
height: 600px;
background-color: black;
}
.snack{
position: absolute;
width: 30px;
height: 30px;
}
.food{
position: absolute;
width: 30px;
height: 30px;
border: 1px solid white;
background-color: blue;
box-sizing: border-box;
}
</style>
</head>
<body>
<script>
var Map;
function map() {
this._map=null;
this.createMap=function () {
this._map=document.createElement("div");
this._map.className="map";
//_map加给body
document.body.appendChild(this._map);
}
}
//创建蛇的类
var Snack;
function snack(){
this._snack=[["red",3,1,null],["yellow",2,1,null],["yellow",1,1,null]];
//蛇的运动方向
this.direct="right";
//3号位 null是蛇的对象 前面的是蛇的属性
this.createSnack=function () {
for (var i=0;i<this._snack.length;i++){
if (this._snack[i][3]==null) {
this._snack[i][3]=document.createElement("div");
this._snack[i][3].className="snack";
//设置颜色 数组0号位是颜色
this._snack[i][3].style.backgroundColor=this._snack[i][0];
//加入地图
Map._map.appendChild(this._snack[i][3]);
}
//1号位 距离左边界的距离
this._snack[i][3].style.left=this._snack[i][1]*30+"px";
//2号位 距离上边界的距离
this._snack[i][3].style.top=this._snack[i][2]*30+"px";
}
}
//蛇的运动方法
this.snackmove=function () {
var len=this._snack.length-1;
for (var i=len;i>0;i--){
//把前一位的属性给后一位
this._snack[i][1]=this._snack[i-1][1];
this._snack[i][2]=this._snack[i-1][2];
}
//蛇根据方向运动
switch (this.direct) {
case "right":
//一号位 距离左边距位置加一 即向右移动一个单位
this._snack[0][1]+=1;
break;
case "left" :
this._snack[0][1]-=1;
break;
case "up" :
this._snack[0][2]-=1;
break;
case "down" :
this._snack[0][2]+=1;
break;
}
//穿越
if (this._snack[0][1]>29){
this._snack[0][1]=0;
}
if (this._snack[0][1]<0){
this._snack[0][1]=29;
}
if (this._snack[0][2]>19){
this._snack[0][2]=0;
}
if (this._snack[0][2]<0){
this._snack[0][2]=19;
}
//检测蛇头和食物的坐标 当它们相同时
if (this._snack[0][1]==Food.x&&this._snack[0][2]==Food.y)
//_snack[0][1] _snack[0]蛇头 _snack[0][1]坐标 _snack[0][2]同理
{
//蛇身长度增加 继承最后一节的属性
this._snack.push(["yellow",
this._snack[this._snack.length-1][1],
this._snack[this._snack.length-1][2],
null]);
//调食物的方法
// 在蛇头的坐标与食物的坐标相同时调用createFood()方法
// function food()的默认值等于null 即每次调用 createFood()方法都
// 会触发 创建新的食物 createFood()方法中 的创建新食物的条件是
// this._food=null 而this._food已经在function food()中声明为null
Food.createFood();
}
//调用方法
this.createSnack();
}
}
//食物
var Food;
function food(){
this._food=null;
this.x;
this.y;
this.createFood=function () {
this.x=Math.floor(Math.random()*30);
this.y=Math.floor(Math.random()*20);
if (this._food==null) {
this._food=document.createElement("div");
this._food.className="food";
//给地图上添加食物
Map._map.appendChild(this._food);
}
this._food.style.top=this.y*30+"px";
this._food.style.left=this.x*30+"px";
}
}
//实例化
window.onload=function () {
//实例化地图
Map=new map();
//创建地图
Map.createMap();
//实例化蛇
Snack=new snack();
//创建蛇
Snack.createSnack();
//实例化食物
Food=new food();
//创建食物
Food.createFood();
//通过键盘控制蛇运动的方位
document.body.onkeyup=function(e){
console.log(e.key);
// 会输出按键 没有参数e无法输出
switch (e.key) {
case "ArrowUp":
if (Snack.direct!="down") { Snack.direct="up";}
break;
case "ArrowDown":
if (Snack.direct!="up") { Snack.direct="down";}
break;
case "ArrowLeft":
if (Snack.direct!="right") { Snack.direct="left";}
break;
case "ArrowRight":
if (Snack.direct!="left") { Snack.direct="right";}
break;
}
}
//创建计时器 调用snackmove
setInterval(function () {
Snack.snackmove();
},300);
//500毫秒跑一次
}
</script>
</body>
</html>