这是我参与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();
复制代码