您的位置:首页 > 其它

面向对象小结

2015-10-09 21:03 911 查看

面向对象之
构造函数

结构:

function 构造函数() {
this.属性 = valve
}
构造函数.prototype.方法 = function() {

}
var 对象1 = new 构造函数();
对象1.方法();

eg :
function Person() {
this.name = 'bob';
}
Person.prototype.sayName = function() {
alert(this.name)
}

var p1 = new Person();
alert(p1.name);  // bob
p1.sayName();  //bob

tips : 当`new`去调用一个函数,函数中的`this`就是`new`创建出来的对象,而且函数的返回值就是`this`,也就是对象(隐式返回)


如何改写面向对象的选项卡

原则:

先写出普通的方法,再改成面向对象的写法。

1、普通的方法

(1)尽量不要出现函数嵌套函数

(2)可以有全局变量

(3)把onload中不是赋值的语句放到单独函数中。

2、改成面向对象

(1)全局变量就是属性

(2)函数就是方法

(3)onload中创建对象

(4)改this指向问题,尽量让this指向对象

eg:
<body>
<input type="button" value="选项1" class="active">
<input type="button" value="选项2">
<input type="button" value="选项3">
<div class="box1" style="display:block">内容一</div>
<div class="box2">内容二</div>
<div class="box3">内容三</div>
</body>
/*面向对象写法*/
window.onload = function(){
var t1=new Tab('tab1');
t1.init();
t1.autoPlay(2000);

var t2=new Tab('tab2'); //新弄的一个
t2.init();
t2.autoPlay(1000);
}
function Tab(id) {
this.oTaba=document.getElementById(id);
this.aInp=this.oTaba.getElementsByTagName('input');
this.aDiv=this.oTaba.getElementsByTagName('div');
this.iNow=0;
}
Tab.prototype.init = function() {
var This=this;
for (var i = 0; i < this.aInp.length; i++) {
this.aInp[i].index=i;
this.aInp[i].onclick=function() {
console.log(this)
This.change(this);
};
};
}
Tab.prototype.change = function(obj) {
for (var i = 0; i < this.aInp.length; i++) {
this.aInp[i].className='';
this.aDiv[i].className='';
};
obj.className='active';
this.aDiv[obj.index].className='active';
};

Tab.prototype.autoPlay = function (time){
var This=this;
setInterval(function(){
This.iNow++;
if (This.iNow == This.aInp.length) {
This.iNow=0;
};
for (var i = 0; i < This.aInp.length; i++) {
This.aInp[i].className='';
This.aDiv[i].className='';
};
This.aInp[This.iNow].className='active';
This.aDiv[This.iNow].className='active';
},time)
}


包装对象

1、系统对象也是基于原型
prototype
的程序

2、基本类型都有自己对应的包装对象 : String 、 Number、 Boolean(除了null 和 undefined)

var str = 'abc';
str.charAt(0);  //基本类型会找到对应的包装对象,包装对象把所有的属性和方法给了基本类型,然后包装对象消失


原型链

1 、实例对象与原型之间的链接,叫做原型链。最外层是Object.prototype

2、proto(原型链,隐式连接) ,先找普通方法,再找原型。最后找最外层

3、Object对象类型时原型链的最外层

面向对象的一些属性和方法

1、hasOwnPrototype(); 看是不是自身下面的属性和方法,不会查找原型下面的属性和方法

2、constructor : 查看对象的构造函数。

function Person() {

}
Person.prototype.name = 'Bob';
Person.prototype.age = 100;
Person.prototype.constructor = Person  //自动生成,不要手动添加
var p1 = new Person();
alert( p1.constructor )  //function Person() {}

/** tips :写成对象字面量时 指向问题  **/
function Person() {

}
Person.prototype = {
name : 'Bob',
age : 100
}
var p1 = new Person();
alert( p1.constructor )  //function Object() {[native code]}

解决办法 :手动修改指向
Person.prototype = {
constructor  : Person,
name : 'Bob',
age
1629e
: 100
}


3、for in

找不到系统自带的属性,比如constructor,自己写constructor也找不到

4、instanceof : 运算符,对象与构造函数在原型链上是否有联系,任何对象instanceof Object 都是true

5、toString : Object上的方法,也可用作类型的判断(最靠谱);系统对象下面都是自带的,写在构造函数prototype下的,自己写的都是通过原型链找Object下面的(Object.prototype)

var arr = [];
alert( Object.prototype.toString.call(arr) ) // '[object Array]'


继承

概念 : 在原有对象的基础上,略作修改,得到一个新的对象,并且不影响原有对象

常用的继承方式:

属性的继承 : call

方法的继承 :for in (浅复制与深复制)

function Person (name,age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function () {
alert(this.name)
}
Person.prototype.sayAge = function () {
alert(this.age)
}
function Start (name, age, job) {
Person.call(this,name,age); //属性继承
this.job = job;
}
extend(Start.prototype,Person.prototype); //方法继承,浅复制
Start.prototype.sayJob = function () {
alert(this.job);
}

function extend (obj1,obj2) {
for (var attr in obj2) {
obj1[attr] = obj2[attr]
}
}
var s1 = new Start('黄晓明',20,'stat');
s1.sayAge();
s1.sayJob();

var p1 = new Person('小球',100);
alert(p1.name);


继承的其他方式

1、类式继承 : 利用构造函数继承的方式

类 : js是没用类概念的,把构造函数看做是类

子构造函数.prototype = new 父构造函数  //继承的属性和方法


存在的问题 : ,

(1)constructor的指向问题 (需手动指向)

(2)实例1 的属性方法修改会影响 实例2 (想想原型链的查找 , 属性和方法分开继承)

function Person1(name) {
this.name = name;
this.job = 'worker';
}
Person1.prototype.sayName = function() {
alert(this.name);
}
Person1.prototype.sayJob = function() {
alert(this.job);
}
function Person2(name,age) {
Person1.call(this,name,age); //继承属性
this.age = age;
this.job = 'student';
}

/** 下面四行重点,前三行继承方法,第四行解决指向问题 **/
var F = function(){};
F.prototype = Person1.prototype;
Person2.prototype = new F();
Person2.prototype.constructor = Person2;

Person2.prototype.sayAge = function() {
alert(this.age);
}

var p1 = new Person2('小强','255');
alert(p1.name);
p1.sayName();
p1.sayAge();


2、原型继承 : 借助原型来实现对象继承对象

function Person() {
this.name = 'bob';
this.job = 'worker';
}
Person.prototype.sayName = function() {
alert(this.name);
}
Person.prototype.sayJob = function() {
alert(this.job);
}

var p2 = cloneObj(Person);
p2.name = 'xiaohua';
p2.age = 289;
p2.sayName();
function cloneObj(obj) {
var F = function(){};
F.prototype = obj.prototype;

return new F();
}


组件开发

组件开发 : 多组对象,像兄弟之间的关系,代码复用(UI组件,功能组件)

默认参数 : 写在构造函数中,普通方法

配置参数 : 写在参数中

//组件开发弹出框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
* {margin: 0;padding: 0}
.loading1 {border: 1px solid #000;position: absolute;left: 0;top: 0;z-index: 10}
.loading1 p {width: 100%;height: 40px;background: #0cf}
.loading1 p .close {float: right;}
#mark {width: 100%; height: 100%; position: absolute; left: 0; top: 0; background: rgba(0,0,0,.4);}
</style>
<script type="text/javascript">
window.onload = function() {
var aInp = document.getElementsByTagName('input');

aInp[0].onclick = function() {
var l1 = new Load();
l1.init({
iNow : 1,
drag : true
})
}

aInp[1].onclick = function() {
var l2 = new Load();
l2.init({
iNow : 2,
w : '100',
h : '400',
dir : 'right',
title : '广告'
});
}

aInp[2].onclick = function() {
var l3 = new Load();
l3.init({
iNow : 3,
title : '推广',
mark : true
})
}

}
function Load() {
this.obj = null;
this.mark = null;
this.disX = 0;
this.disY = 0;
this.settings = {
w : '300',
h : '300',
dir : 'center',
title : '登陆',
mark : false,
toDown : function(){},
toMove : function(){},
toUp : function(){}
}
}
Load.prototype.json = {}; // 处理多次点击多次添加的问题
Load.prototype.init = function(opt) {
var This = this;
extend(this.settings , opt);

if (this.json[opt.iNow] == undefined) {
this.json[opt.iNow] = true;
}
if (this.json[opt.iNow]) {
this.cresteData();

this.json[opt.iNow] = false;
};

}
Load.prototype.cresteData = function() {

this.obj = document.createElement('div');
this.obj.className = 'loading1';
this.obj.innerHTML = '<p><span>登陆</span><span class="close">X</span></p>';

document.body.appendChild(this.obj);
this.fnMark();
this.setData();
this.drag();
this.fnClose();
}

Load.prototype.setData = function() {
var oTitle = this.obj.getElementsByTagName('span')[0];
this.obj.style.width = this.settings.w + 'px';
this.obj.style.height = this.settings.h + 'px';
oTitle.innerHTML = this.settings.title;
if ( this.settings.dir == 'center' ) {
this.obj.style.left = ( viewWidth() - this.obj.offsetWidth )/2 + 'px';
this.obj.style.top = ( viewHeight() - this.obj.offsetHeight )/2 + 'px';
}else if ( this.settings.dir == 'right' ) {
this.obj.style.left = ( viewWidth() - this.obj.offsetWidth ) + 'px';
this.obj.style.top = ( viewHeight() - this.obj.offsetHeight ) + 'px';
}
}

Load.prototype.fnClose = function() {
var This = this;
var oClose = this.obj.getElementsByTagName('span')[1];
oClose.onclick = function (){
document.body.removeChild( This.obj );
This.json[This.settings.iNow] = true;
console.log( This.settings )
if ( This.settings.mark ) {
document.body.removeChild( This.mark );
};
}
}

Load.prototype.fnMark = function() {
if (this.settings.mark == true ) {
this.mark = document.createElement('div');
this.mark.id = 'mark';
document.body.appendChild(this.mark)
};
}
Load.prototype.drag = function (){
var This = this;
if (this.settings.drag) {
this.obj.onmousedown = function(ev) {
var ev = ev || window.event;
This.fnDown(ev);
// This.settings.toDown();
return false;

}
};

}
Load.prototype.fnDown = function(ev) {
var This=this;
this.disX = ev.clientX - this.obj.offsetLeft;
this.disY = ev.clientY - this.obj.offsetTop;
document.onmousemove = function(ev) {
var ev = ev || window.event;
This.fnMove(ev);
// This.default.toMove();
}
document.onmouseup = function(ev) {
var ev = ev || window.event;
This.fnUp();
// This.default.toUp();

}
}
Load.prototype.fnMove = function(ev) {
var iLeft = ev.clientX - this.disX;
var iTop = ev.clientY - this.disY;
if (iLeft < 0) {
iLeft = 0;
}else if (iLeft > viewWidth()-this.obj.offsetWidth) {
iLeft = viewWidth()-this.obj.offsetWidth;
}
this.obj.style.left = iLeft + 'px';
this.obj.style.top = iTop + 'px';
}
Load.prototype.fnUp = function() {
document.onmousemove = null;
document.onmouseup = null;
}
function extend (obj1,obj2) {
for(var attr in obj2){
obj1[attr] = obj2[attr]
}
}
function viewWidth() {
return document.documentElement.clientWidth;
}
function viewHeight() {
return document.documentElement.clientHeight;

}
</script>
</head>
<body>
<input type="button" value="1" />
<input type="button" value="2" />
<input type="button" value="3" />
<!-- <div class="loading1">
<p><span>登陆</span><span class="close">X</span></p>
</div> -->
<!-- <div id="mark"></div> -->
</body>
</html>


//组件开发选项卡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
#tab1,#tab2,#tab3 {width: 300px;height: 300px;}
#tab1 div,#tab2 div,#tab3 div {width: 300px;height: 200px;border: 1px solid #000;display: none;}
input {width: 60px;height: 30px;}
.active {background: red}

</style>
<script type="text/javascript">
window.onload = function() {
var t1 = new Tab();
t1.init({
id : 'tab1',
events : 'onclick'
});

var t2 = new Tab();
t2.init({
id : 'tab2',
events : 'onmouseover'
})
t2.delay();

var t3 = new Tab();
t3.init({
id : 'tab3',
events : 'onmouseover'
});
t3.setIndex(1);

}
function Tab() {
this.obj = null;
this.aBtn = null;
this.aBox = null;
this.timer = null;
this.settings = {
events : 'onclick'
}
}
Tab.prototype.init = function(opt) {
extend(this.settings,opt)
this.obj = document.getElementById(opt['id']);
this.aBtn = this.obj.getElementsByTagName('input');
this.aBox = this.obj.getElementsByTagName('div');
this.change();

}
Tab.prototype.change = function() {
var This = this;
for (var i = 0; i < This.aBtn.length; i++) {
This.aBtn[i].index = i;
This.aBtn[i][This.settings.events] = function() {
var _this = This;
for (var i = 0; i < _this.aBtn.length; i++) {
_this.aBtn[i].className = '';
_this.aBox[i].style.display = 'none';
};
this.className = 'active';
_this.aBox[ this.index ].style.display = 'block';

}
};
}
Tab.prototype.delay = function() {
var This = this;
for (var i = 0; i < this.aBtn.length; i++) {
this.aBtn[i].index = i;

this.aBtn[i].onmouseout = function() {
clearTimeout(This.timer);
}

this.aBtn[i][this.settings.events] = function() {
var _index = this.index;

This.timer = setTimeout(function(){
toDelay(_index)
},200)

}
}
function toDelay(index) {
for (var i = 0; i < This.aBtn.length; i++) {
This.aBtn[i].className = '';
This.aBox[i].style.display = 'none';
};
This.aBtn[index].className = 'active';
This.aBox[index ].style.display = 'block';
}

}
Tab.prototype.setIndex = function(index) {
for (var i = 0; i < this.aBtn.length; i++) {
this.aBtn[i].className = '';
this.aBox[i].style.display = 'none'
};
this.aBtn[index].className = 'active';
this.aBox[index].style.display = 'block'
}
function extend(obj1,obj2) {
for(var attr in obj2) {
obj1[attr] = obj2[attr]
}
}
</script>
</head>
<body>
<div id="tab1">
<input type="button" value="1" class="active" />
<input type="button" value="2" />
<input type="button" value="3" />
<div style="display: block;">111111111</div>
<div>22222222</div>
<div>33333333</div>
</div>
<div id="tab2">
<input type="button" value="1" class="active" />
<input type="button" value="2" />
<input type="button" value="3" />
<div style="display: block;">111111111</div>
<div>22222222</div>
<div>33333333</div>
</div>
<div id="tab3">
<input type="button" value="1" class="active" />
<input type="button" value="2" />
<input type="button" value="3" />
<div style="display: block;">111111111</div>
<div>22222222</div>
<div>33333333</div>
</div>
</body>
</html>


自定义事件 :

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
window.onload = function () {
var oDiv = document.getElementById('div1');
var oSpan = document.getElementById('span1');

bindEvent(oDiv,'click',function(){
alert(1)
});

bindEvent(oDiv,'click',function(){
alert(2)
});

bindEvent(oSpan,'show',function(){
alert(3)
});

bindEvent(oSpan,'show',function(){
alert(4)
});

bindEvent(oSpan,'hide',function(){
oSpan.style.background = 'red';
});

fireEvenet(oSpan,'hide')
function bindEvent(obj,events,fn) {  //不完善,比如this指向
// obj :图书馆的楼层
// events :图书的分类(书架)
// fn :一本书

obj.listener = obj.listener || {};
obj.listener[events] = obj.listener[events] || [];
obj.listener[events].push(fn);

if (obj.addEventListener) {
obj.addEventListener(events,fn,false)
}else{
obj.attachEvent('on'+events,fn)
}

}

function fireEvenet(obj,events) { //主动触发函数
for (var i = 0; i < obj.listener[events].length; i++) {
console.log(obj.listener[events])
obj.listener[events][i]();
};
}
}
</script>
</head>
<body>
<div id="div1">div</div>
<span id="span1">span</span>
</body>
</html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息