本章节主要讲解js的继承,in和instanceof运算符和一些方法
继承
继承继承,子承父业,父亲有的孩子都有。直接看实例吧,有一个people方法 和一个student 那么student要去继承people的参数和方法,咱们循循渐进的一一道来。先上代码
<script type="text/javascript">
function People(name,age){
this.name = name;
this.age = age;
}
People.prototype.eat = function(){
alert("eat eat");
}
function Student(name,age,xuehao,nianji){
People.apply(this,arguments);
this.xuehao = xuehao;
this.nianji = nianji;
}
Student.prototype.play = function(){
alert("play games");
}
var xiaoming = new Student("xiaoming",18,1322120211,"一年级");
console.log(xiaoming);
console.log(xiaoming.name+" "+xiaoming.age+" "+xiaoming.xuehao+" "+xiaoming["nianji"]);
</script>
我们可以看到people是父类,student是子类,那么在创建子类的同时需要需要继承父类的全部属性,所以我们在student里面加了———> People.apply(this,arguments),将people的this指向student,从而给student添加上了父类也就是people的属性。
这个时候我们完成了子类继承父类的属性,通过日志我们可以看到到确实是这么一回事儿,但是people的方法却没有继承,若想调用people的eat方法,xiaoming.eat();会报错说找不到eat方法。那么这个时候,我们就需要利用到上一节课的知识点,原型链,将people的原型链赋予student,那么xiaoming在调用eat的时候可以通过原型链的机制,也就是__proto__向上到,到到people的eat方法,从而显示出来。
关键代码 Student.prototype = People.prototype;
不妨输出添加上诉关键代码的xiaoming的日志
可以看到在__proto__里有父亲people的eat方法。
在这里参数的继承还有一种方式,首先添加完关键代码之后,我们来看看student.constructor的输入,
其实student.constructor是一个方法,因为将student的原型对象是people的prototype,prototype里是有people的构造方法,通过student.constructor间接的调用了people原型的构造方法,所以
this.constructor.apply(this,arguments)可以替代People.apply(this,arguments)
in操作符
主要作用就是判断某个对象是否含有某个属性。
var obj ={
a:10,
b:20,
c:30,
};
obj.__proto__.x = true;
//obj.prototype.y = true;//这一步报错
console.log("a" in obj);//true
console.log("b" in obj);//true
console.log("x" in obj);//true
//console.log("y" in obj);//前面报错 无法执行到该步
首先所有的方法都有prototype属性,通过方法new出来的对象是有prototype属相,但是通过{ }出来的对象是没有prototype属性,因为所有的对象最顶层的原型对象都是object,所以我们可以通过__proto__的方法去添加额外参数x。
如 console.log("abc" in obj);那么会返回underfined obj没有改参数,则会往上的原型对象查找。
hasOwnProperty
查看对象自己身上是否有该属性,不考虑原型链上的。
hasOwnProperty 该方法其实是object的一个方法
var obj = {
x: 1,
y: 2,
z:3
}
obj.__proto__ = {
h: 4
}
console.log(obj);
alert(obj.hasOwnProperty("x"));//true
alert(obj.hasOwnProperty("y"));//true
alert(obj.hasOwnProperty("z"));//true
alert(obj.hasOwnProperty("h")); // false 不考虑原型链 就看自己身上有没有该属性
我们可以看到 obj的原型对象object中有hasOwnProperty方法,
看后面输出,确实是查找对象不从原型链上查找
instanceof
表示该对象是否含有某一实例,也可以理解遍历该对象的原型链上的原型对象,若访问到的原型对象是目标实例的构造函数的prototype,则返回true。
function Cat() {
}
function Dog() {
}
Cat.prototype = new Dog();//
console.log(Cat.prototype); // 狗的实例
var hellokitty = new Cat();
console.log(hellokitty instanceof Dog);//true
console.log(hellokitty instanceof Cat);//true
console.log(hellokitty instanceof Object);//true
为什么Object返回true?不要忘了所有对象最顶层的__proto__都是object
下面在附上一个demo----->打气球
如上所示的打气球,其实原理和之前一个例子一样小红帽走路一样,通过面向对象的思想去写一个气球的方法,再通过定时去改变气球的top。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
html,body {
height: 100%;
overflow: hidden;
background-color: #ccc;
}
div {
width: 250px;
height: 333px;
position: absolute;
background: url(img/ballons.png) no-repeat -250px 0;
}
</style>
</head>
<body>
<!-- <div></div> -->
<h1></h1>
<h1></h1>
<script type="text/javascript">
// 面向对象技术
// 创建气球的构造函数
function Ballon() {
// 列举气球所有的属性和方法和监听
this.dom = null;
this.x = null;
this.y = null;
this.scroe = null;
// 初始化
this.init();
// 绑定事件
this.bindEvent();
// 把new出来的对象存放全局数组中 便于管理
Ballons.push(this);
}
// init() 方法
Ballon.prototype.init = function() {
// 上DOM树
this.dom = document.createElement("div");
document.body.appendChild(this.dom);
//初始化x和y
this.y = document.documentElement.clientHeight;
this.x = parseInt(Math.random()*(document.documentElement.clientWidth - 250));
this.dom.style.left = this.x + "px";
this.dom.style.top = this.y + "px";
// 产生一个随机分数 1~12
this.score = parseInt(Math.random()*12)+1;
// 显示对应分数的气球背景
var cutx = - (this.score-1)%4 *250;
var cuty = 0;
if(this.score>8) {
cuty = -333*2;
} else if(this.score>4) {
cuty = -333;
}
this.dom.style.backgroundPosition = cutx + "px "+cuty+"px";
}
// update方法
Ballon.prototype.update = function() {
this.y -= this.score*5;
if(this.y < - 340) {
this.goDied();
}
this.dom.style.top = this.y + "px";
}
Ballon.prototype.bindEvent = function(){
var mthis = this;
mthis.dom.onclick = function(){
scoreAll +=mthis.score;
document.body.removeChild(mthis.dom);
for(var i = 0;i<Ballons.length;i++){
if (mthis===Ballons[i]) {
Ballons.splice(i,1);
}
}
};
}
// 删除
Ballon.prototype.goDied = function() {
document.body.removeChild(this.dom);
// 之前所在的数组删除该元素
for(var i=0; i<Ballons.length; i++) {
if(this===Ballons[i]) {
Ballons.splice(i,1);
}
}
}
var Ballons = [];
var scoreAll = 0;
// 游戏总时间
var allTime = 20;
// 定义帧数
var iframe = 0;
var timer = setInterval(function() {
iframe++;
if(iframe%10==0) {
allTime--;
// 每秒创建4个气球
for(var i=0; i<4; i++) {
new Ballon();
}
}
console.log(allTime+" alltime");
document.getElementsByTagName("h1")[0].innerHTML = "你目前总分为"+scoreAll;
document.getElementsByTagName("h1")[1].innerHTML = "游戏剩余"+allTime+"秒";
// 让Ballons里面所有的气球对象调用update()
for(var i=0; i<Ballons.length; i++) {
Ballons[i]&&Ballons[i].update();
}
if(allTime <= 0) {
console.log("~~~~~~");
clearInterval(timer);
alert("Game Over");
}
}, 100);
</script>
</body>
</html>
js高级相关部分已讲完,接下来会来讲解日历的编写,如有表达错的请谅解,并请提出指出,且修改错误,望能共同进步。