• JavaScript面向对象入门


    什么是JavaScript?

    我们可以从几个方面去说JavaScript是什么:

    • 基于对象
      • javaScript中内置了许多对象供我们使用【String、Date、Array】等等
      • javaScript也允许我们自己自定义对象
    • 事件驱动
      • 当用户触发执行某些动作的时候【鼠标单机、鼠标移动】,javaScript提供了监听这些事件的机制。当用户触发的时候,就执行我们自己写的代码。
    • 解释性语言
      • [x] javaScript代码是由浏览器解析的,并不需要编译。
    • 基于浏览器的动态交互技术
      • 既然javaScript是由浏览器解析的,那么它肯定要基于浏览器。 javaScript让网页变得更加“灵活""
    • 弱类型
      • [x] 像java、c++等编译型语言,要先定义变量,后使用。javaScript能够直接使用,不需要先定义

    JavaScript变量类型

    javaScript变量可分为三种类型:

    • 基本类型【number、string、boolean】
      • javaScript是弱类型语言,在运行的时候才知道具体的类型是什么。所有类型都用var来修饰。
    • 特殊类型【null、undefined】
      • 当定义了变量,没有任何赋值的时候,该变量就是undefined类型
    • 复合类型【数组、对象、函数】

    javaScript对象的类型

    在JavaScript中对象的类型可分为4种:

    • 内置对象【String、Math、Array】
    • 自定义对象【程序员自己创建的对象】
    • 浏览器对象【windows、document、history、status等等与浏览器相关的对象】
    • ActiveXObject(XMLHttpRequest)对象【异步对象,使用AJAX用到的对象,使用该对象与服务器进行异步交互】

    定义函数三种方式

    函数是属于特殊类型的一种,在另外一篇博文已经讲解了创建对象、创建类的几种方式,可参考http://blog.csdn.net/hon_3y/article/details/69362242

    值得注意的是:javaScript定义函数的时候,参数的类型是不用声明的!

    正常方式

    下面就定义了一个名称为mysum的函数

            function mysum(num1,num2){
    			return num1 + num2;
    		}
    		var myresult = mysum(100,200);
    		alert("myresult="+myresult);
    

    Function定义

    在JavaScript中, 一切皆是对象,函数也可以用一个对象来代表:Function,我们可以使用Function来创建对象:

    函数参数全都是字符串,最后一个字符串是方法体

    
    		var youresult = new Function("num1","num2","return num1+num2");
    		alert( youresult(1000,2000) );
    

    由于这种方法写起来并不好些,可读性也不太好,因此很少使用【不推荐使用】


    匿名创建函数

    其实这种和第一种差不多,只不过是将一个无名的函数赋值给一个变量。那么这个变量就代表了这个函数。

    
    
    var theyresult = function(num1,num2){
    							return num1 + num2;	
    						 }
    		alert( theyresult(10000,20000) );
    
    

    theyresult这个变量就代表了函数。


    创建对象

    方式①

    直接使用new Object()

    
      var obj = new Object();
    
    

    方式②

    使用空的{}大括号

        var obj2 = {};
    

    测试

    这里写图片描述

    增加属性,访问属性

    我们要为创建的对象增加属性和访问属性的值

    使用.操作符增加属性

    JavaScript是弱类型的语言,可以动态的添加属性。

    
        obj.age = 20;
        obj.name = "zhongfucheng";
        obj.say = function () {
            alert("hello");
        };
    
    

    测试

    这里写图片描述


    使用.操作符访问属性

    
        var aa = obj.age;
        var bb = obj.name;
    
    

    测试

    这里写图片描述


    使用[]操作符访问属性

    
        var aa = [obj["age"]];
        var bb = [obj["name"]];
    
    

    测试

    这里写图片描述


    创建类

    方式①

    使用function来模拟创建类,function充当了构造函数

    
    		//测试函数
            function test() {
    
                var teacher = new Teacher();
    
            }
    
    		//使用function来模拟类
            function Teacher() {
    
            }
    

    测试

    这里写图片描述


    方式②

    上面的function来模拟类很容易和函数混淆。

    我们一般这样做:用一个变量记住一个匿名的function当做是类,function充当了构造函数

    
            function test() {
    
                var teacher = new Teacher();
                
            }
            var Teacher = function () {
    
    
            };
    
    

    测试

    这里写图片描述


    方式③

    使用JSON语法来创建类,也就是对象直接量定义方法

    
    
            var obj = {
                age: 20,
                str: "zhongfucheng",
                method:function () {
                    alert("aaa");
                }
    
            };
    

    测试

    这里写图片描述


    公有属性和方法

    我们创建公有属性应该在类中指定,创建公有方法应该使用原型对象prototype

    prototype定义的属性就类似于Java的静态成员:在原型对象上定义了属性,拥有这个原型对象的function所创建的对象也拥有定义的属性!所以,我们方法中就使用prototype

    
            var obj = function Teacher(name) {
                this.name = name;
                if( typeof obj._init=="undefined") {
                    obj.prototype.setName = function (name) {
                        this.name = name;
                    };
    
                    obj.prototype.getName = function () {
                        alert(this.name);
                    };
                }
    
                obj._init = true;
            };
    
    

    创建两个不同的Teacher对象,name属性是不一样的。而它们共享同一份setName()和getName()方法

    这里写图片描述

    值得注意的是:prototype定义的属性只可读的。如果你想要使用具体对象写prototype的属性,实际上并不是写,而是重新为该类定义了一个同名(和prototype同名)的属性。在读取同名属性的时候,优先读取对象上的属性,而不是prototype的。


    私有属性

    我们在Java中,定义私有属性是通过关键字private来修饰的。。

    在JavaScript中是没有这样的关键字的,我们需要这样做:定义在方法内【也就是function内部,也可以看作成构造函数】的变量,就是私有变量。

    
            var obj = function Teacher(name) {
    
                //这是私有属性,外界不能访问
                var age = 23;
    
                //这是公有属性,外界可以访问
                this.name = name;
                
                //想要访问私有变量age,只能在这里编写方法来访问。其余的地方都不行!
    
    			//我们通常就是在这里编写公有方法来访问私有属性
    
            };
    
    

    静态属性和方法

    在JavaScript中定义静态属性其实就是通过prototype原型对象来定义的

    定义静态的时机:

    • 当类的某个值与对象无关期望所有位置看到的结果是一样的时候,就可以定义为类静态属性
    • 如果类的一个方法做的是和具体对象无关的操作,而是做一些工作操作的时候,就可以将这个方法定义为静态的类方法
    	//静态属性TYPE
    	Book.TYPE = “IT”;
    
    	Book.print = function(){alert(Book.TYPE);}
    
    

    JavaScript中的for in循环

    在学习AJAX的时候,发现JavaScript中for in循环,这种循环对于遍历JSON是很好用的。于是写下了这篇博文

    for in循环本质上是forEach循环,它主要有两个作用

    • 遍历数组
    • 遍历JavaScript对象

    遍历数组

    当使用for in来遍历数组的时候,它的循环计数器是数组元素的索引值

    
        var a = ['a', 'b', 'c'];
        for(var index in a) {
            alert(index);
        }
    
    
    

    效果:

    这里写图片描述

    遍历JavaScript对象

    当使用for in来遍历对象的时候,它的循环计数器是对象的属性名

    
    	//对象json上,包含了两个对象a和b属性
        var json = {a:{num:1},b:{num:2}};
    
        for(var name in  json){
            alert(name);
        }
    
    

    效果

    这里写图片描述


    JS打气球游戏

    在B站中看见了一个JS大气球这么一个教程,才知道原来JS+HTML5+CSS3能那么有趣。但是视频中没并没有给出源码。于是在别人的博客中搜到了对应的源码以及他自己实现的思路,该博主对其进行了改编。

    http://www.cnblogs.com/morang/p/7636148.html

    以上的博文有源码的下载。下面我就直接贴上源码了。思路就在博文中。

    
    <!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
    <html>
    	<head>
    		<title>气球大战</title>
    		<meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0">
    		<style>
    
    		/*CSS3能够将气球描绘出来,使用到了圆形、旋转、阴影等技术*/
    			body{margin:0px;padding:0px;}
    			#ballDiv{position: fixed;top: 0;left: 0;}
    			.balloon{
    				150px;
    				height:150px;
    				position:absolute;
    				left:0px;
    				top:0px;
    				background-color:#f3778d;
    				border-radius:50% 50% 10% 50%;
    				transform:rotate(45deg);
    				box-shadow:1px 1px 20px 20px pink inset;
    				z-index:10;
    			}
    			/*这里使用到了伪元素,可以不用到html中定义元素就可以实现功能了!*/
    			.balloon:after{
    				20px;
    				height:20px;
    				content:"";
    				display:block;
    				background:transparent;
    				position:absolute;
    				right: -15px;
    				bottom: -15px;
    				border-left:5px solid pink;
    				border-top:5px solid pink;
    			}
    			/*这里使用到了伪元素,可以不用到html中定义元素就可以实现功能了!*/
    			.balloon:before{
    					 2px;
    					height: 50px;
    					content: "";
    					display: block;
    					background: #ffc0cb;
    					position: absolute;
    					right: -10px;
    					top: 100%;
    					margin-top: -16px;
    					transform: rotate(-45deg);
    			}
    		</style>
    	</head>
    	<body>
    		<div id="gameinfo" style="transform: translateZ(360px);">
    			<p>
    				最高连击:<span id='maxDoubleHit'>0</span>				
    			</p>
    			<p>
    				本次游戏:<span id='currentDoubleHit'>0</span>				
    			</p>
    			<p id="gamemsg" style="display:none;">
    				<span style="color:red;font-weight:bold;">
    					Game Over
    				</span>
    				<button onclick="javscript:location.reload();">
    					重新开始
    				</button>
    			</p>
    		</div>
    		<div id="ballDiv">
    			
    			
    		</div>
    		<!--<div class="balloon"></div>-->
    		<script>
    			var maxDoubleHit=localStorage.getItem('eliminateCount')||0
    			var currentDoubleHit=0
    			//当做一个缓存池,优化性能的。
        		var bnElements=[];//存放所有气球
    			var random=Math.random;//随机函数
    			var wW=window.innerWidth;//窗口宽度
    			var wH=window.innerHeight;//窗口高度
    			var ballW=160;//气球的宽度
    			var ballH=300;//气球的宽度
    			var minSpeed=3;//最小速度,每次向上移动至少3px
    			var speedNum=5;//速度的定量
    			var defBnNumber=5;//初始化气球
    			var moveTimer;
    			var isEnd=false;			
    			var jindex=1;
    			var ballDiv=document.getElementById('ballDiv');
    			
    			//初始化			
    			init(defBnNumber);
    			//移动
    			move();
    			//绑定单击事件
    			bindClick();
    			
    			//游戏信息
    			document.getElementById('maxDoubleHit').innerText=maxDoubleHit
    			function record(){
    				if(isEnd){
    					clearTimeout(moveTimer);
    					bnElements=[];
    					document.getElementById('gamemsg').style.display='block';
    					document.getElementById('gameinfo').style='transform: translateZ(360px);position: fixed;top:0;left:0;z-index:999';
    				}
    				else{
    					init(1);
    					document.getElementById('currentDoubleHit').innerText=++currentDoubleHit;
    					if(currentDoubleHit>maxDoubleHit){
    						document.getElementById('maxDoubleHit').innerText=currentDoubleHit;
    						localStorage.setItem('eliminateCount',currentDoubleHit)
    					}
    				}
    			}
        		//初始化气球
    			function init(num){
    				//创建一个虚拟文档节点
    				var docFragment=document.createDocumentFragment();
    				for(var i=0;i<num;i++){
    					var bnElement=document.createElement('div');
    					bnElement.className='balloon';
    					//速度随机,限定最小值
    					var speed=Math.max(minSpeed,~~(random()*speedNum));
    					bnElement.setAttribute('speed',speed);//~~取整 移动速度
    					bnElement.setAttribute('id','ball-'+jindex++);
    					//分散排列
    					var x=(~~(random()*wW))-ballW;
    					x=Math.max(0,x);
    					bnElement.style.left=x+'px';				
    					bnElement.style.top=wH+'px';//露一点出来			
    					
    					//1.先将创建的气球放入创建的虚拟文档节点
    					docFragment.appendChild(bnElement);
    					bnElements.push(bnElement);
    				}
    				//2.将虚拟文档节点添加到body中
    				ballDiv.appendChild(docFragment);
    			}
    
    			//使用定时器来对气球进行移动。
    			function move(){
    				var bl=bnElements.length
    				for(var i=0;i<bl;i++){
    						var currentElement=bnElements[i]
    						if(currentElement==null){
    							continue;
    						}
    						var offsetTop=currentElement.offsetTop;
    					if(offsetTop>0){//窗口中
    
    							//offset就是针对窗口的位置来进行移动的。
    							var speed=currentElement.getAttribute('speed');
    							currentElement.style.top=offsetTop-speed+'px'
    						}
    						else{
    							//移除dom节点
    							//ballDiv.removeChild(currentElement);
    							//移除数组中
    							//bnElements.splice(i,1);
    							//init(1);
    							isEnd=true;
    							record();
    						}
    				}
    				moveTimer=setTimeout(move,1000/30);
    			}
    
    			//对所有的气球进行单击监听事件,不要单独为每个气球来进行监听,这样耗费性能!
    			function bindClick(){
    			
    				ballDiv.addEventListener('click',clickFunc,false);
    				function clickFunc(e){
    					if(!isEnd && e.target.className=='balloon'){
    						bnElements.splice(bnElements.lastIndexOf(e.target),1);
    
    						//这里使用call主动调用,在boom方法中我们就可以使用this指针了。
    						boom.call(e.target,function(){
    							e.target.parentNode.removeChild(e.target);
    							record();
    						});
    					}
    				}
    			}
    			function boom(callback){
    				//var that=this; //替换了上下文,但是没有使用this的意义.
    				var speed=this.getAttribute('speed');
    				this.timer=setInterval(function(){
    					this.style.opacity=0.1*(speed--)
    					if(speed<1){
    						callback&&callback();
    						clearInterval(this.timer);
    					}
    				}.bind(this),30);
    			}
    			
    		</script>
    	</body>
    </html>
    

    看了视频也学到了之前一直没有注意的东西:

    • CSS3很厉害啊,能将方形的div转成是椭圆形的[也就是气球的形状],还有盒子的阴影设置。
    • 使用伪元素就可以不用直接在html中设置标签了。配合CSS3也能够做出对应的样式。
    • 使用实体边框配合CSS3也可以做出不同的形状样式
    • 在生成元素的时候,可以先将要生成的元素加入到文档片段中,再使用文档片段来进行一次性添加到body上,这样性能会好很多!
    • 使用~~运算符能够取整数
    • 限定气球的边界就可以使用max和min函数来进行限定。这也是很好用的。
    • 移动气球我们需要用到定时器。

    • 使用call主动调用方法,把目标对象传递过去的话,我们就可以使用this指针了。
    • 在定时器中使用bind(this),就可以在定时器中使用this指针的,因为定时器默认是由浏览器window来进行调用的,默认是不能使用this的
    • 绑定单击事件的时候,不要使用循环来进行绑定,这样太耗费性能了,我们可以使用监听事件来进行一次绑定。
    • 在遍历元素数组的时候,条件是元素数组的长度时,我们可以先把该元素数组的长度初始化出来,那么也可以提升性能!不然就每次判断前都要去查询数据的长度!
    
    for(var i=0,len = array.length; i<len;i++){}
    

    如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y

  • 相关阅读:
    为知笔记 Markdown 新手指南
    如何在服务器正确的看日志呢?
    如何查看网络之间是否互通
    自定义异常以及异常的处理
    记录下工作中用到的Linux命令
    fastJson中常用方法以及遇到的“坑”
    Java语法清单-快速回顾(开发)
    kafka的简单命令
    Elasticsearch集群状态查看命令
    ElasticSearch学习文档2018.11
  • 原文地址:https://www.cnblogs.com/Java3y/p/8487892.html
Copyright © 2020-2023  润新知