您现在的位置是:首页 > web开发 > JS笔记加强版3

JS笔记加强版3

web开发作者:dayu日期:10天前点击:3
JS 面向对象及组件开发

JS的面向对象:

1、什么是面向对象编程

用对象的思想去写代码,就是面向对象编程
过程式写法
面向对象写法
我们一直都在使用对象
数组 Array 时间 Date
var date = new Date();
var arr = new Array(); //[] //我们把系统自带的对象,叫做系统对象
面向对象编程(OOP)的特点
抽象:抓住核心问题
封装:只能通过对象来访问方法
继承:从已有对象上继承出新的对象
多态:多对象的不同形态

2、对象的组成

方法(行为、操作)——函数:过程、动态的
属性——变量:状态、静态的

var arr = [];
arr.number = 10; //对象下面的变量:叫做对象的属性
arr.test = function(){ //对象下面的函数 : 叫做对象的方法
alert(123);
};

arr.test(); //123

3、创建第一个面向对象程序

为对象添加属性和方法
Object对象
this指向
创建两个对象 : 重复代码过多

//var obj = {};
var obj = new Object(); //创建了一个空的对象
obj.name = ‘小明‘; //属性
obj.showName = function(){ //方法

//alert(obj.name);
alert(this.name); // this指向的就是obj

};

obj.showName(); //小明

4、工厂方式

//工厂方式 : 面向对象中的封装函数

function createPerson(name){

//1.原料
var obj = new Object();
//2.加工
obj.name = name;
obj.showName = function(){
alert( this.name );
};
//3.出场
return obj;

}

var p1 = createPerson(‘小明‘);
p1.showName();
var p2 = createPerson(‘小强‘);
p2.showName();

5、对象的引用

var a = 5;
var b = a;
b += 3;
alert(b); //8
alert(a); //5 基本类型 : 赋值的时候只是值的复制


var a = [1,2,3];
var b = a;
b.push(4);
alert(b); //[1,2,3,4]
alert(a); //[1,2,3,4] 对象类型 : 赋值不仅是值的复制,而且也是引用的传递

var a = [1,2,3];
var b = a;
b = [1,2,3,4]; // b又重新占了一个内存地址,和原来的无关
alert(b); //[1,2,3,4]
alert(a); //[1,2,3]

var a = 5;
var b = 5;
alert(a == b); //基本类型 : 值相同就可以

var a = [1,2,3];
var b = [1,2,3];
alert( a == b ); //false //对象类型 : 值和引用都相同才行

var a = [1,2,3];
var b = a;
alert( a==b ); //true

6、工厂方式,构造函数的写法:

首字母大写、New 关键字提取、This指向为新创建的对象

当new去调用一个函数 : 这个时候函数中的this就是创建出来的对象,而且函数的的返回值直接就是this(隐式返回)

构造函数:new后面调用的函数,即用来创建对象的函数,叫做构造函数

// CreatePerson()构造函数:
function CreatePerson(name){

//省略new Object和最后的return obj

this.name = name;
this.showName = function(){
alert( this.name );
};

}

var p1 = new CreatePerson(‘小明‘);
p1.showName();
var p2 = new CreatePerson(‘小强‘);
p2.showName();

alert( p1.showName == p2.showName ); //false ,值虽然相同,但是引用的 内存地址不同

存在的问题:对象的引用、浪费内存

7、原型-prototype

原型 : 重写对象方法,让相同方法在内存中存在一份。就是去改写对象下面公用的方法或者属性 , 让公用的方法或者属性在内存中存在一份 ( 提高性能 )

原型 : CSS中的class,可以重用,但优先级没style高
普通方法 : CSS中的style,不可以重用,优先级高

即原型可以重用,但优先级没有普通方法高。

var arr = [];
arr.number = 10;
Array.prototype.number = 20;

alert(arr.number); //10


普通方法:

var arr = [1,2,3,4,5];
var arr2 = [2,2,2,2,2];

arr.sum = function(){

var result = 0;
for(var i=0;i<this.length;i++){
result += this[i];
}
return result;

};
arr2.sum = function(){

var result = 0;
for(var i=0;i<this.length;i++){
result += this[i];
}
return result;

};

alert( arr.sum() ); //15
alert( arr2.sum() ); //10

原型方法 :

var arr = [1,2,3,4,5];
var arr2 = [2,2,2,2,2];

Array.prototype.sum = function(){
var result = 0;
for(var i=0;i<this.length;i++){
result += this[i];
}
return result;
};

alert( arr.sum() ); //15
alert( arr2.sum() ); //10

8、工厂方式之原型:面向对象的写法:

原型prototype : 要写在构造函数的下面

function CreatePerson(name){

this.name = name;

}

CreatePerson.prototype.showName = function(){
alert( this.name );
};

var p1 = new CreatePerson(‘小明‘);
p1.showName();
var p2 = new CreatePerson(‘小强‘);
p2.showName();

alert( p1.showName == p2.showName ); //true

总结面向对象写法:构造函数加属性,原型加方法

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



调用写法:

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


9、面向对象的例子:

原则:
1)先写出普通的写法,然后改成面向对象写法
2)普通方法变型
3)尽量不要出现函数嵌套函数
4)可以有全局变量
5)把onload中不是赋值的语句放到单独函数中

改成面向对象:
1)全局变量就是属性
2)函数就是方法
3)Onload中创建对象
4)改this指向问题
5)事件ev要放到事件函数中:
var ev = ev || window.event;
return false;




例子:面向对象的选项卡:

第一步:普通方法:

<script>

window.onload = function(){

var oParent = document.getElementById(‘div1‘);
var aInput = oParent.getElementsByTagName(‘input‘);
var aDiv = oParent.getElementsByTagName(‘div‘);

for(var i=0;i<aInput.length;i++){
aInput[i].index = i;
aInput[i].onclick = function(){

for(var i=0;i<aInput.length;i++){
aInput[i].className = ‘‘;
aDiv[i].style.display = ‘none‘;
}
this.className = ‘active‘;
aDiv[this.index].style.display = ‘block‘;
};
}

};

</script>

第二步:
先变型:
尽量不要出现函数嵌套函数
可以有全局变量
把onload中不是赋值的语句放到单独函数中



<script>

var oParent = null;
var aInput = null;
var aDiv = null;

window.onload = function(){

oParent = document.getElementById(‘div1‘);
aInput = oParent.getElementsByTagName(‘input‘);
aDiv = oParent.getElementsByTagName(‘div‘);

init();

};

function init(){
for(var i=0;i<aInput.length;i++){
aInput[i].index = i;
aInput[i].onclick = change;
}
}

function change(){
for(var i=0;i<aInput.length;i++){
aInput[i].className = ‘‘;
aDiv[i].style.display = ‘none‘;
}
this.className = ‘active‘;
aDiv[this.index].style.display = ‘block‘;
}

</script>


第三步:

全局变量就是属性
函数就是方法
Onload中创建对象
改this指向问题



<script>

window.onload = function(){

var t1 = new Tab(‘div1‘);
t1.init();
t1.autoPlay();

var t2 = new Tab(‘div2‘);
t2.init();
t2.autoPlay();

};

function Tab(id){
this.oParent = document.getElementById(id);
this.aInput = this.oParent.getElementsByTagName(‘input‘);
this.aDiv = this.oParent.getElementsByTagName(‘div‘);
this.iNow = 0;
}

Tab.prototype.init = function(){
var This = this;
for(var i=0;i<this.aInput.length;i++){
this.aInput[i].index = i;
this.aInput[i].onclick = function(){
This.change(this);
};
}
};

Tab.prototype.change = function(obj){
for(var i=0;i<this.aInput.length;i++){
this.aInput[i].className = ‘‘;
this.aDiv[i].style.display = ‘none‘;
}
obj.className = ‘active‘;
this.aDiv[obj.index].style.display = ‘block‘;
};

Tab.prototype.autoPlay = function(){

var This = this;
setInterval(function(){

if(This.iNow == This.aInput.length-1){
This.iNow = 0;
}
else{
This.iNow++;
}

for(var i=0;i<This.aInput.length;i++){
This.aInput[i].className = ‘‘;
This.aDiv[i].style.display = ‘none‘;
}
This.aInput[This.iNow].className = ‘active‘;
This.aDiv[This.iNow].style.display = ‘block‘;

},2000);

};

</script>


10、包装对象 : JS基于原型的程序、系统对象也是基于原型的程序

尽量不要去修改或者添加系统对象下面的方法和属性

基本类型都有自己对应的包装对象 : String Number Boolean

基本类型会找到对应的包装对象类型,然后包装对象把所有的属性和方法给了基本类型,然后包装对象消失


var str = ‘hello‘;

String.prototype.lastValue = function(){
return this.charAt(this.length-1);
};

alert( str.lastValue() ); // o



var str = ‘hello‘;

str.number = 10; //创建对象后,包装对象立即消失

alert( str.number ); //undefined 创建的新对象


11、原型链

原型链 : 实例对象与原型之间的连接,叫做原型链

原型链的最外层 : Object.prototype

对象调用的属性在构造函数中没有的话,会沿着原型链到该对象的prototype原型中查找,若还是没有,则沿着最外层原型链到Object.prototype中查找


function Aaa(){
this.num = 10; // 优先级最高
}
Aaa.prototype.num = 20; // 优先级第二
Object.prototype.num = 30; //优先级最后

var a1 = new Aaa();
alert(a1.num);


12、hasOwnProperty : 看是不是对象自身下面的属性

var arr = [];
arr.num = 10;
Array.prototype.num2 = 20;

alert( arr.hasOwnProperty(‘num‘) ); //true //只是arr中的属性,其余的数组对象没有

alert( arr.hasOwnProperty(‘num2‘) ); //false //数组对象原型中的属性,所有数组都有这个属性

alert( arr.hasOwnProperty == Object.prototype.hasOwnProperty ); //true // 这个属性是在最外层的Object原型上



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

function Aaa(){
}

var a1 = new Aaa();

alert( a1.constructor ); //Aaa

var arr = [];
alert( arr.constructor == Array ); //true


function Aaa(){
}
Aaa.prototype.constructor = Aaa; //每一个函数都会有的,都是自动生成的

Aaa.prototype.constructor = Array; // 修改了对象的构造函数,避免这样做


function Aaa(){
}

Aaa.prototype.name = ‘小明‘;
Aaa.prototype.age = 20;

var a1 = new Aaa();
alert( a1.constructor );

//若用JSON形式写Aaa的属性,那么a1的constructor不是Aaa了,而是JSON对象,即Object
Aaa.prototype = {
constructor : Aaa,
name : ‘小明‘,
age : 20
};



function Aaa(){
}

Aaa.prototype.name = 10;
Aaa.prototype.constructor = Aaa;

for( var attr in Aaa.prototype ){ //遍历不到JS内置属性,只能遍历到name
alert(attr);
}



14、instanceof : 对象与构造函数在原型链上是否有关系

//自定义对象
function Aaa(){
}

var a1 = new Aaa();

alert( a1 instanceof Object ); //true

//系统内置对象
var arr = [];

alert( arr instanceof Array ); //true


15、toString() :

toString() : 系统对象下面都是自带的,不需要经过原型链寻。自己写的对象都是通过原型链找Object下面的。

var arr = [];
alert( arr.toString == Object.prototype.toString ); //false

/function Aaa(){
}
var a1 = new Aaa();
alert( a1.toString == Object.prototype.toString ); //true


toString() : 把对象转成字符串

var arr = [1,2,3];

Array.prototype.toString = function(){
return this.join(‘+‘);
};

alert( arr.toString() ); //‘1+2+3‘


toString() : 进制转换
var num = 255;
alert( num.toString(16) ); //‘ff‘ //255转成16进制


利用toString做类型的判断 : (推荐)

var arr = [];

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

用constructor和instanceof判断类型在iframe中判断不出

alert( arr.constructor == Array ); //false
alert( arr instanceof Array ); //false



16、继承

继承 :在原有对象的基础上,略作修改,得到一个新的对象。不影响原有对象的功能。

子类不影响父类,子类可以继承父类的一些功能 ( 代码复用 )

1)拷贝继承:

属性的继承 : 调用父类的构造函数 call

方法的继承 : for in : 拷贝继承 (jquery也是采用拷贝继承extend)

function CreatePerson(name,sex){ //父类
this.name = name;
this.sex = sex;
}
CreatePerson.prototype.showName = function(){
alert( this.name );
};

var p1 = new CreatePerson(‘小明‘,‘男‘);
//p1.showName();


function CreateStar(name,sex,job){ //子类

CreatePerson.call(this,name,sex); //继承 call改变this指向为对象

this.job = job;

}

//不能用对象的赋值,CreateStar.prototype = CreatePerson.prototype; 都指向同一内存地址,改变其中一个,另一个也会改变

extend( CreateStar.prototype , CreatePerson.prototype );

CreateStar.prototype.showJob = function(){
};

var p2 = new CreateStar(‘黄晓明‘,‘男‘,‘演员‘);

p2.showName();


function extend(obj1,obj2){ //把父类所有的非对象属性给子类
for(var attr in obj2){
obj1[attr] = obj2[attr];
}
}




2)类式继承:

类 : JS是没有类的概念的 , 把JS中的构造函数看做的类

要做属性和方法继承的时候,要分开继承,避免子类对象之间的修改相互影响属性

属性的继承 : 调用父类的构造函数 call

方法的继承 : 利用构造函数(类)继承的方式


function Aaa(){ //父类
this.name = [1,2,3];
}
Aaa.prototype.showName = function(){
alert( this.name );
};


function Bbb(){ //子类 ,属性的继承

Aaa.call(this);

}

//方法的继承
var F = function(){};
F.prototype = Aaa.prototype; //只能继承方法
Bbb.prototype = new F();
Bbb.prototype.constructor = Bbb; //修正指向问题

var b1 = new Bbb();
b1.name.push(4);
alert( b1.name ); //[1,2,3,4]

var b2 = new Bbb();
alert( b2.name );//[1,2,3]



3)原型继承:

借助原型来实现对象继承对象

var a = {
name : ‘小明‘
};

var b = cloneObj(a);

b.name = ‘小强‘;

alert( b.name );//小强
alert( a.name );//小明

function cloneObj(obj){

var F = function(){};

F.prototype = obj;

return new F();

}


拷贝继承: 通用型的 有new或无new的时候都可以

类式继承: new构造函数

原型继承: 无new的对象

17、组件开发 : 多组对象,像兄弟之间的关系( 代码复用的一种形式 )

对面向对象的深入应用(UI组件,功能组件)
将 配置参数、方法、事件,三者进行分离


18、自定义事件 : 主要是跟函数有关系,就是让函数能够具备事件的某些特性

window.addEventListener(‘show‘,function(){
alert(1);
},false);
window.addEventListener(‘show‘,function(){
alert(2);
},false);
window.addEventListener(‘show‘,function(){
alert(3);
},false);

show(); //主动触发自定义事件

JS笔记加强版3

原文地址:http://www.cnblogs.com/hello-web/p/7221443.html


下一篇       上一篇