一、 JS代碼運(yùn)行環(huán)境
js代碼是通過<script>標(biāo)簽直接嵌入頁面中的,一個頁面中可以有多段<script>定義的代碼片段 它們既相互關(guān)聯(lián) 又保持獨(dú)立(角度不同)
關(guān)聯(lián)性:一段script中的內(nèi)容(變量、函數(shù)) 可以在另一段script中使用
獨(dú)立性:一段script運(yùn)行發(fā)生錯誤 不影響另一script的執(zhí)行
1媒役、全局執(zhí)行環(huán)境
js在運(yùn)行時 首先會創(chuàng)建一個全局執(zhí)行環(huán)境 這個全局環(huán)境就是定義一個全局對象偿曙,頁面中所有的內(nèi)容(不同的script中的內(nèi)容) 都是這個全局對象的屬性龙亲,在瀏覽器javascript中(嵌入網(wǎng)頁的js)這個全局對象是window承二。
// 定義變量
var bar = "some text";
// 定義函數(shù)
function(){
console.log("hello world");
}
// 查看網(wǎng)頁中的全局對象
console.log(window);
這就是說 不同的script中的內(nèi)容 都同屬一個window對象 因此他們的內(nèi)容可以共享榆鼠。
<script>
// 定義變量
var bar = "some text";
// 定義函數(shù)
function(){
console.log("hello world");
}
// 查看網(wǎng)頁中的全局對象
console.log(window);
</script>
<script>
// 打印不同script標(biāo)簽里的變量
console.log(bar);
// 調(diào)用不同script標(biāo)簽里的函數(shù)
foo();
</script>
2、運(yùn)行錯誤
1亥鸠、當(dāng)發(fā)生編譯錯誤時 代碼不執(zhí)行 而執(zhí)行時的錯誤;
2识啦、影響錯誤之后的的輸出 而不影響前面代碼的執(zhí)行负蚊。
3、無論發(fā)生何種錯誤 一段代碼發(fā)生了錯誤不影響另一段代碼的運(yùn)行颓哮。
<script>
// 錯誤之前輸出
console.log("編譯錯誤之前的輸出");
// js代碼可以不以";"結(jié)尾 它會自動補(bǔ)全
// 非法換行家妆,編譯時發(fā)生語法錯誤
var bar = "hello
world";
console.log("編譯錯誤之后的輸出");
</script>
<script>
console.log("執(zhí)行錯誤之前的輸出");
console.log(unknow);
console.log("執(zhí)行錯誤之后的輸出");
</script>
3、使用異常處理錯誤
js代碼運(yùn)行時的錯誤 在頁面不顯示冕茅。而是自動拋出一個錯誤對象(Error)
處理錯誤:
1伤极、使用try/catch來捕獲該錯誤對象蛹找。
2、自定義錯誤處理場景 使用throw new Error(‘提示信息’)手動拋出錯誤哨坪。
try {
//當(dāng)執(zhí)行發(fā)生錯誤時 會拋出一個ReferenceError錯誤對象
console.log(unknow);
} catch (e) {
console.log(e);
//查看錯誤提示信息 ->
console.log(e.message);
}
function division(x) {
if (!x) throw new Error("被除數(shù)不能為0");
return 1/x;
}
try {
division(0);
} catch (e) {
console.log(e.message);
}
</script>
二庸疾、 變量和作用域
1、變量是存儲數(shù)據(jù)的容器当编,JS中變量使用var聲明届慈,與變量密切相關(guān)的是它的作用域。作用域是指變量作用的區(qū)域 它分為全局和局部的作用域忿偷。
2金顿、定義在程序頂層(不屬于某個函數(shù))中的變量是全局變量,函數(shù)體內(nèi)的變量為局部變量鲤桥。全局變量在整個頁面中都有效揍拆,局部變量只能做作用于函數(shù)體內(nèi) 當(dāng)函數(shù)退出(執(zhí)行完畢、調(diào)用結(jié)束)時 函數(shù)體內(nèi)的狀態(tài)會被銷毀掉(變量被刪除了) 因此無法在外部訪問到茶凳。
3嫂拴、變量也可不用var聲明 未經(jīng)var聲明的變量會成為全局變量 即使是定義在函數(shù)體內(nèi)。
4慧妄、使用var聲明 但是未賦值的變量 初始化值是undefined顷牌。
5、沒有塊狀作用域
<script>
//常見面試題
function foo() {
var scope;
//函數(shù)體內(nèi)的變量沒有塊狀的作用域 變量一經(jīng)定義 在整個函數(shù)體內(nèi)都有效
console.log(scope);
scope = "local";
}
foo();
</script>
6塞淹、作用域鏈
全局變量是全局對象的屬性 局部變量是一個叫做激活對象(也叫調(diào)用對象 是函數(shù)調(diào)用時產(chǎn)生的對象)的屬性窟蓝。組成變量作用域的是一個對象列表或?qū)ο箧?一般叫“作用域鏈”。
在程序頂層中變量作用域鏈為全局對象饱普,定義在函數(shù)f體內(nèi)的變量作用域鏈為 f的激活對象 => 全局對象运挫,函數(shù)體內(nèi)嵌套的函數(shù)g的作用域?yàn)?g的激活對象 => 外圍函數(shù)f的激活對象 => 全局對象。
當(dāng)查詢變量x值時 JS會沿著它當(dāng)前所在位置的作用域鏈的頭部開始查找 如果找到 則返回結(jié)果 如果沒有 則繼續(xù)往下查找 直到根部(根沒有則是undefined)套耕。
三谁帕、數(shù)據(jù)類型
布爾值、字符串冯袍、數(shù)值匈挖、null、undefined等是基本類型數(shù)據(jù)康愤,傳值引用儡循;
數(shù)組、函數(shù)和對象是引用類型征冷,傳地址引用择膝。
四、運(yùn)算符和表達(dá)式
1检激、typeof
使用typeof 查看變量的數(shù)據(jù)類型 它是一個運(yùn)算符 不是函數(shù) 當(dāng)查看一個表達(dá)式時 會使用()使之看起來像個函數(shù)肴捉。
var arr = [];
arr[0] = "z";
console.log(typeof arr); // object
console.log(typeof 1); //number
console.log(typeof "hello"); //string
console.log(typeof true); //boolean
console.log(1 + "a"); //數(shù)值和字符串相加 是將數(shù)值轉(zhuǎn)化成字符串"1"
console.log(typeof (1 + "a")); //string
2腹侣、delete
可以刪除一個對象的屬性或者數(shù)組元素。
還可以用來刪除一個未用var聲明的變量齿穗。
3傲隶、instanceof
用來檢測一個對象是否是某個類的實(shí)例 注意不要取檢測是否是Object的實(shí)例(都是true)。
4缤灵、in
用來判斷對象中是否有某個屬性
5伦籍、with 語句
變量有作用域 當(dāng)作用域比較長的時候 可以使用with修改作用域鏈的頭 簡化代碼輸入量。
<body>
<div id="d"></div>
<script>
var d = document.getElementById("d");
with (d.style) {
width = 100 + "px";
height = 100 + "px";
backgroundColor = "green";
}
</script>
</body>
6腮出、|| 運(yùn)算
或運(yùn)算執(zhí)行時 當(dāng)表達(dá)式兩邊都為false時 返回false帖鸦,有一個為true就返回true。
短路運(yùn)算:當(dāng)左邊為true時 直接返回左邊的值 不用往后執(zhí)行胚嘲。如果左邊為FALSE呢 右邊代表最終的結(jié)果作儿。
五、函數(shù)
1馋劈、函數(shù)參數(shù)
JS中的函數(shù)參數(shù)可以不嚴(yán)格的匹配 當(dāng)調(diào)用時傳入的實(shí)參個數(shù) 多余定義的形參 多出的值會被忽略 當(dāng)實(shí)參個數(shù)少于形參 在函數(shù)體內(nèi)的形參值為undefined攻锰。
<script>
function f(x, y) {
console.log(x,y);
}
f(1,2);
f(1,2,3);
f(1);
</script>
2、arguments對象
函數(shù)體內(nèi)標(biāo)識符arguments有著特殊的含義 它是一個類似數(shù)組的對象 用來獲取函數(shù)調(diào)用時傳入的實(shí)參值妓雾。
function h(x, y) {
//函數(shù)體內(nèi)使用arguments查看傳入的實(shí)參
console.log(arguments);
//arguments對象的數(shù)字下標(biāo)存儲了實(shí)參值
console.log(arguments[0], arguments[1]);
//arguments的length屬性存放實(shí)參個數(shù)
console.log(arguments.length);
}
h("hello","world");
arguments對象可以有效的幫助我們處理可變參數(shù)(參數(shù)長度不固定 沒法定義形參接收)函數(shù)娶吞,例如 計算一組數(shù)的最大值 實(shí)際調(diào)用時 會有不同個數(shù)的參數(shù)傳入。
max(1,2,3,4)
max(1,2)
max(1,2,3)
<script>
//使用arguments來處理可變參數(shù)的函數(shù)
function max() {
//不定義形參 使用arguments來獲取實(shí)際調(diào)用時的參數(shù)值
//初始化最大值為第一個實(shí)參元素
var m = arguments[0];
//從第二個實(shí)參值開始 循環(huán) 判斷
for (var i = 1; i < arguments.length; i++) {
if (m < arguments[i]) m = arguments[i];
}
return m;
}
console.log(max(1,2,3));
console.log(max(1,2,3,4));
console.log(max(1,2,3,4,5));
</script>
3械姻、函數(shù)屬性
函數(shù)是數(shù)據(jù)類型 是對象的數(shù)據(jù)類型妒蛇,它有屬性和方法,函數(shù)的length屬性是查看函數(shù)形參的個數(shù)楷拳。
function g(x, y) {
//函數(shù)的length屬性是它定義的形參個數(shù)
console.log(g.length);
}
g();