1.JavaScript基于對象的語言
JavaScript和PHP不一樣的地方在于:
- PHP是面向?qū)ο笳Z言,先有類再實(shí)例化對象;
-
JavaScript是基于對象的語言,也就是說JavaScript是由很多內(nèi)置的對象組成的編程語言;
JavaScript的主要內(nèi)置對象
1.1數(shù)組對象
對象主要是由屬性、方法組成的,所以學(xué)習(xí)數(shù)組對象就是學(xué)習(xí)數(shù)組對象提供的屬性和方法;
- length屬性,獲得數(shù)組元素的個(gè)數(shù)
- concat:連接數(shù)組生成新的數(shù)組
- join,使用指定的分隔符將數(shù)組連接成字符串
- push、pop:分別表示向數(shù)組末尾添加元素、刪除末尾的元素
- shift、unshift分別表示刪除數(shù)組第一個(gè)元素、向數(shù)組開頭添加一個(gè)元素
- reverse,顛倒數(shù)組順序
-
slice(),截取數(shù)組元素,并將截取的部分返回
參數(shù)1:開始的索引位置
參數(shù)2:結(jié)束的索引
截取字符串 -
splice() 刪除數(shù)組元素,這個(gè)方法在執(zhí)行時(shí)返回的是刪除的數(shù)組元素
參數(shù)1:開始的索引位置
參數(shù)2:刪除的元素個(gè)數(shù)
參數(shù)3:可選的,如果有參數(shù)3,表示使用參數(shù)3代替刪除的那些元素
splice方法比slice方法要強(qiáng)大一些
- toString(), 將數(shù)組轉(zhuǎn)換為字符串,該結(jié)果的返回值是修改后的字符串
1.2字符串對象
- indexOf(),獲得某個(gè)字符在字符串整體中第一次出現(xiàn)的索引
- lastIndexOf(),獲得某個(gè)字符在字符串整體中最后一次出現(xiàn)的索引
- split(),根據(jù)指定的分隔符,將字符串拆分成數(shù)組
參數(shù)1:分隔符號
參數(shù)2:限制返回的結(jié)果數(shù)量
- replace,字符串替換
參數(shù)1:正則表達(dá)式
參數(shù)2:替換的結(jié)果
- match()方法,用來根據(jù)正則表達(dá)式進(jìn)行篩選
- charAt(),用來獲得在指定索引位置的字符是什么?
參數(shù):索引位置
- slice,字符串截取
參數(shù)1:開始的索引位置
參數(shù)2:結(jié)束的索引位置
- substr()
參數(shù)1:開始的索引位置,如果正數(shù)從0開始;如果是負(fù)數(shù),從后面向前面數(shù)
參數(shù)2:截取的長度
- toLowerCase(),將字符串轉(zhuǎn)換成小寫
toUpperCase(),將字符串轉(zhuǎn)換成大寫
1.3數(shù)學(xué)對象
JavaScript給我們提供的用來進(jìn)行數(shù)學(xué)計(jì)算的對象,Math
-
Math.abs(),計(jì)算一個(gè)數(shù)值的絕對值,例如 -9的絕對值就是:9
計(jì)算一個(gè)數(shù)值的絕對值 -
Math.ceil(),向上取整,進(jìn)一取整
要注意負(fù)數(shù)的情況 Math.floor(),向下取整
- Math.round(),四舍五入取整
- max(),獲得最大值
min(),獲得最小值
- Math.pow(x,y)計(jì)算x的y次方
- Math.sqrt(),返回?cái)?shù)值的平方根
Math.random(),返回0-1之間的小數(shù),這是js中取隨機(jī)數(shù)的一種方法
1.4日期對象
說明:日期對象是JavaScript封裝的用來操作日期、時(shí)間的對象
通過new Date()獲得日期對象
- getFullYear(),獲得年份
getMonth(),獲得當(dāng)前的月份
getDate()獲得當(dāng)前的日期
getHours()獲得當(dāng)前的時(shí)間
getMinutes()獲得當(dāng)前的分鐘
getSeconds()獲得當(dāng)前的秒數(shù)
- getDay(),獲得當(dāng)前是星期幾?
- getMiliseconds()獲得當(dāng)前時(shí)間的毫秒部分:1000毫秒==1秒
\
- getTime(),獲得當(dāng)前的時(shí)間戳(單位毫秒)php時(shí)間戳的單位是(秒)
- toLocaleString(),將日期對象轉(zhuǎn)換成本地時(shí)間格式
- 設(shè)置日期:
setFullYear(),設(shè)置年份
setMonth(),設(shè)置月份
setDate(),設(shè)置日期
獲得上個(gè)月1號是星期幾?
getDay()返回的是0-6的數(shù)字,分別代表了0為星期日,6為星期六;
1.5正則表達(dá)式對象
這個(gè)在正則表達(dá)式,我有做詳細(xì)的論述
1.6DOM對象
這個(gè)在DOM操作這章我有做詳細(xì)的論述
1,7BOM對象
BOM,Browser Object Model,瀏覽器對象模型,獨(dú)立于內(nèi)容之外的,和瀏覽器進(jìn)行交互的對象(前進(jìn)、后退、地址欄、瀏覽器本身一些信息等)
BOM這個(gè)瀏覽器對象模型給我提供了如下子對象和瀏覽器進(jìn)行交互:
- location對象,操作瀏覽器地址欄
history對象,操作瀏覽器歷史記錄(前進(jìn)、后退、刷新)
history.go(-1),后退1步
history.go(-2),表示后退2步
....
history.go(1),前進(jìn)1步
history.go(0):刷新頁面
....
history.forward():前進(jìn)一步
history.back():后退1步screen對象,獲得屏幕分辨率
- navigator對象,獲得瀏覽器本身的信息
appName: 返回瀏覽器內(nèi)核名稱
appVersion: 返回瀏覽器和平臺的版本信息
platform: 返回運(yùn)行瀏覽器的操作系統(tǒng)平臺
userAgent: 返回由客戶機(jī)發(fā)送服務(wù)器的 user-agent 頭部的值
1.8 Window對象
window,指的是瀏覽器窗口,也是javascript的一個(gè)頂層對象,該對象包括DOM
、BOM,也就是說:DOM對象、BOM對象都是window的子對象
除了DOM、BOM之外,window對象還提供了一些方法供我們使用:
alert():彈出警告框
confirm(),彈出一個(gè)確認(rèn)框
參數(shù):彈出框顯示的內(nèi)容
返回布爾值,點(diǎn)擊確定返回true,點(diǎn)擊取消返回false
如果點(diǎn)擊確定,則返回true,如果點(diǎn)擊取消則返回false
- prompt(),彈出一個(gè)輸入框
//參數(shù)1:在輸入框提示的信息
//參數(shù)2:默認(rèn)值
//返回值:點(diǎn)擊確定獲得輸入框的內(nèi)容;點(diǎn)擊取消返回null
- setInterval,設(shè)置計(jì)時(shí)器(定時(shí)炸彈),每間隔指定的時(shí)間就執(zhí)行一次
- clearInterval,清除計(jì)時(shí)器
//開啟一個(gè)計(jì)時(shí)器,每間隔1秒執(zhí)行一次
//參數(shù)1:執(zhí)行的函數(shù)體
//參數(shù)2:間隔的時(shí)間,單位是毫秒
//返回值:id,將來刪除這個(gè)計(jì)時(shí)器的標(biāo)記
- setTimeout,設(shè)置延遲執(zhí)行,延遲指定的時(shí)間執(zhí)行一次
- clearTimeout,清除延遲執(zhí)行
<h1>復(fù)習(xí)部分</h1>
<h1>1.什么是變量的聲明前置?什么是函數(shù)的聲明前置?</h1>
所謂變量提升是指javaScript引擎的一種工作方式,先解析代碼,獲取所有聲明的變量,之后再一行一行的運(yùn)行,因此我們在js中先聲明變量,再給變量賦值,其運(yùn)行機(jī)制是先把變量的聲明語句提升到代碼的頭部,相當(dāng)于在代碼的預(yù)執(zhí)行階段,變量就已經(jīng)在頭部執(zhí)行了,并賦值為undefined;
而函數(shù)聲明前置,則是在函數(shù)預(yù)執(zhí)行階段,將函數(shù)聲明語句提到代碼頭部執(zhí)行,那么該函數(shù)實(shí)際在代碼正式執(zhí)行之前就已經(jīng)聲明過了,因此在js中,調(diào)用函數(shù)語句可以寫在函數(shù)聲明語句的前面.
<h1>2.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別?</h1>
<h3>首先明白怎么定義函數(shù)?</h3>
定義函數(shù)的方法有三種:
- 1.函數(shù)聲明(Function Declaration)
- 2.函數(shù)表達(dá)式(Function Expression)
- new function 構(gòu)造函數(shù),這種方式不推薦使用;
函數(shù)聲明語法格式如下:
function functionName(){ statement; } printName();
函數(shù)聲明的重要特征之一是<b>函數(shù)聲明提升</b>,意思是執(zhí)行代碼之前會讀取函數(shù)聲明,這也就意味著函數(shù)聲明可以放在調(diào)用它的語句后面,如下:
sayHi(); function sayHi(){ alert("Hi"); }
結(jié)果是返回彈窗Hi.
函數(shù)表達(dá)式語法格式如下:
var printName = function(){ console.log('Byron'); };
函數(shù)表達(dá)式的形式看起來似乎是一個(gè)常規(guī)的變量賦值語句,即將函數(shù)作為一個(gè)值賦給變量,同樣的也能夠?qū)⒑瘮?shù)作為其他函數(shù)的值返回.
<h3>那么函數(shù)表達(dá)式與函數(shù)聲明有什么區(qū)別了?</h3>
- 函數(shù)表達(dá)式可以沒有函數(shù)名,這種情況創(chuàng)建的函數(shù)稱之為匿名函數(shù);函數(shù)聲明必須要有函數(shù)名,我們試試看
聲明函數(shù)時(shí),不設(shè)置函數(shù)名會提示語法錯(cuò)誤;
-
函數(shù)表達(dá)式與函數(shù)聲明的最重要區(qū)別就在于函數(shù)聲明會提升
因?yàn)楹瘮?shù)聲明會提升,在執(zhí)行代碼之前會讀取函數(shù)聲明,想當(dāng)于在代碼執(zhí)行之前,函數(shù)聲明已經(jīng)執(zhí)行過了,而函數(shù)表達(dá)式則是代碼執(zhí)行到函數(shù)表達(dá)式之后再進(jìn)行執(zhí)行.
<h1>3.arguments 是什么?</h1>
在函數(shù)內(nèi)部可以使用arguments對象獲取到該函數(shù)的所有傳入?yún)?shù):
<h1>4.函數(shù)的"重載"怎樣實(shí)現(xiàn)?</h1>
在JavaScript中沒有函數(shù)重載的概念,函數(shù)通過名字確定唯一性,參數(shù)不同也被認(rèn)為是相同的函數(shù),后面的覆蓋前面的.
可以在函數(shù)體針對不同的參數(shù)調(diào)用執(zhí)行相應(yīng)的邏輯。如下所示:
`function printPeopleInfo(name, age, sex){
if(name){
console.log(name);
}
if(age){
console.log(age);
}
if(sex){
console.log(sex);
}
}
printPeopleInfo('Byron', 26);
printPeopleInfo('Byron', 26, 'male');`
<h1>5.立即執(zhí)行函數(shù)表達(dá)式是什么?有什么作用</h1>
立即執(zhí)行函數(shù)表達(dá)式就是(function(){})()
使用立即執(zhí)行函數(shù)表達(dá)式的作用是隔離變量,防止全局變量被污染;
<h1>6.求n!,用遞歸來實(shí)現(xiàn)</h1>
<h1>7.以下代碼輸出什么?</h1>
輸出結(jié)果應(yīng)該是:
//name:饑人谷; age:2; sex:男;name:valley;
//name:小谷; age:3; sex: undefined;name:valley;
//name:男;age: undefined; sex: undefined; name: valley;
<h1>8.寫一個(gè)函數(shù),返回參數(shù)的平方和?</h1>
平方和函數(shù)如下:
<h1>9. 如下代碼的輸出?為什么?</h1>
- 應(yīng)該是輸出undefined 以及報(bào)錯(cuò),原因在于:變量提升,a由于提到代碼頭部,被賦值undefined,因此輸出undefined,而b未定義,因此會報(bào)錯(cuò);
<h1>10. 如下代碼的輸出?為什么</h1>
- 由于函數(shù)聲明提升,而函數(shù)表達(dá)式不會提升,因此在代碼預(yù)執(zhí)行階段,函數(shù)聲明已經(jīng)提升至代碼頭部,接下來執(zhí)行階段,sayName('world')輸出helloworld,而到了執(zhí)行sayAge(10)階段,由于函數(shù)表達(dá)式相當(dāng)于還未聲明,因此會報(bào)錯(cuò),這個(gè)函數(shù)尚不存在!
<h1>11. 如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼</h1>
1.全局作用域:
globalContext = {
AO: {
x: 10;
foo: function;
bar: function;
}
Scope: null;
}
//聲明foo時(shí),得到scope屬性
foo.[[scope]] = globalContext.AO;
//聲明bar時(shí),得到scope屬性
bar[[scope]] = globalContext.AO;
2.當(dāng)調(diào)用bar()時(shí),進(jìn)入bar的執(zhí)行上下文
barContext = {
AO:{
x: 30;
}
Scope: bar.[[scope]]// bar[[scope]] = globalContext.AO
}
3.調(diào)用foo(),先從bar執(zhí)行上下文的活動(dòng)變量(AO)中找,找不到再從bar.[[scope]]中找,找到后進(jìn)行調(diào)用
4.調(diào)用foo(),進(jìn)入foo的執(zhí)行上下文
fooContext{
AO{
null
}
Scope: foo.[[scope]]//foo.[[scope]]=globalContext.AO;
}
5.在globaContext.AO中,x:10;因此調(diào)用foo()輸出為10;
6.整體調(diào)用bar[],輸出結(jié)果為10;
結(jié)果于預(yù)期一致,輸出為10;
<h1>12. 如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼</h1>
1.全局作用域
globalContext{
AO{
x:10;
bar: function;
}
Scope: null
}
//聲明函數(shù)bar得到Scope屬性
bar[[scope]] = globalContext.AO;
2.執(zhí)行bar(),進(jìn)入bar的執(zhí)行上下文
bar.Context{
AO{
x: 30;
foo : function;
}
Scope: bar[[scope]]//bar[[scope]]=globalContext.AO
}
//聲明函數(shù)foo得到其Scope屬性
foo[[scope]] = bar.context.AO;
3.執(zhí)行bar()時(shí),調(diào)用foo(),這時(shí)進(jìn)入foo的執(zhí)行上下文
foo.Context{
AO{
null;
}
Scope: foo.[[scope]];//foo.[[scope]]=bar.context.AO
}
4.執(zhí)行console.log(x),x從當(dāng)前foo.Context.AO中查找,無果,從foo.[[scope]]中查找,實(shí)質(zhì)上就是從bar.Context.AO中查找,查到x=30,因此輸出結(jié)果應(yīng)該為30;
如同預(yù)期輸出結(jié)果為30;
<h1>13. 以下代碼輸出什么? 寫出作用域鏈的查找過程偽代碼</h1>
1.全局作用域
globalContext{
AO{
x :10;
bar : function;
}
Scope: null;
}
//聲明bar函數(shù)時(shí),bar函數(shù)得到Scope屬性
bar.[[scope]] = globalContext.AO;
2.執(zhí)行bar(),進(jìn)入bar的執(zhí)行上下文
bar.Context{
AO{
x: 30;
立即執(zhí)行函數(shù)(匿名函數(shù)): function;
}
Scope: bar.[[scope]] //bar.Context=globalCotext.AO;
}
聲明立即函數(shù)時(shí),立即執(zhí)行函數(shù)得到屬性Scope
function.[[scope]] = bar.Context.AO;
3.調(diào)用立即執(zhí)行函數(shù),進(jìn)入其執(zhí)行上下文
function.Context{
AO{
null;
}
Scope: function.[[scope]];
}
4.執(zhí)行console.log(x),x從當(dāng)前執(zhí)行上下文中查找,先查function.Context.AO,無果,之后從function.[[scope]]中查找,function.[[scope]]=bar.Context.AO, 從中查找查x=30;
輸出 30;
<h1>14. 以下代碼輸出什么? 寫出作用域鏈查找過程偽代碼</h1>
1.全局作用域
globalContext{
AO{
a: 1;
fn : function;
fn3 : function;
}
Scope: null;
}
//聲明函數(shù)fn時(shí),得到其Scope屬性
fn.[[scope]] = globalContext.AO;
//聲明函數(shù)fn3時(shí),得到其Scope屬性
fn3.[[scope]] = globalContext.AO;
2.調(diào)用fn(),進(jìn)入fn的執(zhí)行上下文
fnContext{
AO{
a:5;
a:6;
fn2: function;
}
Scope: fn.[[scope]] //fn.[[scope]] = globalContext.AO
}
//聲明fn2,得到其屬性Scope
fn2.[[scope]] = fnContext.AO;
3.執(zhí)行第一個(gè)console.log(a),輸出為undefined;
4.賦值操作,a=5;
5.執(zhí)行第二個(gè)console.log(a),輸出5;
6.a++,a =6;
7.調(diào)用fn3(),進(jìn)入fn3的執(zhí)行上下文
fn3Context{
AO{
null
}
Scope: fn3.[[scope]];//fn3.[[scope]]=globalContext.AO;
}
8.執(zhí)行fn3內(nèi)部console.log(a),a搜尋當(dāng)前執(zhí)行上下文,從fn3,[[scope]]中搜尋,a=1;輸出1;之后執(zhí)行賦值操作,a=200;調(diào)用fn3完畢
9.調(diào)用fn2(),進(jìn)入fn2的執(zhí)行上下文
fn2Context{
AO{
null
}
Scope: fn2.[[scope]]//fn2.[[scope]] = fnContext.AO;
}
10.執(zhí)行fn2內(nèi)部的console.log(a),a從當(dāng)前執(zhí)行上下文中搜尋,從fn2.[[scope]]中搜尋得a=6,輸出5;之后賦值操作,a=20;調(diào)用fn2結(jié)束
11.執(zhí)行console.log(a),輸出20;調(diào)用fn()結(jié)束;
12.執(zhí)行console.log(a),此時(shí)全局變量a為200;
總的輸出: undefined,5,1,6,20,200;