1. 程式人生 > >JavaScript基礎函式和詞法分析以及常用的內建物件和使用方法(4)

JavaScript基礎函式和詞法分析以及常用的內建物件和使用方法(4)

day52

參考:https://www.cnblogs.com/liwenzhou/p/8004649.html

函式

函式定義

JavaScript中的函式和Python中的非常類似,只是定義方式有點區別。

function foo(a, b) {
    console.log("a:", a)
    console.log("b:", b)

    return a+b;
};

//匿名函式
var func = function (a, b){
    console.log("a:", a);
    console.log("b:", b);
    return a+b;
};

//立即執行函式 (function (a, b) { console.log("立即執行函式"); console.log(a+b); })(11, 22); console.log("================================================="); //函式呼叫 var ret = foo(11, 22); console.log("a+b=", ret); func(11,33);

 

函式中的arguments引數

//arguments
function foo2(a, b) {

    console.log(
"總共有" + arguments.length + "個引數");//引數的個數 var ret = 0; for (var i = 0; i<arguments.length; i++) { ret += arguments[i] } return ret; }; console.log(foo2(11, 22))

 

函式的全域性變數和區域性變數

區域性變數

在JavaScript函式內部宣告的變數(使用 var)是區域性變數,所以只能在函式內部訪問它(該變數的作用域是函式內部)。只要函式執行完畢,本地變數就會被刪除。

全域性變數:

在函式外宣告的變數是全域性變數,網頁上的所有指令碼和函式都能訪問它。

變數生存週期:

JavaScript變數的生命期從它們被宣告的時間開始。

區域性變數會在函式執行以後被刪除。

全域性變數會在頁面關閉後被刪除。

 

作用域

首先在函式內部查詢變數,找不到則到外層函式查詢,逐步找到最外層。

幾個例子:

1.

複製程式碼
var city = "BeiJing";
function f() {
  var city = "ShangHai"; function inner(){ var city = "ShenZhen"; console.log(city); } inner(); } f(); //輸出結果是?
複製程式碼

2.

var city = "BeiJing";
function Bar() {
  console.log(city);
}
function f() {
  var city = "ShangHai";
  return Bar;
}
var ret = f();
ret();  // 列印結果是?

 

結果是beijing

3.閉包

var city = "BeiJing";
function f(){
    var city = "ShangHai";
    function inner(){
        console.log(city);
    }
    return inner;
}
var ret = f();
ret();

結果:ShangHai

 

 作用域

函式的呼叫 要往回找 函式的定義階段
首先在函式內部找 -> 內部找不到就往外找,直到找到全域性為止

 

詞法分析(嘗試理解)

JavaScript中在呼叫函式的那一瞬間,會先進行詞法分析。

詞法分析的過程:

當函式呼叫的前一瞬間,會先形成一個啟用物件:Avtive Object(AO),並會分析以下3個方面:

1:函式引數,如果有,則將此引數賦值給AO,且值為undefined。如果沒有,則不做任何操作。
2:函式區域性變數,如果AO上有同名的值,則不做任何操作。如果沒有,則將此變數賦值給AO,並且值為undefined。
3:函式宣告,如果AO上有,則會將AO上的物件覆蓋。如果沒有,則不做任何操作。

函式內部無論是使用引數還是使用區域性變數都到AO上找。

 

看兩個例子:

 

複製程式碼
var age = 18;
function foo(){
  console.log(age);
  var age = 22; console.log(age); } foo(); // 問:執行foo()之後的結果是?
複製程式碼

 

第二題:

 

複製程式碼
var age = 18;
function foo(){
  console.log(age);
  var age = 22; console.log(age); function age(){ console.log("呵呵"); } console.log(age); } foo(); // 執行後的結果是?
複製程式碼

 

 

複製程式碼
詞法分析過程:
1、分析引數,有一個引數,形成一個 AO.age=undefine;
2、分析變數宣告,有一個 var age = 22, 發現 AO 上面已經有一個 AO.age = underfined,前後一行的console.log()沒什麼用,因此不做任何處理
3、分析函式宣告,有一個 function age(){...} 宣告, 則把原有的 age 覆蓋成 AO.age=function(){...}; 最終,AO上的屬性只有一個age,並且值為一個函式宣告 執行過程: 注意:執行過程中所有的值都是從AO物件上去尋找 1、執行第一個 console.log(age) 時,此時的 AO.age 是一個函式,所以第一個輸出的一個函式 2、這句 var age=22; 是對 AO.age 的屬性賦值, 此時AO.age=22 ,所以在第二個輸出的是 2 3、同理第三個輸出的還是22, 因為中間再沒有改變age值的語句了
複製程式碼

 

內建物件和方法

JavaScript中的所有事物都是物件:字串、數字、陣列、日期,等等。在JavaScript中,物件是擁有屬性和方法的資料。

我們在學習基本資料型別的時候已經帶大家瞭解了,JavaScript中的Number物件、String物件、Array物件等。

注意var s1 = "abc"和var s2 = new String("abc")的區別:typeof s1 --> string而 typeof s2 --> Object

 

創見物件的方式

 

自定義物件

//JS自定義物件

var person = {"name": "丁丁", "age":38};
console.log(person);
//單獨取
console.log("name:", person.name);
console.log("age:", person.age);

//遍歷
for (var i in person){
    console.log(i);
    console.log(person[i]);
}

-鍵不用加引號,加上也不出錯
 -值如果是字串必須寫雙引號

結果:

物件取值的方式區別

 

內建的Date物件

//Date物件
var d1 = new Date();
console.log(d1);
console.log(typeof d1);
console.log(d1.toLocaleString());
console.log(typeof d1.toLocaleString());

//生成指定時間的Date物件
var d2 = new Date("2004/3/20 11:12");
console.log(d2.toLocaleString());//轉成字串格式的本地時間
console.log(d2.toUTCString());//轉成字串格式的UTC時間

var d3 = new Date("2004-3-20 11:12");
console.log(d2.toLocaleString());//轉成字串格式的本地時間
console.log(d2.toUTCString());//轉成字串格式的UTC時間

console.log(d2.getDate()); //獲取幾號
console.log(d2.getDay()); //獲取星期
console.log(d2.getMonth());//獲取月份2 表示3月
console.log(d2.getFullYear()); //獲取年

console.log(d2.getHours());
console.log(d2.getMinutes());
console.log(d2.getSeconds());//
console.log(d2.getTime()); //時間戳

結果:

 

JSON物件

複製程式碼
var str1 = '{"name": "Alex", "age": 18}';
var obj1 = {"name": "Alex", "age": 18};
// JSON字串轉換成 物件 var obj = JSON.parse(str1); // 物件轉換成JSON字串 var str = JSON.stringify(obj1);
複製程式碼

 str1為字串、obj1為物件。

JSON物件 (背會)
        1. 字串轉物件 --> obj = JSON.parse(string)
        2. 物件轉字串 --> s   = JSON.stringify(obj)

 

Math物件

複製程式碼

abs(x)      返回數的絕對值。
exp(x)      返回 e 的指數。
floor(x)    對數進行下舍入。
log(x)      返回數的自然對數(底為e)。
max(x,y)    返回 x 和 y 中的最高值。
min(x,y)    返回 x 和 y 中的最低值。
pow(x,y)    返回 x 的 y 次冪。
random()    返回 0 ~ 1 之間的隨機數。
round(x)    把數四捨五入為最接近的整數。
sin(x)      返回數的正弦。
sqrt(x)     返回數的平方根。
tan(x)      返回角的正切。
複製程式碼

網頁中效果:

 

RegExp物件

var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{3,11}$")
var regexpRet1 = reg1.test("xiaoqiang");
console.log(regexpRet1);

var regexpRet2 = reg1.test("2xiaoqiang");
console.log(regexpRet2);

//(坑)正則表示式中間一定不能有空格
console.log(/^[a-zA-Z][a-zA-Z0-9_]{3,11}$/.test("xiangang"));
console.log(/^[a-zA-Z][a-zA-Z0-9_]{3,11}$/.test("2xiangang"));

//坑 不傳值相當於傳undefined 當做“undefined”
console.log("==============================================");
console.log(/^[a-zA-Z][a-zA-Z0-9_]{3,11}$/.test());
console.log(/^[0-9a-zA-Z][a-zA-Z0-9_]{3,11}$/.test());//不傳值,相當於傳undefined
console.log(/^[0-9a-zA-Z][a-zA-Z0-9_]{3,11}$/.test(undefined));


//g 表示全域性
//i 忽略大小寫
var ss = "Alexadfsa";
//不是改變預設字串,而是生成一個新的字串
var s3 = ss.replace(/a/gi, "哈哈哈哈");
console.log(s3);

//
// 當正則表示式使用了全域性模式(g)的時候,並且你還讓它去檢測一個字串,此時會引出來一個lastIndex
// lastIndex會記住上一次匹配成功的位置,並把下一次要開始校驗的位置記住
console.log("=============================================");
var r = /alex/g;  //全域性情況下
console.log(r.test("alex"));//test判斷能否匹配  true
console.log(r.lastIndex);  // 4
console.log(r.test("alex")); //會從索引4位置匹配,這必然是找不到的 false 若"1234alex"便能找到
console.log(r.lastIndex);  // 0    false之後從0開始
console.log(r.test("alex"));   // true
console.log(r.lastIndex);  // 4
console.log(r.test("alex"));  //false
console.log(r.lastIndex);  // 4

效果: