什麼是JavaScript? 我們可以從幾個方面去說JavaScript是什麼: 基於對象 javaScript中 內置了許多對象 供我們使用【String、Date、Array】等等 javaScript也 允許我們自己自定義對象 事件驅動 當用戶觸發執行某些動作的時候【滑鼠單機、滑鼠移動】, j ...
什麼是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{
width: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{
width: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{
width: 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