一、變量
1.雙標簽
<!-- 外部js script 雙標簽 --><script src='my.js'></script>
在新文件my.js里面寫:
2.字符串定義:
//外單內雙var str = '我是一個"高富帥"的程序員';console.log(str);// 字符串轉義字符 都是用 \ 開頭 但是這些轉義字符寫在引號里面//外雙引號內單引號var str1 = "我是一個'高富帥'的\n程序員";// \n 是換行console.log(str1);
3.字符串拼接
// 1. 檢測獲取字符串的長度 length var str = 'my name is andy';console.log(str.length); // 15// 2. 字符串的拼接 + 只要有字符串和其他類型相拼接 最終的結果是字符串類型console.log('沙漠' + '駱駝'); // 字符串的 沙漠駱駝console.log('pink老師' + 18); // 'pink老師18'console.log('pink' + true); // pinktrueconsole.log(12 + 12); // 24console.log('12' + 12); // '1212'console.log('pink老師' + 18 + '歲');var age = 19;console.log('pink老師' + age + '歲');案例:var age=prompt('請輸入您的年齡');var str1='您已經'+age+'歲了';alert(str1)
4.boolean 及undefined 和null
var flag=true;//flag 布爾型var flag1=false;console.log(flag+1);//true參與加法運算當成1console.log(flag1+1);//false參與加法運算當成0// 如果一個變量聲明未賦值 就是 undefined 未定義數據類型var str;console.log(str);var variable = undefined;console.log(variable + 'pink'); // undefinedpinkconsole.log(variable + 1); // NaN undefined 和數字相加最后的結果是 NaN// null 空值var space = null;console.log(space + 'pink'); // nullpinkconsole.log(space + 1); // 1
5.typeof檢測變量數據類型:
var num = 10;console.log(typeof num); // numbervar str = 'pink';console.log(typeof str); // stringvar flag = true;console.log(typeof flag); // booleanvar vari = undefined;console.log(typeof vari); // undefinedvar timer = null;console.log(typeof timer); // object// prompt 取過來的值是 字符型的var age = prompt('請輸入您的年齡');console.log(age);console.log(typeof age);
6.字符串的不可變性
var str = 'andy';console.log(str);str = 'red';console.log(str);// 因為我們字符串的不可變所以不要大量的拼接字符串var str = '';for (var i = 1; i <= 1000000000; i++) {str += i;}console.log(str);
7.數據類型轉換
1.轉為字符串
//toString()var num=10;console.log(num);var str=num.toString();console.log(str);console.log(typeof str);//String(變量)console.log(String(num));//+拼接字符串方法console.log(''+num);
黑字體是字符串
2.轉為數字
// var age = prompt('請輸入您的年齡');// 1. parseInt(變量) 可以把 字符型的轉換為數字型 得到是整數// console.log(parseInt(age));console.log(parseInt('3.14')); // 3 取整console.log(parseInt('3.94')); // 3 取整console.log(parseInt('120px')); // 120 會去到這個px單位console.log(parseInt('rem120px')); // NaN// 2. parseFloat(變量) 可以把 字符型的轉換為數字型 得到是小數 浮點數console.log(parseFloat('3.14')); // 3.14console.log(parseFloat('120px')); // 120 會去掉這個px單位console.log(parseFloat('rem120px')); // NaN// 3. 利用 Number(變量) var str = '123';console.log(Number(str));console.log(Number('12'));// 4. 利用了算數運算 - * / 隱式轉換console.log('12' - 0); // 12console.log('123' - '120');console.log('123' * 1);案例1:計算年齡:// 彈出一個輸入框(prompt),讓用戶輸入出生年份 (用戶輸入)// 把用戶輸入的值用變量保存起來,然后用今年的年份減去變量值,結果就是現在的年齡 (程序內部處理)// 彈出警示框(alert) , 把計算的結果輸出 (輸出結果)var year = prompt('請您輸入您的出生年份');var age = 2021 - year; // year 取過來的是字符串型 但是這里用的減法 有隱式轉換alert('您今年已經' + age + '歲了');
3.轉換為布爾型
?????
//代表空、否定的值會被轉換為false,//如''、0、NaN、null、undefinedconsole.log(Boolean('')); // falseconsole.log(Boolean(0)); // falseconsole.log(Boolean(NaN)); // falseconsole.log(Boolean(null)); // falseconsole.log(Boolean(undefined)); // false//其余都是trueconsole.log('------------------------------');console.log(Boolean('123'));console.log(Boolean('你好嗎'));console.log(Boolean('我很好'));
8.返回字符串和位置
1.根據位置返回字符
??????? // 1. charAt(index) 根據位置返回字符
??????? var str = 'andy';
??????? console.log(str.charAt(3));
??????? // 遍歷所有的字符
??????? for (var i = 0; i < str.length; i++) {
??????????? console.log(str.charAt(i));
??????? }
??????? // 2. charCodeAt(index)? 返回相應索引號的字符ASCII值 目的: 判斷用戶按下了那個鍵
??????? console.log(str.charCodeAt(0)); // 97
??????? // 3. str[index] H5 新增的
??????? console.log(str[0]); // a
2.根據字符返回位置
//str.indexOf('要查找的字符', [起始的位置])var str = '改革春風吹滿地,春天來了';console.log(str.indexOf('春'));//2console.log(str.indexOf('春', 3)); //8 、從索引號是 3的位置開始往后查找
9.查找字符串中某個字符出現的次數
var str = "oaoefoxyozzop";var index = str.indexOf('o');var num = 0;// console.log(index);while (index !== -1) {console.log(index);num++;index = str.indexOf('o', index + 1);//從下一個o開始再找}console.log('o出現的次數是: ' +num);
10. 判斷一個字符串中出現次數最多的字符,并統計其次數。
// 有一個對象 來判斷是否有該屬性 對象['屬性名']var o = {age: 18}if (o['sex']) {console.log('里面有該屬性');} else {console.log('沒有該屬性');}// 核心算法:利用 charAt() 遍歷這個字符串// 把每個字符都存儲給對象, 如果對象沒有該屬性,就為1,如果存在了就 +1// 遍歷對象,得到最大值和該字符var str = 'aboooo';var obj= {};for (var i = 0; i < str.length; i++) {var chars = str.charAt(i); // chars 是字符串的每一個字符if (obj[chars]) { // o[chars] 得到的是屬性值,i=0時是判斷o里面是否有a這個屬性值obj[chars]++;//當o里面有a這個屬性時就將a這個屬性的值加1} else {obj[chars] = 1;}//當o里面沒有a這個屬性時就將a這個屬性的值賦值為1,最后的結果:a:1,b:1,o:4 }console.log(obj);//{a:1,b:1,o:4}// 2. 遍歷對象var max = 0;var ch = '';for (var k in obj) {// k 得到是 屬性名// o[k] 得到的是屬性值if (obj[k] > max) {max = obj[k];ch = k;}}console.log(max);console.log('最多的字符是' + ch);alert('a的值為'+obj.a);//1alert('b的值為'+obj.b);//1alert('o的值為'+obj.o);//4
11.字符串操作方法
??????? // 1. concat('字符串1','字符串2'....)
??????? var str = 'andy';
??????? console.log(str.concat('red'));
??????? // 2. substr('截取的起始位置', '截取幾個字符');
??????? var str1 = '改革春風吹滿地';
??????? console.log(str1.substr(2, 2)); // 第一個2 是索引號的2 從第幾個開始? 第二個2 是取幾個字符
???????? // 1. 替換字符 replace('被替換的字符', '替換為的字符')? 它只會替換第一個字符
??????? var str = 'andyandy';
??????? console.log(str.replace('a', 'b'));
??????? // 有一個字符串 'abcoefoxyozzopp'? 要求把里面所有的 o 替換為 *
??????? var str1 = 'abcoefoxyozzopp';
??????? while (str1.indexOf('o') !== -1) {
??????????? str1 = str1.replace('o', '*');
??????? }
??????? console.log(str1);
??????? // 2. 字符轉換為數組 split('分隔符') 前面我們學過 join 把數組轉換為字符串
ar str2 = ['red', 'pink', 'blue'];console.log(str2.join(''));//redpinkbluevar str3 = 'red&pink&blue';console.log(str3.split('&'));// ["red", "pink", "blue"]
- 運算符
- 算數運算符
1.基本運算
console.log(1 + 1); // 2console.log(1 - 1); // 0console.log(1 * 1); // 1console.log(1 / 1); // 1// % 取余 (取模) console.log(4 % 2); // 0console.log(5 % 3); // 2console.log(3 % 5); // 3// 浮點數 算數運算里面會有問題console.log(0.1 + 0.2); // 0.30000000000000004console.log(0.07 * 100); // 7.000000000000001// 我們不能直接拿著浮點數來進行相比較 是否相等var num = 0.1 + 0.2;console.log(num == 0.3); // false
2.邏輯運算符
// 1. 邏輯與 && and 兩側都為true 結果才是 true 只要有一側為false 結果就為false console.log(3 > 5 && 3 > 2); // falseconsole.log(3 < 5 && 3 > 2); // true// 2. 邏輯或 || or 兩側都為false 結果才是假 false 只要有一側為true 結果就是trueconsole.log(3 > 5 || 3 > 2); // true console.log(3 > 5 || 3 < 2); // false// 3. 邏輯非 not ! console.log(!true); // false
3.短路邏輯
// 1. 用我們的布爾值參與的邏輯運算 true && false == false // 2. 123 && 456 是值 或者是 表達式 參與邏輯運算? // 3. 邏輯與短路運算 如果表達式1 結果為真 則返回表達式2 如果表達式1為假 那么返回表達式1console.log(123 && 456); // 456console.log(0 && 456); // 0console.log(0 && 1 + 2 && 456 * 56789); // 0為假,‘1 + 2 && 456 * 56789’不再參與運算console.log('' && 1 + 2 && 456 * 56789); // ''// 如果有空的或者否定的為假 其余是真的 0 '' null undefined NaN// 4. 邏輯或短路運算 如果表達式1 結果為真 則返回的是表達式1 如果表達式1 結果為假 則返回表達式2console.log(123 || 456); // 123console.log(123 || 456 || 456 + 123); // 123console.log(0 || 456 || 456 + 123); // 456// 邏輯中斷很重要 它會影響我們程序運行結果思密達var num = 0;console.log(123 || num++);console.log(num); // 0
4.運算符優先級
- 流程控制
1.分支
if和else(和c一樣)
1.三元表達式
??????var?num?=?10;
????????var?result?=?num?>?5???'是的'?:?'不是的';?//?我們知道表達式是有返回值的
????????console.log(result);
1.switch語句
??????switch?(3)?{
????????????case?1:
????????????????console.log('這是1');
????????????????break;
????????????case?2:
????????????????console.log('這是2');
????????????????break;
????????????case?3:
????????????????console.log('這是3');
????????????????break;
????????????default:
????????????????console.log('沒有匹配結果');
????????}
- 循環
1.for循環:
????//打印三角形
????var?str='';
????var?raw;
????raw=prompt('輸入打印行數');
????for(var?i=0;i<=raw;i++){
????????for(var?j=0;j<=i;j++){
????????????str=str+'*';
????????}
????????str=str+'\n';
????}
console.log(str);
??//打印乘法表
????var?str='';
????var?raw;
????for(var?i=1;i<=9;i++){
????????for(var?j=1;j<=i;j++){
????????????str=str+i+'*'+j+'='+i*j;
????????????str=str+'\t';
????????}
????????str=str+'\n';
????}
????console.log(str);
2.do while
?? ?//?1.do?while?循環?語法結構
??do?{
????????????//?循環體
????????}?while?(條件表達式)
????????//?2.??執行思路?跟while不同的地方在于?do?while?先執行一次循環體?在判斷條件?如果條件表達式結果為真,則繼續執行循環體,否則退出循環
????????//?3.?代碼驗證
????????var?i?=?1;
????????do?{
????????????console.log('how?are?you?');
????????????i++;
????????}?while?(i?<=?100)
????????//?4.?我們的do?while?循環體至少執行一次
- continue
??//?continue?關鍵字???退出本次(當前次的循環)??繼續執行剩余次數循環
?for?(var?i?=?1;?i?<=?5;?i++)?{
????????????if?(i?==?3)?{
????????????????continue;?//?只要遇見?continue就退出本次循環?直接跳到?i++
????????????}
????????????console.log('我正在吃第'?+?i?+?'個包子');
????????}
- 數組
- 數組對象的創建
?// 1. 利用數組字面量
??????? var arr = [1, 2, 3];
??????? console.log(arr[0]);
? // 2. 利用new Array()
??????? // var arr1 = new Array();? // 創建了一個空的數組
??????? // var arr1 = new Array(2);? // 這個2 表示 數組的長度為 2? 里面有2個空的數組元素
??????? var arr1 = new Array(2, 3); // 等價于 [2,3]? 這樣寫表示 里面有2個數組元素 是 2和3
??????? console.log(arr1);
- 檢測是否是數組
??????? // (1) instanceof? 運算符 它可以用來檢測是否為數組
??????? var arr = [];
??????? var obj = {};
??????? console.log(arr instanceof Array);
??????? console.log(obj instanceof Array);
??????? // (2) Array.isArray(參數);? H5新增的方法? ie9以上版本支持
??????? console.log(Array.isArray(arr));
??????? console.log(Array.isArray(obj));
- 數組元素的增刪
?//?1.?push()?在我們數組的末尾?添加一個或者多個數組元素???push??推
????????var?arr?=?[1,?2,?3];
????????//?arr.push(4,?'pink');
????????console.log(arr.push(4,?'pink'));
????????console.log(arr);
????????//?(1)?push?是可以給數組追加新的元素
????????//?(2)?push()?參數直接寫?數組元素就可以了
????????//?(3)?push完畢之后,返回的結果是?新數組的長度?
????????//?(4)?原數組也會發生變化
????????//?2.?unshift?在我們數組的開頭?添加一個或者多個數組元素
????????console.log(arr.unshift('red',?'purple'));
????????console.log(arr);
????????//?(1)?unshift是可以給數組前面追加新的元素
????????//?(2)?unshift()?參數直接寫?數組元素就可以了
????????//?(3)?unshift完畢之后,返回的結果是?新數組的長度?
????????//?(4)?原數組也會發生變化
????????//?3.?pop()?它可以刪除數組的最后一個元素??
????????console.log(arr.pop());
????????console.log(arr);
????????//?(1)?pop是可以刪除數組的最后一個元素?記住一次只能刪除一個元素
????????//?(2)?pop()?沒有參數
????????//?(3)?pop完畢之后,返回的結果是?刪除的那個元素?
????????//?(4)?原數組也會發生變化
????????//?4.?shift()?它可以刪除數組的第一個元素??
????????console.log(arr.shift());
????????console.log(arr);
????????//?(1)?shift是可以刪除數組的第一個元素?記住一次只能刪除一個元素
????????//?(2)?shift()?沒有參數
????????//?(3)?shift完畢之后,返回的結果是?刪除的那個元素?
????????//?(4)?原數組也會發生變化
4.數組排序
??//?冒泡排序
????????//?var?arr?=?[5,?4,?3,?2,?1];
????????var?arr?=?[4,?1,?2,?3,?5];
????????for?(var?i?=?0;?i?<=?arr.length?-?1;?i++)?{?//?外層循環管趟數?
????????????for?(var?j?=?0;?j?<=?arr.length?-?i?-?1;?j++)?{?//?里面的循環管?每一趟的交換次數
????????????????//?內部交換2個變量的值?前一個和后面一個數組元素相比較
????????????????if?(arr[j]?<?arr[j?+?1])?{
????????????????????var?temp?=?arr[j];
????????????????????arr[j]?=?arr[j?+?1];
????????????????????arr[j?+?1]?=?temp;
????????????????}
????????????}
????????}
????????console.log(arr);
???// 1. 翻轉數組
??????? var arr = ['pink', 'red', 'blue'];
??????? arr.reverse();
??????? console.log(arr);
??????? // 2. 數組排序(冒泡排序)
??????? var arr1 = [13, 4, 77, 1, 7];
??????? arr1.sort(function(a, b) {
??????????? //? return a - b; 升序的順序排列
??????????? return b - a; // 降序的順序排列
??????? });
??????? console.log(arr1);
- 獲取數組元素索引
??// 返回數組元素索引號方法? indexOf(數組元素)? 作用就是返回該數組元素的索引號 從前面開始查找
??????? // 它只返回第一個滿足條件的索引號
??????? // 它如果在該數組里面找不到元素,則返回的是 -1?
??????? // var arr = ['red', 'green', 'blue', 'pink', 'blue'];
??????? var arr = ['red', 'green', 'pink'];
??????? console.log(arr.indexOf('blue'));
??????? // 返回數組元素索引號方法? lastIndexOf(數組元素)? 作用就是返回該數組元素的索引號 從后面開始查找
??????? var arr = ['red', 'green', 'blue', 'pink', 'blue'];
??????? console.log(arr.lastIndexOf('blue')); // 4
??? </script>
- 數組去重
??// 封裝一個 去重的函數 unique 獨一無二的
??????? function unique(arr) {
??????????? var newArr = [];
??????????? for (var i = 0; i < arr.length; i++) {
??????????????? if (newArr.indexOf(arr[i]) == -1) {
??????????????????? newArr.push(arr[i]);
??????????????? }
??????????? }
??????????? return newArr;
??????? }
??????? // var demo = unique(['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'])
??????? var demo = unique(['blue', 'green', 'blue'])
??????? console.log(demo);
6.數組轉換為字符串
??????? // 1. toString() 將我們的數組轉換為字符串
??????? var arr = [1, 2, 3];
??????? console.log(arr.toString()); // 1,2,3
??????? // 2. join(分隔符)
??????? var arr1 = ['green', 'blue', 'pink'];
??????? console.log(arr1.join()); // green,blue,pink
??????? console.log(arr1.join('-')); // green-blue-pink
??????? console.log(arr1.join('&')); // green&blue&pink
7.基本包裝類型
??????? var str = 'andy';
??????? console.log(str.length);
??????? // 對象(var obj={})才有 屬性和方法?? 復雜數據類型才有 屬性和方法
??????? // 簡單數據類型為什么會有length 屬性呢?
??????? // 基本包裝類型:? 就是把簡單數據類型 包裝成為了 復雜數據類型
??????? // (1) 把簡單數據類型包裝為復雜數據類型
??????? //相當于執行以下操作
??????? var temp = new String('andy');
??????? // (2) 把臨時變量的值 給 str
??????? str = temp;
??????? // (3) 銷毀這個臨時變量
??????? temp = null;
- 函數
1.語法
?? function?sayHi()?{
????????????console.log('hi~~');
????????}
????????//?(1)?function?聲明函數的關鍵字?全部小寫
????????//?(2)?函數是做某件事情,函數名一般是動詞?sayHi?
????????//?(3)?函數不調用自己不執行
????????//?2.?調用函數
????????//?函數名();
????????sayHi();
????????//?調用函數的時候千萬不要忘記加小括號
2.參數
1.實參和形參
??????? function cook(aru) { // 形參是接受實參的? aru = '酸辣土豆絲' 形參類似于一個變量
??????????? console.log(aru);
??????? }
??????? cook('酸辣土豆絲');
??????? cook('大肘子');
??????? // 4. 函數的參數可以有,也可以沒有個數不限
2.參數匹配
???? // 函數形參實參個數匹配
??????? function getSum(num1, num2) {
??????????? console.log(num1 + num2);
??????? }
??????? // 1. 如果實參的個數和形參的個數一致 則正常輸出結果
??????? getSum(1, 2);
??????? // 2. 如果實參的個數多于形參的個數? 會取到形參的個數
????????getSum(1, 2, 3);
??????? // 3. 如果實參的個數小于形參的個數? 多于的形參定義為undefined? 最終的結果就是 NaN
??????? // 形參可以看做是不用聲明的變量? num2 是一個變量但是沒有接受值? 結果就是undefined
????????getSum(1); // NaN
??????? // 建議 我們盡量讓實參的個數和形參相匹配
3.復雜的數據類型傳參
//?復雜數據類型傳參
function?Person(name)?{
????????????this.name?=?name;
????????}
????????function?f1(x)?{?//?x?=?p
????????????console.log(x.name);??
????????????x.name?=?"張學友";
????????????console.log(x.name);?//?3.?這個輸出什么?????張學友
????????}
????????var?p?=?new?Person("劉德華");
????????console.log(p.name);?//?1.?這個輸出什么??劉德華?
????????f1(p);???????????????//?2.?這個輸出什么??劉德華??張學友
????????console.log(p.name);?//?4.?這個輸出什么??張學友?p->x->張學友
- 返回值
?// 函數返回值注意事項
??????? // 1. return 終止函數
??????? function getSum(num1, num2) {
??????????? return num1 + num2; // return 后面的代碼不會被執行
??????????? alert('我是不會被執行的哦!')
??????? }
??????? console.log(getSum(1, 2));
??????? // 2. return 只能返回一個值
??????? function fn(num1, num2) {
??????????? return num1, num2; // 返回的結果是最后一個值
??????? }
??????? console.log(fn(1, 2));
??????? // 3.? 我們求任意兩個數的 加減乘數結果
??????? function getResult(num1, num2) {
??????????? return [num1 + num2, num1 - num2, num1 * num2, num1 / num2];
??????? }
??????? var re = getResult(1, 2); // 返回的是一個數組
??????? console.log(re);
??????? // 4. 我們的函數如果有return 則返回的是 return 后面的值,如果函數么有 return 則返回undefined
??????? function fun1() {
??????????? return 666;
??????? }
??????? console.log(fun1()); // 返回 666
??????? function fun2() {
??????? }
??????? console.log(fun2()); // 函數返回的結果是 undefined
- arguments
當我們不確定有多少個參數傳遞的時候,可以用arguments來獲取。在JavaScript中,arguments實際上它是當前函數的一個內置對象。所有函數都內置了一個arguments對象,arguments對象中存儲了傳遞的所有實參。
?//?arguments?的使用??只有函數才有?arguments對象??而且是每個函數都內置好了這個arguments
function?fn()?{
????????????//?console.log(arguments);?//?里面存儲了所有傳遞過來的實參??arguments?=?[1,2,3]
????????????//?console.log(arguments.length);
????????????//?console.log(arguments[2]);
????????????//?我們可以按照數組的方式遍歷arguments
????????????for?(var?i?=?0;?i?<?arguments.length;?i++)?{
????????????????console.log(arguments[i]);}}
????????fn(1,?2,?3);
????????fn(1,?2,?3,?4,?5);
????????//?偽數組?并不是真正意義上的數組
????????//?1.?具有數組的?length?屬性
????????//?2.?按照索引的方式進行存儲的
????????//?3.?它沒有真正數組的一些方法?pop()??push()?等等
- 函數聲明
?// 函數的2中聲明方式
??????? // 1. 利用函數關鍵字自定義函數(命名函數)
??????? function fn() {
??????? }
??????? fn();
??????? // 2. 函數表達式(匿名函數)
????????// var 變量名 = function() {};
??????? var fun = function(aru) {
??????????? console.log('我是函數表達式');
??????????? console.log(aru);
??????? }
??????? fun('pink老師');
??????? // (1) fun是變量名 不是函數名?
????????// (2) 函數表達式聲明方式跟聲明變量差不多,只不過變量里面存的是值 而 函數表達式里面存的是函數
??????? // (3) 函數表達式也可以進行傳遞參數
- 作用域
1.基本作用域
?? //?1.JavaScript作用域?:?就是代碼名字(變量)在某個范圍內起作用和效果?目的是為了提高程序的可靠性更重要的是減少命名沖突
????????//?2.?js的作用域(es6)之前?:全局作用域???局部作用域?
????????//?3.?全局作用域:?整個script標簽?或者是一個單獨的js文件
????????var?num?=?10;
????????var?num?=?30;
????????console.log(num);
????????//?4.?局部作用域(函數作用域)?在函數內部就是局部作用域?這個代碼的名字只在函數內部起效果和作用
????????function?fn()?{
????????????//?局部作用域
????????????var?num?=?20;
????????????console.log(num);
????????}
????????fn();
?// js中沒有塊級作用域? js的作用域: 全局作用域? 局部作用域? 現階段我們js 沒有 塊級作用域
??????? // 塊級作用域 {}?? if {}? for {}
??????? // java
????????// if(xx) {
??????? //???? int num = 10;
??????? // }
??????? // 外面的是不能調用num的
??????? if (3 < 5) {
??????????? var num = 10;
??????? }
??????? console.log(num); //外面是可以調用num的
2.作用域鏈
·只要是代碼,就至少有一個作用域
·寫在函數內部的局部作用域
·如果函數中還有函數,那么在這個作用域中就又可以誕生一個作用域
·根據在內部函數可以訪問外部函數變量的這種機制,用鎮式查找決定哪些數據能被內部函數訪問,就稱作作用域鏈
??? ?// 作用域鏈? : 內部函數訪問外部函數的變量,采取的是鏈式查找的方式來決定取那個值 這種結構我們稱為作用域鏈?? 就近原則
??????? var num = 10;
??????? function fn() { // 外部函數
??????????? var num = 20;
??????????? function fun() { // 內部函數
??????????????? console.log(num);
??????????? }
??????????? fun();
??????? }
??????? fn();
一層一層向上找:
3.案例
案例1.
?//?案例1?:?結果是幾?
????????function?f1()?{
????????????var?num?=?123;
????????????function?f2()?{
????????????????console.log(num);?//?站在目標出發,一層一層的往外查找
????????????}
????????????f2();
????????}
????????var?num?=?456;
????????f1();
案例2.
//?案例2?:結果是幾?
????????var?a?=?1;
????????function?fn1()?{
????????????var?a?=?2;
????????????var?b?=?'22';
????????????fn2();
????????????function?fn2()?{
????????????????var?a?=?3;
????????????????fn3();
????????????????function?fn3()?{
????????????????????var?a?=?4;
????????????????????console.log(a);?//a的值??
????????????????????console.log(b);?//b的值??
????????????????}
????????????}
????????}
????????fn1();