此文章僅作為給新人培訓(xùn)的內(nèi)容,若有錯誤還原指正
基本語法
因為語言很多地方是相通的,所以特別基本的if else之類的就不講了。
JS以簡單靈活方便而出名,而這些所謂“靈活”的地方,卻隱藏著很多坑
主要講一下JS與其他語言不一樣、且容易出bug的地方
JS的數(shù)據(jù)類型
JS是門弱類型語言,聲明時不需要int、string之類的,只要var就可以了,至于變量的類型,JS內(nèi)部會自動進行轉(zhuǎn)化
基本數(shù)據(jù)類型包括 Number、String、Boolean、undefined、null
引用數(shù)據(jù)類型只有 Object
一、基本數(shù)據(jù)類型
弱語言類型,會隱式的自動轉(zhuǎn)化數(shù)據(jù)類型,為我們帶來很多方便,同樣也帶來一些坑
比如我們從接口那里拿到了一個計數(shù)變量 count="1";
我們運算時,想把count+2,怎么做呢
var count='1';
count+=2; //你會發(fā)現(xiàn)返回的是12,而不是3
count=2+count; //依然不對
上面的這種操作,字符串+數(shù)字,JS會自動把數(shù)字轉(zhuǎn)字符串再相加
再比如,某種情況下,接口返給我們的count是空字符串
像是
""==0
[]==""
之類的隱式轉(zhuǎn)換數(shù)據(jù)類型導(dǎo)致出bug的情況,在實際開發(fā)中也經(jīng)常遇到
- 解決方案:判斷時用===全等,運算時用強轉(zhuǎn) 如Number('1')
引用數(shù)據(jù)類型
對象(Object)是屬于引用數(shù)據(jù)類型的
所謂對象還包括數(shù)組(Array)、函數(shù)(Function)等擴展的對象
之所以叫引用數(shù)據(jù)類型,是因為它其實是一個指針,指向一個內(nèi)存地址,每次取值和改變值時,會改變內(nèi)存地址中的變量,而指針地址不改變。說下其中的坑
var a = {a:1};
var b = a;
b.a=2;
a.a //輸出2
因為上面的賦值操作,只是將a的地址傳遞給了b,也就是a和b指向的同一個內(nèi)存空間,b改變了a也會聯(lián)動。
var a = {a:1};
var b = {a:1};
a == b; //false
a.a==b.a; //true
對象的比較,其實是指針地址的比較。a和b都是全新的對象,地址不同
解決方案:
盡量不要做對象的賦值,如果賦值了,盡量只讀不寫
盡量不要用對象做比較,可以比較對象里的value
二、變量與函數(shù)
變量比如var a = 1;
不過JS可以先使用(變量提升),后定義,如
console.log(a); //打印 undefined
var a = 1;
非常不建議先使用再定義
但是要注意的是JS中,先使用后定義的都是返回undefined,而不會報錯
函數(shù)定義,一般是
function a (){
//函數(shù)體
}
也可以
var a = function(){
//函數(shù)體
}
第二種寫法不建議,見到了認識就好
函數(shù)在JS里幾乎有著一等公民的待遇,
- 函數(shù)可以先調(diào)用再定義(函數(shù)提升),函數(shù)提升和變量提升同時存在時,函數(shù)會覆蓋變量
a();//彈出1
function a (){
alert(1)
}
var a = 2;
- 變量的作用域以函數(shù)為準,而不以花括號為準
if(true){
var a = 1;
}
alert(a);//彈出1
function b(){
var a = 1;
}
b();
alert(a);//error:a is not defined
三、異步與回調(diào)
JS是單線程非阻塞的,雖然ES6中已在逐步廢棄回調(diào)這種寫法了,可是目前的項目中還是十分依賴回調(diào)的,由于OC和Java也有回調(diào)的存在,就大概講一下
一般,如果一個函數(shù)接收一個函數(shù)做為參數(shù),那么這個參數(shù)通常是回調(diào),最常見的回調(diào)是ajax
var a = 0;
setTimeout(function(){
a = 1;
},1000)
alert(a);
由于產(chǎn)生了異步,彈出的a是0
JS的API及原理還有很多,不過最特殊、最容易出坑的主要是這些了
工作相關(guān)
一般前端的工作包括
1、拿到設(shè)計稿樣式(html/CSS)
2、調(diào)用數(shù)據(jù)、發(fā)送數(shù)據(jù)(ajax)
3、渲染數(shù)據(jù)與交互(DOM)
為了更方便的做ajax和DOM操作,我們引入了zepto這個庫
一、獲取/發(fā)送 數(shù)據(jù)
如果是在H5項目中,一般是用zepto的ajax方法獲取數(shù)據(jù)
$.ajax({
type: 'GET',
url: 'http://app.t.ly.com/client/CircleLottery/GetLotteryBaseInfo',
data: {
lotterfId:'2',
memberId: '86b7070a5a6f4f3ec736f3bb98b92b65'
},
success: function(data){
alert(data)
},
error: function(xhr, type){
alert('Ajax error!')
}
})
混合項目中一般是使用bridge的
_tc_bridge_util.get_data({
param: {
"servicename": "expensesdetail",
"requrl": "http://tcmobileapi.17usoft.com/zhuanxian/IndianaHandler.ashx",
"reqbody": {
memberId: '86b7070a5a6f4f3ec736f3bb98b92b65',
expensesType:'1',
pageIndex: '0',
pageSize: '10',
}
},
callback: function (data) {
alert("callback:" + JSON.stringify(data));
}
})
JSON
我們知道,獲得的數(shù)據(jù)是個JSON字符串,而在JS中,轉(zhuǎn)換JSON字符串和對象是十分方便的
JSON.stringify(obj)//將一個JS對象轉(zhuǎn)換成JSON
JSON.parse(str)//將一個JSON字符串解析成JS對象
二、dom操作
$
獲取一個html元素
var elem = $('h1')
和CSS的選擇器一樣強大
.html
改變元素內(nèi)的內(nèi)容
可以簡單粗暴的替換掉整個元素內(nèi)的內(nèi)容
elem.html('我更改了這個標(biāo)題')
也可以只替換部分內(nèi)容
elem.html(function(idx, html){
return html.replace('標(biāo)題','部分內(nèi)容')
})
.css
動態(tài)操作元素的CSS樣式
elem.css('color', 'red')
也可以同時操作多個CSS,操作多個CSS的時候,使用對象做為參數(shù)
elem.css({ color: 'orange', fontSize: 60 })
這里注意要使用駝峰原則,如font-size
要寫成fontSize
綁定事件
做交互離不開事件,zepto綁定事件的寫法一般是用
elem.click(function(){
alert(1)
})
或者
elem.on('click',function(){
alert(1)
})
三、實際演練
先寫html結(jié)構(gòu)
<pre class="content"></pre>
<h1>點擊展開</h1>
給點CSS樣式
.content{
overflow: hidden;
height: 0;
}
一開始先獲取這兩個元素
var elem = $('h1'),
content = $('.content');
然后發(fā)送ajax請求
$.ajax({
type: 'GET',
url: 'http://app.t.ly.com/client/CircleLottery/GetLotteryBaseInfo',
data: {
lotterfId:'2',
memberId: '86b7070a5a6f4f3ec736f3bb98b92b65'
},
success: function(data){
content.html(JSON.parse(data).RuleText)//設(shè)置內(nèi)容區(qū)的內(nèi)容
},
error: function(xhr, type){
alert('Ajax error!')
}
})
寫綁定事件
elem.click(function(){
if(content.height()==0){
content.css('height','auto');
elem.html('點擊收起')
}else{
content.css('height','0');
elem.html('點擊展開')
}
})
進階:面向?qū)ο?/h2>
JS可以面向過程也可以面向?qū)ο?,如果封裝組件或者封裝工具類時,面向?qū)ο笫欠浅:糜玫?/p>
一般的業(yè)務(wù)變現(xiàn)完全可以不使用面向?qū)ο?,即使是做前端的,恐怕也有近一半的人不使用面向?qū)ο?,所以這里只稍微講一些
JS的面向?qū)ο笈c大多數(shù)語言不同,它是通過原型鏈進行繼承的
var a = {a:1}
a.__proto__ = {a:2,b:3}
a.a //1
a.b //3
構(gòu)造函數(shù)
function A(){
this.a = 1
}
A.prototype={
a:2,
b:3
}
var a = new A();
a //{a:1}
a.__proto__ //{a:2,b:3}
JS里所有復(fù)雜的繼承、多態(tài)效果都是基于上面兩條拓展的,
由于不推薦剛?cè)腴TJS的同學(xué)學(xué)習(xí),所以就不多拓展了