js面向对象1
1.在空白的Object上加属性和方法:
<script type="text/javascript"> function createPerson(name, qq){ //构造函数 var obj = new Object(); obj.name = name; obj.qq = qq; obj.showName = function(){ alert("我的名字叫:"+this.name); } obj.showQQ=function(){ alert("我的qq号:"+this.qq); } return obj; } var obj1 = createPerson("blue","2312371239"); obj1.showName(); obj1.showQQ(); var obj2 = createPerson("shangsan","97979797872"); obj2.showName(); obj2.showQQ(); /* * 上述工厂方式创建对象的缺点:每次创建一个对象,都是自己的函数showName,showQQ,如果有很多的createPerson的话,那么就多出了很多的对象; * 会占用很多的系统内存; */ </script>
上述的createPerson叫构造函数,只是因为它的作用就是构造一个对象,和普通函数并没有什么不同;
但是这个createPerson创建对象,有两个缺点:
1.没有new关键字;
2.每次创建一个对象,每个对象上都有自己的函数,如果调用了成百上千个createPerson的话,函数大量重复,占用系统资源大,浪费。
2.先解决没有new关键字:
<script type="text/javascript"> function createPerson(name, qq){ //构造函数 //系统偷偷替咱们做: //var this = new Object(); this.name = name; this.qq = qq; this.showName = function(){ alert("我的名字叫:"+this.name); } this.showQQ=function(){ alert("我的qq号:"+this.qq); } //系统也会偷偷做一些: //return this; } var obj1 = new createPerson("blue","2312371239"); obj1.showName(); obj1.showQQ(); var obj2 = new createPerson("shangsan","97979797872"); obj2.showName(); obj2.showQQ(); </script>
3.解决资源浪费的问题;
在解决资源浪费问题之前,介绍prototype原型的概念:
原型:
CSS JS
class 一次给一组元素加样式 原型
行间样式 一次给一个元素加样式 给对象加东西
.box{background:red;}
<div class="box" style="background:green;"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
举个例子:数组是没有求和方法的,这里写一个求和方法:
<script type="text/javascript"> var arr1 = new Array(1,2,45,34); var arr2 = new Array(1,2,33); arr1.sum=function(){ var result = 0; for(var i=0; i<this.length; i++){ result+= this[i]; } return result; } alert(arr1.sum()); alert(arr2.sum()); </script>
但是只能弹出arr1的和,因为这里只是给了arr1加了sum方法,相当于行间样式一样,只是给了某一个对象单独添加了sum方法;
因此,如果要arr2也具有sum方法,这么做:
<script type="text/javascript"> var arr1 = new Array(1,2,45,34); var arr2 = new Array(1,2,33); Array.prototype.sum=function(){ var result = 0; for(var i=0; i<this.length; i++){ result+= this[i]; } return result; } alert(arr1.sum()); alert(arr2.sum()); </script>
把原型用到面向对象里面:这里把createPerson改成了Person类:
<script type="text/javascript"> function Person(name, qq){ //构造函数 this.name = name; this.qq = qq; } Person.prototype.showName= function(){ alert("我的名字叫:"+this.name); } Person.prototype.showQQ = function(){ alert("我的qq号:"+this.qq); } var obj1 = new Person("blue","2312371239"); obj1.showName(); obj1.showQQ(); var obj2 = new Person("shangsan","97979797872"); obj2.showName(); obj2.showQQ(); alert(obj1.showName == obj2.showName); //true,都有showName方法并且是同一个,因为都是来自于原型上的 </script>
用构造函数加属性;
用原型加方法;
类似于Array、Date这种,说明它不是普通的函数,是构造函数,类名首字母一般大写;所以这里改成了Person;
4.json方式的面向对象:
json:
简单
不适合多个对象
单体;
不适合Person这种需要构造很多的类;
但是适合比如ajax这种的,只需要一个发起请求的类;
Json:整个程序里只有一个;写起来比较简单;也可以用做命名空间;
比如多个叫getUser的:json.common.getUesr;json.fx.getUser; json.site.getUser等..
<script type="text/javascript"> var json = { name:'blue', qq:'11231234324', showName:function(){ alert('我的名字是:'+this.name); }, showQQ:function(){ alert('我的QQ号是:'+this.qq); } } json.showName(); json.showQQ(); </script>
5.js中的继承:
继承:父级的属性和方法
如何继承父级的属性呢?先讲下call方法;
<script type="text/javascript"> function show(){ alert(this); } //show(); //window //show.call(); //和上面一句话是完全一样的;window //但是和普通的调用又有一点区别;它可以改变里面的this //show.call(12); // 12 function show2(a, b){ alert("this是:"+this+"\na是:"+a+"\nb是:"+b); } //show2(12,5); //this是window a是12 b是5 show2.call('abc', 12, 5); //this是abc a是12 b是5 </script>
于是继承的例子:
<script type="text/javascript"> function A(){ this.abc = 12; } A.prototype.show=function(){ alert(this.abc); } //继承A function B(){ //this->new B() A.call(this); } B.prototype=A.prototype; </script>
A.call(this), B从A哪里继承了属性;
B.prototype=A.prototype;B从A那里继承了方法;
但是上面的继承可能会有点问题:
B上面可能不光有从A哪里继承来的方法,也可能会有自己的方法;
<script type="text/javascript"> function A(){ this.abc = 12; } A.prototype.show=function(){ alert(this.abc); } //继承A function B(){ //this->new B() A.call(this); } B.prototype=A.prototype; B.prototype.fn=function(){ alert('abc'); } var objB = new B(); var objA = new A(); //也能正常弹出abc,但是A上面不应该有;因为fn方法是加在B上面的; //这是因为B.prototype=A.prototype这句话是把A原型的引用赋值给B原型的; //相当于A.prototype和B.prototype指向了同一个引用,一个人去引用,A和B的prototype都变了; objA.fn(); </script>
怎么修改这个问题呢?下面:
<script type="text/javascript"> function A(){ this.abc = 12; } A.prototype.show=function(){ alert(this.abc); } //继承A function B(){ A.call(this); } for(var i in A.prototype){ B.prototype[i] = A.prototype[i]; } B.prototype.fn=function(){ alert('abc'); } //测试 var objB = new B(); var objA = new A(); objB.show(); //12 objB.fn(); //abc objA.fn(); //报错 </script>