上一篇JavaScript高级学习(一)简单的复习了JS的基础知识,在复习创建对象时,由构造函数创建对象带来的问题引出原型这一词,此篇以原型开始学习。
原型
通过原型来添加方法,解决数据共享,节省内存空间
function Person(name,age) {
this.name=name;
this.age=age;
}
//通过原型来添加方法,解决数据共享,节省内存空间
Person.prototype.eat=function () {
console.log("吃凉菜");
};
var p1=new Person("小明",20);
var p2=new Person("小红",30);
console.log(p1.eat==p2.eat);//true
什么是原型?
- 实例对象中有
__proto__
这个属性,叫原型,也是一个对象,这个属性是给浏览器使用,不是标准的属性----->__proto__
----->可以叫原型对象 - 构造函数中有
prototype
这个属性,叫原型,也是一个对象,这个属性是给程序员使用,是标准的属性------>prototype
—>可以叫原型对象 - 实例对象的
__proto__
和构造函数中的prototype
相等—>true - 又因为实例对象是通过构造函数来创建的,构造函数中有原型对象
prototype
, 实例对象的__proto__
指向了构造函数的原型对象prototype
练习—利用原型实现点击按钮改变div颜色
<style type="text/css">
div{
width: 300px;
height: 200px;
background-color: red;
}
</style>
<body>
<input type="button" value="显示效果" id="btn">
<div id="dv"></div>
</body>
<script>
function ChangeStyle(btnId,dvId,json) {
this.btnObj=document.getElementById(btnId);
this.dvObj=document.getElementById(dvId);
this.json=json;
}
ChangeStyle.prototype.init=function () {
var that=this;
this.btnObj.onclick=function () {
for (var key in that.json) {
that.dvObj.style[key]=that.json[key];
}
};
};
var json={"height":"400px","width":"300px", "backgroundColor": "blue"};
var cs=new ChangeStyle("btn","dv",json);
cs.init();
</script>
点击前效果:
点击后效果:
构造函数、实例对象和原型对象之间的关系
- 构造函数可以实例化对象
- 构造函数中有一个属性叫prototype,是构造函数的原型对象
- 构造函数的原型对象(prototype)中有一个constructor构造器,这个构造器指向的就是自己所在的原型对象所在的构造函数
- 实例对象的原型对象(proto)指向的是该构造函数的原型对象
- 构造函数的原型对象(prototype)中的方法是可以被实例对象直接访问的
什么样的数据需要写在原型中?
原型的作用之一是共享数据、节省内存
所以,需要共享的数据(属性、方法)写在原型中,不需要共享的数据写在构造函数中。
简单的原型语法
function Student(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
//简单的原型写法
Student.prototype = {
//手动修改构造器的指向
constructor:Student,
height: "188",
weight: "55kg",
study: function () {
console.log("学习好开心啊");
},
eat: function () {
console.log("我要吃好吃的");
}
};
var stu=new Student("段飞",20,"男");
stu.eat();
stu.study();
console.dir(Student);
console.dir(stu);
原型对象中添加方法
原型中的方法是可以相互访问的
function Animal(name,age) {
this.name=name;
this.age=age;
}
//原型中添加方法
Animal.prototype.eat=function () {
console.log("动物吃东西");
this.play();
};
Animal.prototype.play=function () {
console.log("玩球");
this.sleep();
};
Animal.prototype.sleep=function () {
console.log("睡觉了");
};
var dog=new Animal("小苏",20);
dog.eat();
实例对象使用的属性和方法层层搜索
实例对象使用的属性或者方法,先在实例中查找,找到了则直接使用,找不到则,去实例对象的__proto__
指向的原型对象prototype
中找,找到了则使用,找不到则报错。
为内置对象添加原型方法
内置对象:全局对象、Number、Boolean、String、Array、Object、Function、Date、Math(其实除了Math及全局对象,其余的为构造函数)
ECMA-262 对内置对象的定义是:“由 ECMAScript 实现提供的、不依赖宿主环境的对象,这些对象在 ECMAScript 程序执行之前就已经存在了。”
//为Array内置对象的原型对象中添加方法
Array.prototype.mySort=function () {
for(var i=0;i<this.length-1;i++){
for(var j=0;j<this.length-1-i;j++){
if(this[j]<this[j+1]){
var temp=this[j];
this[j]=this[j+1];
this[j+1]=temp;
}//end if
}// end for
}//end for
};
var arr=[100,3,56,78,23,10];
arr.mySort();
console.log(arr);//100,78,56,23,10,3
局部变量变成全局变量
把局部变量给window就可以了
//函数自调用
(function () {
})();
//把局部变量给window就可以了
(function (win) {
var num=10;//局部变量
//js是一门动态类型的语言,对象没有属性,点了就有了
win.num=num;
})(window);
console.log(num); //10
产生随机数案例
//通过自调用函数产生一个随机数对象,在自调用函数外面,调用该随机数对象方法产生随机数
(function (window) {
//产生随机数的构造函数
function Random() {
}
//在原型对象中添加方法
Random.prototype.getRandom=function (max,min) {
return Math.floor(Math.random()*(max-min)+min);//floor向下取整
};
//把Random对象暴露给顶级对象window--->外部可以直接使用这个对象
window.Random=Random;
})(window);
var random=new Random();
console.log(random.getRandom(5,0));//floor得0,1,2,3,4
随机小方块案例
效果图:
代码:
<style type="text/css">
body{
padding: 0;
margin: 0;
}
.map{
height: 600px;
width: 800px;
background-color: #99CCFF;
position: relative;
left: 50%;
margin-left: -400px;
}
</style>
<body>
<div class="map"></div>
</body>
<script>
//产生随机数
(function (window) {
function Random() {
}
Random.prototype.getRandom=function (min,max) {
return Math.floor(Math.random()*(max-min)+min);//floor向下取整
};
window.Random=new Random();
})(window);
//食物
(function (window) {
var map=document.querySelector(".map");
//querySelector返回文档中匹配指定 CSS 选择器的一个元素
//食物的构造函数
function Food(width,height,color) {
this.width=width||20;
this.height=height||20;
this.color=color;
this.x=0;
this.y=0;
this.element=document.createElement("div");
}
//初始化小方块的样式
Food.prototype.init=function (map) {
var div=this.element;
div.style.position="absolute";
div.style.width=this.width+"px";
div.style.height=this.height+"px";
div.style.backgroundColor=this.color;
map.appendChild(div);
this.render(map);
};
//产生随机坐标
Food.prototype.render=function (map) {
var x= Random.getRandom(0,map.offsetWidth/this.width)*this.width;
var y= Random.getRandom(0,map.offsetHeight/this.height)*this.height;
this.x=x;
this.y=y;
var div=this.element;
div.style.left=this.x+"px";
div.style.top=this.y+"px";
console.log(map.offsetWidth);
};
//实例化
var food=new Food(20,20,"pink");
food.init(map);
})(window);
</script>
下一篇为:贪吃蛇案例,——面向对象的思想,原型添加方法的练习等等。
JS高级学习第三天---------原型链和继承的学习