這是我參與8月更文挑戰的第10天,活動詳情查看:8月更文挑戰javascript
變量提高結束後,代碼纔會從上到下執行。前端
console.log(num); // undefined 由於代碼執行到這裏時,num只是通過了變量提高階段的聲明,可是沒有完成賦值,因此是undefined;
var num = 100; // 代碼執行過這一行後完成了賦值,因此num是100
console.log(num); // 100
console.log(fe); // 函數體自己,由於fe這個變量在函數執行時就已經賦值完成了,因此不管在函數聲明前仍是後使用都是函數自己
fe(); // 由於fe在變量提高階段就已經完成了賦值,因此fe是一個函數,因此能夠成功執行
function fe() {
console.log('We are Front-end Engineer');
複製代碼
console.log(num); // undefined
var num = 12; // 賦值操做,只在執行到這一行時,num才被賦值爲12;
var obj = {
name: "江外",
age: '10'
};
console.log(xy);
function xy(str) {
var age = 10;
console.log(str, age);
}
xy('江外');
複製代碼
做用域是js運行的環境,另一個功能是保存基本數據類型。在js中做用域分爲:java
+全局做用域 :當頁面打開時,首先造成一個全局做用域,執行全局中的代碼,全局做用域是window;
+私有做用域(函數做用域)當函數執行時,會造成一個函數做用域,這個做用域用來保存函數中的基本數據類型同時執行函數代碼;
+塊級做用域(相似私有做用域 ES6)
複製代碼
function fn() {
var num = 13;
}
console.log(num); // 報錯:由於預解釋發生在當前做用域中,而當前做用域沒有num的變量,num是fn的私有變量。
複製代碼
var num;
var num;
var num; // 這些語句沒有賦值操做,當代碼執行時會略過
var num = 100; // num雖然var了4次,可是並不會聲明4次,只會聲明一次,同時只有這一次纔會將num的值賦值成100;
function fn() {
console.log(1)
}
function fn() {
console.log(2)
}
function fn() {
console.log(3)
}
fn(); // 3
複製代碼
console.log(fe); // 函數體
function fe() { // 當代碼執行到這裏時,直接忽略,由於函數變量賦值已經在變量
console.log('我是來自江外的FE');
}
var fe = 123; // 代碼執行到這一行時,將變量fe的值修改成123
複製代碼
若是變量名和函數名同名,在執行到變量的賦值語句以前時,這個名字表明函數,可是當執行過變量賦值語句後,變量標識這個新值瀏覽器
function fe() {
console.log('FE')
}
var fe = 1;
// fe(); // 報錯,由於執行到這裏的時候fe再也不表明一個函數了,而是一個數字
複製代碼
// fn(); // 報錯,
var fn = function () {
console.log('來自等號右側的你');
};
// console.log(x1); // 報錯:x1 is not defined
// console.log(x); // undefined
var x = function x1() {
console.log(x1);
};
複製代碼
console.log(n); // undefined
if (NaN === Number('I Love programming')) {
var n = 1;
}
console.log(n); // undefined,之內條件不成立,因此賦值語句沒執行,因此n仍然是undefined
複製代碼
function add(a, b) {
console.log(n); // undefined
fe(); // 執行了
return a + b;
var n = 123;
function fe() {
console.log('前端工程師從入門到刪庫跑路')
}
}
add();
複製代碼
function minus(a, b) {
console.log(foo);
return function foo() {
console.log('函數的返回值不參與變量提高')
}
}
minus();
複製代碼
用var和function聲明的變量,也至關於給window上添加一個同名屬性markdown
console.log(window);前端工程師
var num = 2019;
console.log(window.num); // 2019
window.num = 2020;
console.log(num); // 2020 num和window.num是綁定在一塊兒的
console.log('num' in window); // in 運算符 檢測對象是否有某個屬性,有返回true,不然false
function fe() {
console.log('FE')
}
window.fe();
fe();
複製代碼
console.log(a); // undefined
var a = 1;
console.log(b); // 報錯:
b = 2; // 不帶var 不會參與變量提高,因此不會提早聲明和賦值
console.log(b);
複製代碼
js中做用域函數
function fn() {
console.log(n);
}
fn(); // 15
function fn2() {
console.log(x)
}
fn3();
function fn3() {
x = 16;
}
fn2();
複製代碼
當在做用域中查找一個變量的時候,先看當前做用域中是否聲明過這個變量,若是聲明過,就使用這個變量,若是沒有生命過,那麼就去上級做用域(上級做用域就是函數聲明時所在的做用域)查找,找到就使用,若是沒有就一直向上查找,一直找到window爲止,若是本次使用變量是賦值,那麼就至關於給window上面增長一個屬性,若是是引用變量,就會報錯;post
function fe() { // fe 是在全局中定義的,因此fe的上級做用域就是全局做用域
var n = 200;
return function f() { // 這個function就是在fe的做用域中定義的,因此該函數的上級做用域就是fe的做用域
console.log(n) // 200
}
}
var fn = fe();
fn();
複製代碼
function fe() { // fe 是在全局中定義的,因此fe的上級做用域就是全局做用域
var n = 200;
return function f() { // 這個function就是在fe的做用域中定義的,因此該函數的上級做用域就是fe的做用域
console.log(n) // 200
}
}
var fn = fe();
fn();
複製代碼