web前端基礎知識-(三)JavaScript基本操作


JavaScript 是一種輕量級的編程語言。

JavaScript 是可插入 HTML 頁面的編程代碼。

JavaScript 插入 HTML 頁面后,可由所有的現代瀏覽器執行。

JavaScript 很容易學習。

一、如何編寫?

1.JavaScript代碼存在形式

<!-- 方式一 -->
<script type="text/javascript" src="JS文件"></script>
  
<!-- 方式二 -->
<script type="text/javascript">
    Js代碼內容
</script> 

2.JavaScript存放位置 

HTML 中的腳本必須位於 <script> 與 </script> 標簽之間。 

腳本可被放置在 HTML 頁面的 <body> 和 <head> 部分中。

由於Html代碼是從上到下執行,如果Head中的js代碼耗時嚴重,就會導致用戶長時間無法看到頁面,如果放置在body代碼塊底部,那么即使js代碼耗時嚴重,也不會影響用戶看到頁面效果,只是js實現特效慢而已。

這里,推薦放在body體底部;

3.注釋

JavaScript 不會執行注釋。

我們可以添加注釋來對 JavaScript 進行解釋,或者提高代碼的可讀性。

單行注釋以 // 開頭。

// 輸出標題:
document.getElementById("myH1").innerHTML="歡迎來到我的主頁";
// 輸出段落:
document.getElementById("myP").innerHTML="這是我的第一個段落。";

多行注釋以 /* 開始,以 */ 結尾。

/*
下面的這些代碼會輸出
一個標題和一個段落
並將代表主頁的開始
*/

二、變量

JavaScript中變量的聲明是一個非常容易出錯的點,局部變量必須一個 var 開頭,如果未使用var,則默認表示聲明的是全局變量。

JavaScript 變量可用於存放值(比如 x=5)和表達式(比如 z=x+y)。

var x=5;
var y=6;
var z=x+y;

變量可以使用短名稱(比如 x 和 y),也可以使用描述性更好的名稱(比如 age, sum, totalvolume)。

  • 變量必須以字母開頭
  • 變量也能以 $ 和 _ 符號開頭(不過我們不推薦這么做)
  • 變量名稱對大小寫敏感(y 和 Y 是不同的變量)

JavaScript 語句和 JavaScript 變量都對大小寫敏感。

<script type="text/javascript">
 
    // 全局變量
    name = 'seven';
 
    function func(){
        // 局部變量
        var age = 18;
 
        // 全局變量
        gender = "男"
    }
</script>

三、數據類型 

JavaScript 中的數據類型分為原始類型和對象類型:

  • 原始類型
    • 數字
    • 字符串
    • 布爾值
  • 對象類型
    • 數組
    • 字典
    • ...

1.數字

JavaScript中不區分整數值和浮點數值,JavaScript中所有數字均用浮點數值表示。

轉換:

  • parseInt(..)    將某值轉換成數字,不成功則NaN
  • parseFloat(..) 將某值轉換成浮點數,不成功則NaN

特殊值:

  •  NaN,非數字。可使用 isNaN(num) 來判斷。
  • Infinity,無窮大。可使用 isFinite(num) 來判斷。

2.字符串

字符串是由字符組成的數組,但在JavaScript中字符串是不可變的:可以訪問字符串任意位置的文本,但是JavaScript並未提供修改已知字符串內容的方法。

常見功能:

obj.length 獲取當前字符串長度
obj.trim() 移除空白
obj.trimLeft()
obj.trimRight)
obj.charAt(n) 返回字符串中的第n個字符
obj.concat(value, ...) 拼接
obj.indexOf(substring,start) 子序列位置
obj.lastIndexOf(substring,start) 子序列位置
obj.substring(from, to) 根據索引獲取子序列---起始位置,結束位置
obj.slice(start, end) 切片
obj.toLowerCase() 大寫
obj.toUpperCase() 小寫
obj.split(delimiter, limit) 分割
obj.search(regexp) 從頭開始匹配,返回匹配成功的第一個位置(g無效)
obj.match(regexp) 全局搜索,如果正則中有g表示找到全部,否則只找到第一個。
obj.replace(regexp, replacement) 替換,正則中有g則替換所有,否則只替換第一個匹配項,
$數字:匹配的第n個組內容;
$&:當前匹配的內容;
$`:位於匹配子串左側的文本;
$':位於匹配子串右側的文本
$$:直接量$符號

3.布爾類型

布爾類型僅包含真假,與Python不同的是其首字母小寫。

  • ==      比較值相等
  • !=       不等於
  • ===   比較值和類型相等
  • !==    不等於
  • ||        或
  • &&    且

4.數組

JavaScript中的數組類似於Python中的列表。

常見功能:

obj.length          數組的大小
obj.push(ele)       尾部追加元素
obj.pop()           尾部獲取一個元素
obj.unshift(ele)    頭部插入元素
obj.shift()         頭部移除元素
obj.splice(start, deleteCount, value, ...)  插入、刪除或替換數組的元素
                    obj.splice(n,0,val) 指定位置插入元素
                    obj.splice(n,1,val) 指定位置替換元素
                    obj.splice(n,1)     指定位置刪除元素
obj.slice( )        切片
obj.reverse( )      反轉
obj.join(sep)       將數組元素連接起來以構建一個字符串
obj.concat(val,..)  連接數組
obj.sort( )         對數組元素進行排序

四、小知識匯總

1. 序列化

序列化就是將JavaScript中的數據類型轉換成字符串,反序列化的過程則相反;

var a="ss";
ret = JSON.stringify(a);//序列化
console.log(ret);

console.log(JSON.parse(ret));//反序列化

結果如下:

2. 轉義

一般使用在URL中字符的轉義等,下面來看一下具體的用法

var a='http://www.baidu.com?name=民資';
console.log(encodeURI(a));
console.log(decodeURI(encodeURI(a)));
console.log(encodeURIComponent(a));
console.log(decodeURIComponent(encodeURIComponent(a)));

結果如下:

3. eval

JavaScript中的eval是Python中eval和exec的合集,既可以編譯代碼也可以獲取返回值。

console.log(eval('1+2*5')); 
console.log(eval(a = 1));    

結果如下:

4. 時間

在JavaScript中,Date對象用來表示日期和時間。JavaScript中提供了時間相關的操作,分別為獲取時間和設置時間,時間操作中分為兩種時間,統一時間(UTC),以及本地時間(東8區)

var now = new Date();
now.getFullYear(); //2016
now.getMonth(); // 月份,注意月份范圍是0~11,6表示7月
now.getDate(); // 日期
now.getDay(); // 表示星期幾
now.getHours(); // 24小時制
now.getMinutes(); // 分鍾
now.getTime(); // 以number形式表示的時間戳

結果如下:

五、循環和條件語句

1. 條件語句

  if(條件){
  
    }else if(條件){
          
    }else{
  
    }
 
 
switch(name){
        case '1':
            age = 123;
            break;
        case '2':
            age = 456;
            break;
        default :
            age = 777;
    }

2.for循環和while循環

for循環

循環時,循環的元素是索引

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <script>
        var names = ["cc", "tony", "rain"];
        for(var i=0;i<names.length;i++){
            console.log(i);
            console.log(names[i]);
        }
    </script>
</body>
</html>

執行結果:

while循環,同python中的while循環

 while(條件){
        
        
        }

五、函數

1.函數類型

JavaScript中函數基本上可以分為以下三類:普通函數,匿名函數,自執行函數。

此外需要注意的是對於JavaScript中函數參數,實際參數的個數可能小於形式參數的個數,函數內的特殊值arguments中封裝了所有實際參數。

//函數
        function func(arg){
        
            return arg+1
        }
        var result = func(1)
        console.log(result);

//普通函數:
    function func(){
        
    }
//匿名函數:
    
    function func(arg){
    
        return arg+1
    }
    
    setInterval("func()", 5000);
    
    setInterval(function(){
        console.log(123);
    
    },5000)
    
//自執行函數(創建函數並且自動執行):
    (function(arg){
        console.log(arg);
    })(1)        
//自執行函數等同於以下代碼:
    function func(arg){
        console.log(arg);
    }
    func(1)
    

2.函數作用域

作用域在許多程序設計語言中非常重要。

通常來說,一段程序代碼中所用到的名字並不總是有效/可用的,而限定這個名字的可用性的代碼范圍就是這個名字的作用域。

作用域的使用提高了程序邏輯的局部性,增強程序的可靠性,減少名字沖突。

首先,了解下其他語言的作用域:

  • 其他語言以代碼塊為作用域
public void Func(){
                        if(1==1){
                            string name = 'Java';
                            
                        }
                        console.writeline(name);
                        
                    }
                    Func()
                    // 報錯
  • python以函數作為作用域
情況一:
    def func():
        if 1==1:
            name = 'alex'
        print(name)
        
    func()
    // 成功
情況二:
    def func():
        if 1==1:
            name = 'alex'
        print(name)
        
    func()
    print(name)
    // 報錯

而javascript的作用域具有如下特點:

2.1 以函數作為作用域

先看下以下代碼:

var name='cc';
function func(){
    console.log(name);
    if(1==1){
        var name = 'dd';
    }
    console.log(name);
}
func()

第一句輸出的是:undefined,而不是cc;

第二句輸出的是:dd

大家可能認為第一句會輸出cc,因為代碼還未執行var name='dd';所以肯定會輸出cc;

上面我們已經說過,javascript是以函數作為作用域。實際上以上代碼可重新編寫:

var name='cc';
function func(){
    var name;
    console.log(name);
    if(1==1){
        var name = 'dd';
    }
    console.log(name);
}
func()

name聲明覆蓋了全局的name,但還沒有賦值,所以輸出undefined;

2.2 函數的作用域在函數未被調用之前,已經創建

function func(){
    if(1==1){
        var name = 'cc';
    }
    console.log(name);
}

2.3 函數的作用域存在作用域鏈,並且也是在被調用之前創建

我們來看第一個例子:

xo = "cc";
function func(){
    var xo = 'eric';
    function inner(){
        var xo = 'tony';
        console.log(xo);
    }
    
    inner()
}

func()

輸出:tony;

注釋掉var xo='tony';一行,輸出:eric;

同時注釋掉var xo='tony';和var xo='eric';輸出cc;

示例二:
    xo = "cc";
    
    function func(){
        var xo = 'eric';
        function inner(){
            
            console.log(xo);
        }
        
        return inner;
    }
    
    var ret = func()
    ret()

示例三:
    xo = "alex";
    
    function func(){
        var xo = 'eric';
        function inner(){
            
            console.log(xo);
        }
        var xo = 'tony';
        
        return inner;
    }
    
    var ret = func()
    ret()

2.4 函數內局部變量聲明提前

function func(){
    console.log(name);
}

func();
// 程序直接報錯

function func(){
    console.log(name);
    var name = 'cc';
}
//解釋過程中:var name;

func();
// undefined

3. javascript高級知識-詞法分析

js運行前有一個類似編譯的過程即詞法分析,詞法分析主要有三個步驟:

  • 分析參數;

  • 再分析變量的聲明;

  • 分析函數說明;

具體步驟如下:

  • 函數在運行的瞬間,生成一個活動對象(Active Object),簡稱AO;

  • 分析參數

  1. 函數接收形式參數,添加到AO的屬性,並且這個時候值為undefine,例如AO.age=undefined;

  2. 接收實參,添加到AO的屬性,覆蓋之前的undefined;

  • 分析變量聲明,如var age;或var age=23;

  1. 如果上一步分析參數中AO還沒有age屬性,則添加AO屬性為undefined,即AO.age=undefined;

  2. 如果AO上面已經有age屬性了,則不作任何修改;

  • 分析函數的聲明,如果有function age(){};把函數賦給AO.age ,覆蓋上一步分析的值;

這樣說可能大家不是很理解,下面結合具體的例子看下:

3.1 例1:

<script>
    function t1(age) {
        console.log(age);
        var age = 27;
        console.log(age);
        function age() {}
        console.log(age);
    }
    t1(3);
</script>

詞法分析階段:

1)首先形成active object對象,即AO對象;

2)第一步分析形參:

AO.age=undefined;

傳入實參即對AO.age=undefined進行覆蓋:AO.age=3;

3)第二步分析局部變量:

存在var age=27;

這個時候遵循如果AO.age存在值則不作任何修改.按照第一步分析的最后結果AO.age = 3,所以這里不作任何修改即:AO.age = 3

4)第三步:分析函數的聲明:

因為函數中存在function age(){}函數

所以按照規則應該將函數賦值給AO.age覆蓋第二步分析的AO.age = 3即:

AO.age = function age(){}

執行階段:

執行t1函數,到console.log(age)時,詞法分析的最后AO.age= function age(){},所以會打印:

function age(){}

var age=27;給age賦值27

到第二個console.log(age)這個時候age已經重新被賦值27,所以這個時候會打印:

27

function age() 並沒有調用所以並不會執行

到第三個console.log(age)這個時候age的值並沒有被再次修改,所以這個時候會打印:

27 

運行js查看結果如下與我們分析的完全相符:

3.2 代碼例子2:

function t1(age) {
        var age;
        console.log(age);
        var age = 23;
        console.log(age);
        function age() {}
        console.log(age);
    }
t1(22)

詞法分析階段:

  • 首先形成Active Object即AO對象

  • 第一步:分析形式參數

AO.age = undefine

傳入實參即對AO.age=undefine進行覆蓋:

AO.age = 22

  • 第二步:分析局部變量

第一步中最后得到AO.age = 22

所以這里var age;以及var age =23 ,因為AO.age屬性已經存在值,所以這個時候遵循如果存在則不作任何修改,即:

AO.age = 22

  • 第三步:分析函數的聲明,

因為函數中存在function age(){}函數

所以按照規則應該將函數賦值給AO.age覆蓋第二步分析的AO.age = 22即:

AO.age = function age(){}

執行階段:

執行t1函數,到console.log(age)時,詞法分析的最后AO.age= function age(){},所以會打印:

function age(){}

var age=23;給age賦值23

到第二個console.log(age)這個時候age已經重新被賦值23,所以這個時候會打印:

23

function age() 並沒有調用所以並不會執行

到第三個console.log(age)這個時候age的值並沒有被再次修改,所以這個時候會打印:

23

運行js查看結果如下與我們分析的完全相符:

3.3 代碼例子3

function t1(age) {
    var age;
    console.log(age);
    age = 23;
    console.log(age);
    function age() {
        console.log(age);
    }
    age();
    console.log(age)
}
t1(22)

詞法分析階段:

  • 首先形成Active Object即AO對象

  • 第一步:分析形式參數

AO.age = undefine

傳入實參即對AO.age=undefine進行覆蓋:

AO.age = 22

  • 第二步:分析局部變量

第一步中最后得到AO.age = 22,所以這里遵循,如果AO.age存在值則不作任何修改即:

AO.age = 22

  • 第三步:分析函數的聲明

因為函數中存在function age(){console.log(age)}函數

所以按照規則應該將函數賦值給AO.age覆蓋第二步分析的AO.age = 22即:

AO.age = function age(){console.log(age)}

執行階段:

執行t1函數,到console.log(age)時,詞法分析的最后AO.age= function age(){console.log(age)},所以會打印:

function age(){console.log(age)}

age = 23,這個時候會覆蓋原來的function age(){console.log(age)},所以第二個console.log(age)會打印:

23

function age() 是一個函數表達式,所以不會做任何操作

age() 這個時候的age還是23,並不是函數表達式,所以這里會報錯

運行js查看結果如下與我們分析的完全相符:

六、面向對象

1. 創建對象

function Foo(n){ //構造函數
    this.name = n;//this等同於python面向對象的self
    this.sayName = function(){
        console.log(this.name);
    }
}
var obj1 = new Foo('we'); //要創建對象的實例必須要用new操作符
obj1.name
obj1.sayName()
var obj2 = new Foo('wee'); //obj1 obj2都是Foo對象的實例
obj2.name
obj2.sayName()

構造函數的缺點:使用構造函數創建每個實例的時候,構造函數里的方法都要在每個實例上重新創建一遍,這樣會浪費內存;

2. 原型

為了解決上述問題,javascript引入了一個prototype-原型;

我們創建的每個函數都有一個prototype(原型)屬性,這個屬性是一個對象;

用途:包含可以由特定類型的所有實例共享的屬性和方法;

理解:prototype是通過調用構造函數創建的那個對象的原型對象;

使用原型的好處是可以讓所有對象實例共享它所包含的屬性和方法;

也就是說,不必在構造函數中定義對象信息(屬性/方法),而是可以直接將這些信息添加到原型中;

function Foo(n){
    this.name = n;
}
# Foo的原型
Foo.prototype = {
    'sayName': function(){
        console.log(this.name)
    }
}

obj1 = new Foo('we');
obj1.sayName()

obj2 = new Foo('wee');

具體可參照http://www.jb51.net/article/63876.htm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM