JavaScript 基礎——快速上手
一、JavaScript簡介
1、什麼是JavaScript?
JavaScript是執行在瀏覽器上的指令碼語言。簡稱JS。 JavaScript是網景公司(NetScape)的 布蘭登·艾奇 開發的,最初叫做LiveScript。LiveScript的出現讓瀏覽器更加生動,使得頁面更具有互動性。 JavaScript(簡稱“JS”) 是一種具有函式優先的輕量級,解釋型或即時編譯型的程式語言。雖然它是作為開發Web頁面的指令碼語言而出名的,但是它也被用到了很多非瀏覽器環境中,JavaScript 基於原型程式設計、多正規化的動態指令碼語言,並且支援面向物件、命令式和宣告式(如函數語言程式設計)風格。
JavaScript在1995年由Netscape公司的Brendan Eich,在網景導航者瀏覽器上首次設計實現而成。因為Netscape與Sun合作,Netscape管理層希望它外觀看起來像Java,因此取名為JavaScript。但實際上它的語法風格與Self及Scheme較為接近。
JavaScript和java沒有任何關係,只是語法類似。JavaScript執行在瀏覽器中,程式碼由瀏覽器解釋後執行。而Java執行在JVM中。
JavaScript的“目標程式”以普通文字形式儲存,這種語言都叫做"指令碼語言“。
Java的目標程式已.class形式存在,不能使用文字編輯器開啟,不是指令碼語言。
1998年網景公司由“美國線上”公司收購。
王景公司最著名的就是“領航者瀏覽器”:Navigator瀏覽器。 LiveScript的出現,最初的時候是為Navigator瀏覽器量身定製一門語言,不支援其他瀏覽器。
微軟一看不行,研發了只支援IE瀏覽器的指令碼語言。JScript。 在兩者語言共存的時代,程式設計師需要寫兩套程式。這時一個叫做ECMA組織(歐洲計算機協會)根據JavaScript制定了ECMA-262標準,叫做ECMA-Script.
JavaScript是一種屬於網路的指令碼語言,已經被廣泛用於Web應用開發,常用來為網頁新增各式各樣的動態功能,為使用者提供更流暢美觀的瀏覽效果。通常JavaScript指令碼是通過嵌入在HTML中來實現自身的功能的。
2、JavaScript構成
-
核心(ECMAScript)
-
文件物件模型(DOM)--document Object Module
-
瀏覽器物件模型(BOM)--Browser Object Module
ECMAScript:是一種由Ecma國際(前身為歐洲計算機制造商協會,英文名稱是European Computer Manufacturers Association)通過ECMA-262標準化的指令碼程式設計語言。這種語言在全球資訊網上應用廣泛,它往往被稱為JavaScript或JScript,但實際上後兩者是ECMA-262標準的實現和擴充套件
BOM: Browse Object Model,提供與瀏覽器互動的方法和介面
DOM: Document Object Model,提供訪問和操作網頁內容的方法和介面
3、 JavaScript 使用
在Web應用程式中,JavaScript是HTML文件的一部分,它是依託 HTML 而存在的。也就是說,必須把指令碼的程式碼放在HTML文件中,否則它無法執行。JavaScript 程式可以用任何文字編輯器來編寫。
1. 行級
給標籤設定對應的屬性,屬性值是要執行的JavaScript程式碼。
<a href="javaScript:alert('你已經領取過了')">領取獎品</a>
<input type="button" value="點選有驚喜" onclick="alert('哈哈哈哈')">
2. 嵌入
使用script標籤,標籤需要閉合,標籤內容是要執行的JavaScript程式碼,格式如下:
<script>
JavaScript 語言程式碼;
</script>
注:
① 可以將JavaScript程式碼嵌入到head中或body中的任何地方。
② 含在<script>元素內部的JavaScript程式碼將被從上至下依次解釋。
3. 引入
使用script標籤,標籤需要閉合,設定屬性src,src的值是js檔案路徑,如:./js/my.js。
<script src="./js/my.js"></script>
<script src="./js/my.js"/>
注:
① 嵌入和匯入的數量不受限制;
② 使用script 標籤引入外部js檔案時(標明src屬性,不管有沒有賦值),標籤內容部分再填寫js語句是不能執行的;
③ js程式碼直接寫在一個獨立的檔案裡面,該檔案就是js檔案,字尾是.js
二、基礎語法
1、語法規範
-
區分大小寫
-
JavaScript區分大小寫,包括關鍵字、變數、函式名、所有識別符號;
-
querySelector的S是大寫,你寫成小寫就會報錯;
-
alert()全部是小寫,你寫一個大寫字母就會提示你該函式不存在;
-
myname、myName、mynamE、MyName他們真不是一個東西;
-
-
註釋
JavaScript支援兩種註釋方式;
單行註釋 //這是註釋內容 /* * 這是一個多行 * (塊級)註釋 */
-
雖然上面註釋中的第二和第三行都以一個星號開頭,但這不是必需的。之所以新增那兩個星號,純粹是為了提高註釋的可讀性(這種格式在企業級應用中用得比較多)。
-
註釋部分不會執行,合理的註釋能顯著提高程式碼的可讀性;
-
可以通過瀏覽器原始檔看到註釋內容,所以什麼該註釋什麼不該註釋要注意;
-
-
語句
ECMAScript 中的語句以一個分號結尾;如果省略分號,則由解析器確定語句的結尾,如下例所示:
var sum = a + b // 即使沒有分號也是有效的語句——不推薦 var sum = a - b; // 有效的語句——推薦
雖然語句結尾的分號不是必需的,換行也可以表示一個語句結束,但我們建議任何時候都不要省略它。這樣可以避免程式設計師犯一些低階錯誤,當然大佬也是可以忽略的,像我們這種小白還是好好寫吧!
可以使用 C 風格的語法把多條語句組合到一個程式碼塊中,即程式碼塊以左花括號({)開頭,以右花括號(})結尾:
if (test) { test = false; alert(test); }
雖然條件控制語句(如 if 語句)只在執行多條語句的情況下才要求使用程式碼塊,但最佳實踐是始終在控制語句中使用程式碼塊——即使程式碼塊中只有一條語句,例如:
if (test) alert(test); // 有效但容易出錯,不要使用 if (test) { // 推薦使用 alert(test); }
在控制語句中使用程式碼塊可以讓編碼意圖更加清晰,而且也能降低修改程式碼時出錯的機率。
-
識別符號:所謂識別符號,就是指變數、函式、屬性、引數的名字,或者用做某些迴圈語句中的跳轉位置的標記。
有以下注意事項:
-
只能由數字、字母、下劃線和美元符號($)組成;
-
合法的識別符號:myname、_age、$classname、abc、hqyj_h5;
-
不合法的識別符號:5myname;
-
-
不能以數字開頭;
-
不能是保留字和關鍵字;(下面會有介紹)
-
大小寫敏感 age 、Age 這是兩個完全不同的變數;
-
見名知意(儘量使用英文全稱),例如年齡:age 而不是a阿b的;
-
單詞個數超過兩個之後;
-
駝峰式命名 className(用的比較多);
-
下劃線命名 class_name;
-
-
2、關鍵字和保留字
ECMA-262 描述了一組具有特定用途的關鍵字,這些關鍵字可用於表示控制語句的開始或結束,或者用於執行特定操作等。按照規則,關鍵字也是語言保留的,不能用作識別符號。以下就是 ECMAScript的全部關鍵字(帶*號上標的是第 5 版新增的關鍵字):
ECMA-262 還描述了另外一組不能用作識別符號的保留字。儘管保留字在這門語言中還沒有任何特定的用途,但它們有可能在將來被用作關鍵字。以下是 ECMA-262 第 3 版定義的全部保留字:
3、變數
當程式需要將值儲存起來以備將來使用時,便將其賦值給一個變數。變數(variable)是一個用於儲存值的佔位符,可以通過變數名稱來獲得對值的引用。
變數在JavaScript中就是用一個變數名錶示,變數名是大小寫英文、數字、$和_的組合,且不能用數字開頭。變數名也不能是JavaScript的關鍵字,如if、while等。申明一個變數用var語句,比如:
var a; // 申明瞭變數a,此時a的值為undefined
var $b = 1; // 申明瞭變數$b,同時給$b賦值,此時$b的值為1
var s_007 = '007'; // s_007是一個字串
var Answer = true; // Answer是一個布林值true
var t = null; // t的值是null
在JavaScript中,使用賦值符號 = 對變數進行賦值。可以把任意資料型別賦值給變數,同一個變數可以反覆賦值,而且可以是不同型別的變數,但是要注意只能用var申明一次,例如:
var a = 123; // a的值是整數123
a = 'ABC'; // a變為字串
4、 var宣告
-
有var,系統就會在當前作用域的第一行程式碼隱式的宣告一個變數(變數提升);
-
無var,系統幫你建立一個(全域性)變數(執行到這裡的時候)。
var abc = 'Hello, world';
abcd = "abcd";
-
嚴格模式下,使用沒有var宣告的變數會報錯。
三、JavaScript資料型別
JavaScript的資料型別分類:
-
基本資料型別:Number、String、Boolean
-
特殊資料型別:NULL、Undefined、NaN
-
引用資料型別:陣列、物件、函式等
1、typeof 操作符
typeof 就是負責鑑定資料型別的操作符。
對一個值使用 typeof 操作符可能返回下列某個字串:
-
"undefined"——如果這個值未定義;
-
"boolean"——如果這個值是布林值;
-
"string"——如果這個值是字串;
-
"number"——如果這個值是數值;
-
"object"——如果這個值是物件或 null;
-
"function"——如果這個值是函式。
面試題--typeof 返回值
//返回值型別
console.log(typeof typeof 222); //string
typeof本身是字串型,這裡是一個坑要注意不要跳進去~
2、 Undefined型別
-
Undefined 型別只有一個值,即特殊的 undefined。
-
在使用 var 宣告變數但未對其沒有賦值時,這個變數的值就是 undefined
來個例子理解吧:
var message;
alert(message == undefined); //true
這個例子只聲明瞭變數 message,但未對其進行賦值。比較這個變數與 undefined 字面量,結果表明它們是相等的。
3 、Null型別
-
null型別是第二個只有一個值的資料型別,這個特殊的值是 null。
-
實際上,ECMA-262 規定對它們的相等性測試要返回 true:
alert(null == undefined); //true,僅做判斷不做字串連線時
這裡,位於 null 和 undefined 之間的相等操作符(==)總是返回 true。
null和undefined區別:
null
-
用來描述空值;
-
typeof null:返回的是字串object
undefined
-
undefined表明只聲明瞭變數沒有賦值;
-
如果函式沒有返回值,則返回undefined;
-
typeof undefined:返回的是字串undefined;
-
==認為NULL和undefined是相等的;===則返回false;
4 、Boolean型別
Boolean 型別是 ECMAScript 中使用得最多的一種型別,該型別只有兩個字面值: true 和 false。Boolean 型別的字面值 true 和 false 是區分大小寫的。
5 、Number型別
用來表示整數和浮點數值
6、 String型別
字串可以由雙引號(")或單引號(')表示,因此下面兩種字串的寫法都是有效的:
var firstColor = "pink";
var lastColor = 'blue';
字串的特點
ECMAScript 中的字串是不可變的,也就是說,字串一旦建立,它們的值就不能改變。要改變某個變數儲存的字串,首先要銷燬原來的字串,然後再用另一個包含新值的字串填充該變數。
7、Object型別
ECMAScript 中的物件其實就是一組資料和功能的集合。物件可以通過執行 new 操作符後跟要建立的物件型別的名稱來建立。
也就是說 物件=屬性+方法
如下所示:
var o = new Object;
//var o={}
//為例項新增屬性並賦值
o.name = "張三";
o.age = 24;
var o={
name:"張三",
age:24
}
也可使用大括號定義物件:
var person = {
name:'張三',
age:24,
say:function(){
console.log('大家好,我叫張三');
}
}
-
通過點(.)訪問物件的屬性:person.name;
-
通過點(.)訪問物件的方法:person.say();
四、操作符
-
A&&B A為False時,執行A,B不執行; 反之執行B。
-
A||B A為True時,執行A,B不執行; 反之執行B;
在開發中優化程式碼最常用。
-
運算子:面試題:var f1=new new Fn.rank( )( )
-
開關思想:把一個變數中儲存一個布林值,然後再業務執行時,修改這個變數的值,為取反,然後通過變數的值執行分支業務。
-
排他思想:先清除所有的效果,然後賦予自己這個效果。
-
== 雙等號 :“100”==100 值相等 但是型別不同 。引用資料比較時看記憶體空間,數值一樣不一定相等。
難點:筆試題中喜歡考 == 的比較表(背它)
var arr=[] var b='' console.log(arr==b)//True //因為轉換成了字串,所以相等 var arr=[] //這是一個記憶體空間 var arr2=[[]] //這是記憶體空間 console.log(arr==arr2) //false
-
=== 三等號 :值和型別都要相等。
-
in運算子:檢查右側物件裡面是否擁有左側屬性名,如果有返回true;反之,返回false。
例項程式碼:
var a = {x:1, y:2, z:''}; console.log(a); console.log('x' in a); console.log('z1' in a); console.log('toString' in a);
-
物件在js中是一種鍵值對的集合:key:value
-
逗號操作符多用於宣告多個變數;但除此之外,逗號操作符還可以用於賦值。在用於賦值時,逗號操作符總會返回表示式中的最後一項,如下面的例子所示:
var num = (5, 1, 4, 8, 0); // num 的值為 0
-
eval() 函式會將傳入的字串當做 JavaScript 程式碼進行執行。
-
eval()
是全域性物件的一個函式屬性。 -
eval()
的引數是一個字串。 -
如果
eval()
的引數不是字串,eval()
會將引數原封不動地返回。
看一下例子:
console.log(eval('2 + 2')); // expected output: 4 console.log(eval(new String('2 + 2'))); // expected output: 2 + 2 console.log(eval('2 + 2') === eval('4')); // expected output: true console.log(eval('2 + 2') === eval(new String('2 + 2'))); // expected output: false
-
五、語句
1、定義:
表示式-----最簡單的語句,
單語句:只有一條語句,每一個單語句結尾都要加分號;
複合語句:多條單語句組成 ; 語句組成程式。
空語句:啥都不寫 ;
2、if語句:
js的執行引擎:如果執行體只有一條語句,可以省略執行體。
if-else if -else 語句 不是js的標準語法,是程式設計師利用js引擎的糾錯功能實現的。
var a = 20;
if (a < 18) {
alert('未成年');
} else if (a > 22) {
alert('可以喝酒結婚')
} else {
alert('可以喝酒');
}
3、switch語句
switch 語句用於基於不同的條件來執行不同的動作。
使用 switch 語句來選擇要執行的多個程式碼塊之一。
語法如下:
switch(n) {
case 10: 執行程式碼塊 1
break;
case 20: 執行程式碼塊 2
break;
default: 與 case 1 和 case 2 不同時執行的程式碼
}
工作原理:首先設定表示式 n(通常是一個變數)。隨後表示式的值會與結構中的每個 case 的值做比較。如果存在匹配,則與該 case 關聯的程式碼塊會被執行。請使用 break 來阻止程式碼自動地向下一個 case 執行。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>switch語法</title>
</head>
<body>
<p>點選下面的按鈕來顯示今天是周幾:</p>
<button onclick="myFunction()">點選這裡</button>
<p id="demo"></p>
<script>
function myFunction(){
var x;
var d=new Date().getDay();
switch (d){
case 0:x="今天是星期日";
break;
case 1:x="今天是星期一";
break;
case 2:x="今天是星期二";
break;
case 3:x="今天是星期三";
break;
case 4:x="今天是星期四";
break;
case 5:x="今天是星期五";
break;
case 6:x="今天是星期六";
break;
}
document.querySelector("demo").innerHTML=x;
}
</script>
</body>
</html>
·使用 default 關鍵詞來規定匹配不存在時做的事情
switch 和 if 語句區別:
switch 更具有業務性
if語句 更具有邏輯性
4、 for語句(重要)
迴圈可以將程式碼塊執行指定的次數。
如果希望一遍又一遍地執行相同的程式碼,並且每次的值都不同,那麼使用迴圈是很方便的。
我們可以這樣輸出陣列的值:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>for迴圈</title>
</head>
<body>
<script>
cars=["BMW","Volvo","Saab","Ford"];
for (var i=0;i<cars.length;i++){
document.write(cars[i] + "<br>");
}
console.log(i)
</script>
</body>
</html>
不同型別的迴圈
JavaScript 支援不同型別的迴圈:
-
for - 迴圈程式碼塊一定的次數
-
for/in - 迴圈遍歷物件的屬性
-
while - 當指定的條件為 true 時迴圈指定的程式碼塊
-
do/while - 同樣當指定的條件為 true 時迴圈指定的程式碼塊
for迴圈
for 迴圈是在希望建立迴圈時常會用到的工具。
語法如下:
for (語句 1; 語句 2; 語句 3)
{
被執行的程式碼塊
}
for (語句 1; 語句 2;)
{
被執行的程式碼塊;
語句 3;
}
-
語句 1 (程式碼塊)迴圈開始前執行 starts.
-
語句 2 定義執行迴圈(程式碼塊)的條件
-
語句 3 在每次迴圈(程式碼塊)已被執行之後執行
考點:
//分析下面的結果 ?
//第一題
var i = 0;
for (; i++, i < 5;) {
console.log(i);
} //1 2 3 4
//第二題:閉包的作用域
var arr = [];
for (var i = 0; i < 4; i++) {
arr[i] = function () {
console.log(i)
};
}
arr[0]() //結果:4
arr[1]() //結果:4
/* 原因:
var arr=[]{
var i=0; //變成1,2,3
if(i<4){
arr[0] = function() {console.log(i)}
//不取值 函式沒有呼叫
i=i+1;
if(1<4){
arr[1] = function() {console.log(i)}
i=i+1;
...
if(4<4){
} else{跳出迴圈}
}
}
}
最後執行 arr[0]() // 其實就是i在執行過程中一直在變化 最後加到了4
*/
for (var j = 0; j < 4; j++) {
arr[j];
}
//第三題
for (var i = 0, j = 6; i < 4, j > 0; i++, j--) {
console.log(i);
} //考點:由j>0控制
//結果 j:6 5 4 3 2 1 i輸出:0 1 2 3 4 5
//for中的業務條件篩選
var arr = [{
age: 21,
name: 'karen',
rank: 580
},
{
age: 10,
name: 'jack',
rank: 380
},
{
age: 12,
name: 'marry',
rank: 540
},
{
age: 23,
name: 'rose',
rank: 880
}
]
/* //1.列印名字
for (var i = 0; i < arr.length; i++) {
console.log(arr[i].name);
} */
//2.列印大於18歲的名字
for (var i = 0; i < arr.length; i++) {
if (arr[i].age > 18) {
console.log(arr[i].name);
}
}
//3.列印年齡大於18 rank 大於480 的名字
for (var i = 0; i < arr.length; i++) {
if (arr[i].age > 18 && arr[i].rank > 480) {
console.log(arr[i].name);
}
}
//4.列印年齡小於18 rank大於400的物件的名字 拼接一個字串“少年班” 大於18 且rank大於480 的普通班 其餘的啥也不是
for (var i = 0; i < arr.length; i++) {
if (arr[i].age < 18 && arr[i].rank > 480) {
console.log(arr[i].name + '少年班');
} else if (arr[i].age >= 18 && arr[i].rank > 480) {
console.log(arr[i].name + '普通班');
} else {
console.log(arr[i].name + '啥也不是');
}
}
for迴圈巢狀思想:
-
不要管內部外部for 的執行問題,重點關注每一個for都是遍歷自己的陣列;
-
for 內部有條件語句和資料處理得到的陣列,然後用for遍歷
-
for大括號會執行陣列的元素個數這麼多次,每次執行時 i 就是元素的下標。
5、while 語句
-
語法
while (A) { 業務需要執行的程式碼 } //A判定為真,執行業務 迴圈 //A判定為假,直接結束while語句 var i=0 for(;i<len;){ //需要執行的程式碼 i++; }
-
怎樣判斷選擇while和for 迴圈?
-
while迴圈:如果有一個業務需要重複執行,但是總有一次執行會讓他停下來不再執行,不知道迴圈次數。
-
for 迴圈: 一個業務需要重複執行,但是是已知次數。
-
6、continue和break 語句
-
break 語句用於跳出迴圈。
-
continue 用於跳過迴圈中的一個迭代,繼續執行下一個迭代(如果有的話)。
break 語句舉例如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <p>點選按鈕,測試帶有 break 語句的迴圈。</p> <button onclick="myFunction()">點選這裡</button> <p id="demo"></p> <script> function myFunction(){ var x="",i=0; for (i=0;i<10;i++){ if (i==3){ break; } x=x + "該數字為 " + i + "<br>"; } document.getElementById("demo").innerHTML=x; } </script> </body> </html>
continue 語句舉例如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <p>點選下面的按鈕來執行迴圈,該迴圈會跳過 i=3 的步進。</p> <button onclick="myFunction()">點選這裡</button> <p id="demo"></p> <script> function myFunction(){ var x="",i=0; for (i=0;i<10;i++){ if (i==3){ continue; } x=x + "該數字為 " + i + "<br>";//9行 } document.getElementById("demo").innerHTML=x; } </script> </body> </html>
7、 label 語句
標籤語句,在語句之前加上冒號:可標記 JavaScript 語句。
語法如下:
label: statements
break 和 continue可以使用標籤語句。
var a = 0;
forhere:
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
if(j == 5){
break forhere;
//這裡終止的是外面的for迴圈
//體會continue、break後面加和不加語句標籤的區別;
}
a++;
}
}
console.log(a);
並且:
continue 語句(帶有或不帶標籤引用)只能用在迴圈中。
break 語句(不帶標籤引用),只能用在迴圈或 switch 中。
通過標籤引用,break 語句可用於跳出任何 JavaScript 程式碼塊:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
cars=["BMW","Volvo","Saab","Ford"];
list:{
document.write(cars[0] + "<br>");
document.write(cars[1] + "<br>");
document.write(cars[2] + "<br>");
break list;
document.write(cars[3] + "<br>");
document.write(cars[4] + "<br>");
document.write(cars[5] + "<br>");
}
</script>
</body>
</html>
8、throw丟擲異常
1.立即停止正在執行的程式,跳轉至就近的邏輯異常處理程式。
例子:
function factorial (n) {
if(isNaN(n)) throw new Error('請輸入數字,HOHO');
if(n == 1) return 1;
return n*factorial(n-1);//遞迴
}
var n = factorial(3);//3*factorial(2)--3*2*factorial(1)--3*2*1
console.log(n);//6
var n = factorial('a05');
console.log(n);
var n = factorial(5);
console.log(n);
2.throw丟擲異常該異常可以是 JavaScript 字串、數字、邏輯值或物件。
3.js語言,是指令碼語言,當執行過程終於到了錯誤就停止執行後面的程式碼。
9、try-catch-finally語句
-
try-catch-finally是JavaScript的異常處理機制。
-
語法
try{ //我們自認為沒有錯誤的 處理業務的程式碼 } catch(e){ //上面的業務處理程式碼報錯了,這裡才會執行 //console.log(e); } finally{ //這裡總是會執行的,理解為領導總結髮言 } //語句 不會影響到後面程式碼的執行。
異常物件e裡面有兩個屬性name和message,分別代表錯誤型別和錯誤描述資訊。
-
例子
try { console.log(1); throw new Error('出錯了'); console.log(2); //不會列印2 } catch (e) { console.log(e.message); //列印throw裡面的內容,裡面寫其他的字串也行 } finally { console.log(4); }
10、with語句(瞭解)
例子:
<script>
var a = 20;
var b = 10;
console.log(window.b); //window 全域性變數 可省略
var obj = {
age: 20,
name: "karen"
};
with(obj) {
console.log(name);
}
/* //我們平常使用的這裡程式碼有一個隱式操作 with(window){
} */
console.log(age); //報錯
</script>
不建議使用,語法有效能問題,es6 解決了這個問題
新技術:解構賦值
var {age,name}=obj;
console.log(age)
六、物件
JavaScript 物件是擁有屬性和方法的資料。
真實生活中的物件、屬性和方法
真實生活中,一輛汽車是一個物件。
物件有它的屬性,如重量和顏色等,方法有啟動停止等:
所有汽車都有這些屬性,但是每款車的屬性都不盡相同。
所有汽車都擁有這些方法,但是它們被執行的時間都不盡相同。
JavaScript的物件
在 JavaScript中,幾乎所有的事物都是物件。在 JavaScript 中,物件是非常重要的,當你理解了物件,就可以瞭解 JavaScript 。
已經學習了 JavaScript 變數的賦值。
var car = "Fiat";
物件也是一個變數,但物件可以包含多個值(多個變數)。
var car = {
type:"Fiat",
model:500,
color:"white"
};
在以上例項中,3 個值 ("Fiat", 500, "white") 賦予變數 car,3 個變數 (type, model, color) 賦予變數 car。
1 物件基礎
1.1 物件建立
1.物件字面量
var person1 = {
name: "bai",
age : 29,
job: "Software Engineer",
sayName: function(){
alert(this.name);
}
};
物件字面量可以用來建立單個物件,但如果要建立多個物件,會產生大量的重複程式碼。
2. 工廠模式
為了解決上述問題,人們開始使用工廠模式。該模式抽象了建立具體物件的過程,用函式來封裝以特定介面建立物件的細節
function createPerson(name,age,job){
var o = new Object();//var o={}
o.name = name;
o.age = age;
o.job = job;
o.sayname = function(){
alert(this.name);
}
return o;
}
var person1 = createPerson('bai',29,'software Engineer');
var person2 = createPerson('hu',25,'software Engineer');
3. 建構函式模式
可以通過建立自定義的建構函式,來定義自定義物件型別的屬性和方法。建立自定義的建構函式意味著可以將它的例項標識為一種特定的型別,而這正是建構函式模式勝過工廠模式的地方。該模式沒有顯式地建立物件,直接將屬性和方法賦給了this物件,且沒有return語句
function Person(name,age,job){
//var this={}
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person("bai",29,"software Engineer");
var person2 = new Person("hu",25,"software Engineer");
//具有相同作用的sayName()方法在person1和person2這兩個例項中卻佔用了不同的記憶體空間
console.log(person1.sayName == person2.sayName);//false
使用建構函式的主要問題是每個方法都要在每個例項上重新建立一遍。
4. new建立
new後面跟一個函式表示建立物件;
var obj1 = new Object();
console.log(obj1);
var obj2 = new Date();
console.log(obj2);
var obj3 = new Array();
console.log(obj3);
這裡的函式是建構函式(constructor)。
5. Object.create()建立
Object.create()的引數只能是物件或null;
用於建立一個新物件,引數是這個物件的原型(後續章節會詳細介紹原型的概念)。
var b = Object.create(new Array(14,5,6,2,3,7));
console.log(b.length);
var nu = Object.create(new String('null'));
console.log(nu[2]);
var nu = Object.create(null);
console.log(nu[2]);
2 物件方法
1. valueOf()
valueOf()方法返回當前物件原始值
var o = new Object();
o.valueOf() === o //true
console.log(new Date().valueOf())//得到XX ms(毫秒)
object 引用是任何內部 JavaScript 物件,將通過不同的方式為每個內部 JavaScript 物件定義 valueOf 方法。
2. toString()
toString()方法返回當前物件對應的字串形式
var o1 = new Object();
o1.toString()
var o2 = {a:1};
o2.toString()
//函式呼叫該方法返回的是函式本身的程式碼
function hq (argument) {
// body...
}
console.log(hq.toString());
var a = [1,2,3];
console.log(a.toString());
console.log(new Date().toString())
toString 方法是一個所有內建的 JavaScript 物件的成員。 它的行為取決於物件的型別:
Object | 行為 |
---|---|
陣列 | 將Array的元素轉換為字串,結果字串被連線起來,用逗號分隔 |
布林值 | 如果布林值為true,則返回"true",否則返回"false" |
日期 | 返回日期的文字表示形式 |
錯誤 | 返回一個包含相關錯誤資訊的字串 |
函式 | 返回如下格式的字串,其中functionName是函式的名稱 function functionName() { [native code] } |
Number | 返回數字的文字表示形式 |
字串 | 返回String物件的值 |
預設{} | 返回"[object Object]" |
附註:valueOf偏向於運算,toString偏向於顯示。
1、 在進行強轉字串型別時將優先呼叫toString方法,強轉為數字時優先呼叫valueOf。
2、 在有運算操作符的情況下,valueOf的優先順序高於toString。
七、函式
函式對任何一門語言來說都是核心的概念。通過函式可以封裝任意多條語句,而且可以在任何地方、任何時候呼叫執行。在javascript裡,函式即物件,程式可以隨意操控它們。函式可以巢狀在其他函式中定義,這樣它們就可以訪問它們被定義時所處的作用域中的任何變數,它給javascript帶來了非常強勁的程式設計能力。
1 函式概述
– 一處定義,處處呼叫;
– 如果把函式作為一個物件的屬性,則稱為方法;
– 每次呼叫函式會產生一個this:誰呼叫這個函式或者方法,this就指向誰;
– 函式就是物件,可以給他設定屬性或方法;
函式定義
總共有三種函式定義的方式:函式宣告語句、函式表示式、內建建構函式。
-
函式宣告語句
function functionName(parameters) { //執行的程式碼 }
函式聲明後不會立即執行,會在我們需要的時候呼叫到。
看一些權威函式:
function distance (x1, y1, x2, y2) { var x = x2 - x1; var y = y2 - y1; return Math.sqrt(x*x + y*y).toFixed(2); } console.log( distance(3, 5, 8, 20) );
小練習:定義一個求階乘的函式。
function fn2(n) { var s = n; var result = 1; for (var n; n >= 1; n--) { result *= n; } console.log(s + '的階乘等於' + result); } fn2(12);
-
函式表示式
var functionName = function (parameters) { //執行的程式碼 }; //函式以分號結尾,因為它實際上是一個執行語句
以上函式實際上是一個 匿名函式 (函式沒有名稱),函式儲存於變數中,故通常不加函式名。
當寫遞迴函式時,也可加上函式名。
定義一個表示式函式:
var square = function factorial(h) { if(h===1) {return 1;} else {return h*factorial(h-1);} } console.log(square(3));
-
Function內建建構函式
在以上例項中,我們瞭解到函式通過關鍵字 function 定義。
函式同樣可以通過內建的 JavaScript 函式構造器(Function())定義。
var functionName = new Function("parameters","執行的程式碼") //注意引號不可省
這種方式不推薦,無法寫遞迴。
用Function()建構函式建立一個函式時並不遵循典型的作用域,它一直把它當作是頂級函式來執行。所以,在 JavaScript 中,很多時候,你需要避免使用 new 關鍵字。
var y = "global"; function constructFunction() { var y = "local"; function test(){}; return new Function("return y"); // 無法獲取區域性變數,作用域始終是全域性作用域 } alert( constructFunction()() );
補充:函式可以巢狀在其他函式裡面,也就是在函式裡面可以定義函式(感覺半句廢話)
function distance (x1, y1, x2, y2) {
var n = 10;
function square(h) { console.log(n);return h*h;}
return Math.sqrt(square(x2-x1) + square(y2-y1)).toFixed(2);
}//
被巢狀的函式可以訪問巢狀他們的函式的變數或引數。
2 函式呼叫
javascript一共有4種呼叫模式:函式呼叫模式、方法呼叫模式、構造器呼叫模式和間接呼叫模式。
每種方式的不同在於 this 的初始化。
-
函式呼叫方式
var myfunc = function(a,b){ console.log(this); return a+b; } alert( myfunc(3,4) );
函式呼叫模式中:
a, this是指向Window的
b, 返回值是由return語句決定的,如果沒有return則表示沒有返回值
-
方法呼叫模式
先定義一個物件,然後在物件的屬性中定義方法,通過myobject.property來執行方法。
var name = "james"; var obj = { name : "wade", fn1 : function () { console.log(this.name); } }; obj.fn1(); //wade
方法呼叫模式中:
a, this 是指向呼叫該方法的物件
b, 返回值還是由return語句決定,如果沒有return表示沒有返回值
-
構造器呼叫模式
如果函式或者方法呼叫之前帶有關鍵字new,它就當成建構函式呼叫。
function Fn () { this.name = "james"; this.age = 32; console.log(this); }; var fn1 = new Fn(); //Fn整個物件 console.log(fn1); //Fn整個物件
通過上面的程式碼結果分析,會得到以下結論(建構函式呼叫模式中):
a, this是指向建構函式的例項
b, 如果沒有新增返回值的話,預設的返回值是this
但是如果手動新增返回值之後呢?
function Fn1 () { this.name = "james"; return "wade" ; }; var fn1 = new Fn1(); console.log(fn1); console.log(fn1.name); function Fn2 () { this.name = "james"; return [1,2,3]; }; var fn2 = new Fn2(); console.log(fn2); console.log(fn2.name);
而通過上面的程式碼結果分析,優化上面的結論:
a, this是指向建構函式的例項
b, 如果沒有新增返回值的話,預設的返回值是this
c, 如果有返回值,且返回值是簡單資料型別(Number,String,Boolean··)的話,最後仍回返回this
d, 如果有返回值,且返回值是複雜資料型別(物件)的話,最終返回該物件,所以上面的fn2是指向陣列,所以fn2.name為undefined
-
間接呼叫模式
也稱之為“apply、call呼叫模式” 或 “上下文呼叫模式”。
var myobject={}; var sum = function(a,b){ console.log(this); return a+b; }; var sum2 = sum.call(myobject,10,30); alert(sum2);
由之前所學,this指向由傳入的第一個引數決定。
再看看,下面函式呼叫中this指向如何呢?
function f1(){ console.log(this); } f1.call(null); f1.call(undefined); f1.call(123); f1.call("abc"); f1.call(true); f1.call([1,2,3]);
通過上面的程式碼結果分析,得出以下結論(上下文呼叫模式中):
a, 傳遞的引數不同,this的指向不同,this會指向傳入引數的資料型別
b, 返回值是由return決定,如果沒有return表示沒有返回值。
前端小白,有錯誤之處還請指正~~~