- 构造函数
一个函数可以用new关键字来调用。那么此时将按顺序发生四件事情
- 隐秘的创建一个新的空对象
- 将这个喊里面的this绑定到刚才创建的隐秘新对象上
- 执行函数体里面的语句
- 返回这个新的对象。
function People(){
this.name="小米";
this.age=18;
this.sex="男";
}
var xiaoming=new People();
console.log(xiaoming);
- 这个函数不仅能执行,还能返回出来一个对象。这个函数就是构造函数,构造函数是用大写字母开头的。上述的叫做Peolple类,xiaoming是这个类的实例化
function People(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
this.sayHello()=fucntion(){
alert("你好,我是"+this.name+",nice to meet you");
}
var xiaoming=new People("xiaoming",18,"男");
var kiny=new People("kiny",17,"女");
javascript中,没有类的概念。是通过构造函数的4不走机制来创建类似的对象吧,可以看成类。JS这个语言是"基于对象"的语言,不能叫做"面向对象"语言。
构造函数中不允许出现return语句
- 原型prototypes属性
每个函数都有prototype属性,prototype的类型是object类型。
当这个函数是一个构造函数的时候,那么它new出来的对象,将以它的原型那个对象为new出来的实例的原型对象。
注意:任意一个对象,都有__proto__属性,这个属性是Chrome自己的属性,别的浏览器不兼容。但是别的浏览器也有原型对象,只不过不能通过__proto__进行访问。这是属性指向自己的原型对象。
举例代码
function People(name,sex,age){
this.name=name;
this.sex=sex;
this.age=age;
}
//构造函数的原型
people.prototype={
haha:250
}
var xiaoming=new People("小明",18,,"男");
//当一个对象被new出来的时候,不仅仅执行了构造函数里面的语句,也会把这个函数__proto__属性值指向构造函数prototype.
console.log(xiaoming.haha); //250 可以读取
console.log(xiaoming.__proto__);
coosole.log(xiaoming.__proto__==People.prototype);//true;
原型链查找
当方位一个对象身上的属性的时候,如果这个对象身上有这个属性,则返回它的值。如果身上没有这个属性,那么将访问他的原型对象,检测它的原型对象身上是否有这个值,如果有返回它原型对象身上的这个值。
当这个函数是构造函数的时候,new出来的对象,他们的原型对象就是这个构造函数的原型。prototype我们称为"原型".
prototype 我们称为原型 只有函数有原型
__proto__属性的值 我们称为原型对象 任何对象都有原型对象。
原型的用途
function People(name,age){
this.name=name;
this.age=age;
/* this.sayHello=function(){
alert("你好,我是"+this.name+"我今年"+this.age+"岁了");
}
*/
}
People.prototype.sayHello=function(){
alert("你好,我是"+this.name+"我今年"+this.age+"岁了");
}
var xiaoming=new People("小明",12);
var xioahong=new People("小红",11);
xiaoming.sayHello();
xiaoming.sayHello();
alert(xiaoming.sayHello==xiaohong.sayHello); //true 同一个函数
所有的属性要绑在对象身上,而所有的方法,定义在对象的原型对象中。
Javascript原型链机制
原型的construct属性
People.prototype.construct //指向构造函数
xiaoming.constructor //指向构造函数
对象的原型拥有的属性,实例对象也可以调用。
– 对象一定有原型对象
---- Object.protype 对象没有__proto__属性,该属性值为null.
– 构造函数的原型的原型是JS内置的Object对象,Object对象的构造器是function Object(){}
–xiaobai. __proto__.__proto__.constructor
----function Object(){}
------ 系统内置的构造函数
– Object.prototype是所有对象的原型链的终点。
– 所有的引用类型值,都有内置的构造函数
---- new Object() //对象
---- new Function() //函数
---- new Array() //数组
---- new RegExp() //正则
---- new Date() //日期
数组对象的原型示意图
– function函数也是对象
函数对象的示意图
案例16 原型链揭示
//数组
var arr=[45,34,23,45,65,76,45];
//我们可以利用原型链的机制,给数组对象增加方法
Array.prototype.max=function(){
var max=-Infinity;
for(var i=0;i<this.length;i++){
if(this[i]>max){
max=this[i];
}
}
return max;
}
//任何数组都能调用这个方法了
console.log(arr.max());
– 基本类型值,也有包装类型
---- 包装类型就是它的构造函数
---- new Number()
---- new String()
---- new Boolean()
面向对象的方式
在JS中面向对象技术,已经变为组织代码的方式。
案例 打气球
注意this的指向的问题
代码部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>打气球游戏</title>
<style type="text/css">
*{
margin:0;
padding:0;
}
html{
height:100%;
background: url(images/bg.jpg);
/* html5属性 */
background-size:cover;
overflow: hidden;
}
.ballon{
width:81px;
height:119px;
background:url(images/ballon.png) no-repeat;
position:absolute;
cursor:crosshair;
}
h1{
color:white;
font-size:60px;
}
</style>
</head>
<body>
<h1 id="fenshu">0</h1>
<h1 id="daojishi">50</h1>
<!-- html5属性 -->
<audio src="images/c.wav" id="yinyue"></audio>
<audio src="images/bgm.mp3" autoplay></audio>
<script type="text/javascript">
//获取元素
var oFenshu=document.getElementById("fenshu");
var oDaojishi=document.getElementById("daojishi");
var yinyue=document.getElementById("yinyue");
var fenshu=0;
var daojishi=50;
//当页面上出现功能类似,属性类型,什么都类似的东西
//应该封装成一个类
function Ballon(){
//设置top值 出现在浏览器底部
this.top=600;
//设置left值 随机值
this.left=Math.random()*1200;
//当前气球的分数值
this.score=parseInt(Math.random()*7+1);
//初始化函数
this.init();
//执行飞行方法
this.fly();
}
//初始化 往原型添加init方法
Ballon.prototype.init=function(){
//创建Dom节点,并且给这个对象的Dom属性
this.dom=document.createElement("div");
//添加节点的class
this.dom.className="ballon";
//追加 dom节点
document.body.appendChild(this.dom);
//设置样式
this.dom.style.left=this.left+"px";
this.dom.style.top=this.top+"px";
//设置背景定位,背景定位要根据自己的分数设置
//精灵图有bug,分数和自己要使用的真实的需求的那部分的气球差了1.
//精灵图向上移动,所以是负号
var x=-(this.score-1)%4*96;
var y=-parseInt((this.score-1)/4)*120;
this.dom.style.backgroundPosition=x+"px "+y+"px";
//备份this
var self=this;
//节点绑定监听
this.dom.onclick=function(){
self.bomb();
//累加分数
fenshu+=self.score;
oFenshu.innerHTML=fenshu;
//音效
yinyue.load();
yinyue.play();
}
}
//fly方法
Ballon.prototype.fly=function(){
//备份this
var self=this;
//自己有自己的定时器
this.timer=setInterval(function(){
//更改top值
self.top-=2*self.score;
//小于-100
if(self.top<-100){
self.bomb();
}
self.dom.style.top=self.top+"px";
},20);
}
//爆炸方法
Ballon.prototype.bomb=function(){
//清除定时器
clearInterval(this.timer);
//移除dom
document.body.removeChild(this.dom);
}
//new 气球对象,
var frameCount=0;
//让定时器每600毫秒一个球
var timer=setInterval(function(){
frameCount++;
if(frameCount%2==0){
daojishi--;
oDaojishi.innerHTML=daojishi;
}
if(daojishi==0){
//倒计时介绍的时候清除定时器
clearInterval(timer);
alert("GAME OVER 你的分数是"+fenshu);
}
//生成新的一个新的气球
new Ballon();
},500);
</script>
</body>
</html>
效果图