- 公式一:没有this => 只跟函数作用域定义位置有关(无论在哪调用)
- 公式二:有this => 只跟函数调用对象有关(无论在哪定义)
1. 公式一
题1. fn1 函数作用域内 定义函数fn2,打印结果为20
var age = 10
function fn1() {
var age = 20
function fn2() {
console.log(age); // 20
}
fn2()
}
fn1()
// 变量age在fn2自身作用域找不到,向上一级去找
// 因为fn2在fn1作用域内定义的,所以fn2的上一级作用域是fn1的作用域
// 打印的age是fn1作用域内声明的变量
题2. fn1 函数作用域外 定义函数fn2,fn2在fn1内调用,打印结果为10
var age = 10
function fn2() {
console.log(age); // 10
}
function fn1() {
var age = 20
fn2()
}
fn1()
// 变量age在fn2自身作用域找不到,向上一级去找
// 因为fn2在全局作用域内定义的,所以fn2的上一级作用域是全局作用域
// 打印的age是全局作用域内声明的变量
题3. fn1 函数作用域外 定义函数fn2,fn2作为fn1的参数,在fn1内调用,打印结果为10
var age = 10
function fn2() {
console.log(age); //10
}
function fn1(fn) {
var age = 20
fn()
}
fn1(fn2)
// 变量age在fn2自身作用域找不到,向上一级去找
// 因为fn2在全局作用域内定义的,所以fn2的上一级作用域是全局作用域
// 打印的age是全局作用域内声明的变量
题4. obj对象方法fn1内 定义函数fn2, 在fn1内调用,打印结果为10
var age = 10
var obj = {
age: 20,
fn1() {
function fn2() {
console.log(age); // 10
}
fn2()
}
}
obj.fn1()
// 变量age在fn2自身作用域找不到,向上一级去找
// 因为fn2在fn1作用域内定义的,所以fn2的上一级作用域是fn1作用域
// fn1作用域内并没有声明的age变量,继续向上一级查找
// 虽然fn1是对象obj的方法,但是对象obj并不能称之为fn1的上一级作用域,fn1的上一级作用域是全局作用域
// 打印的age是全局作用域内声明的变量
2. 公式二
题5. fn1 函数作用域内 定义函数fn2,打印结果为10 (只在第1题的基础上加个this)
var age = 10
function fn1() {
var age = 20
function fn2() {
console.log(this.age); // 10
}
fn2()
}
fn1()
// 函数在没有指定对象调用时,this指向window(node环境指向global)
// fn2()执行时,没有指定对象调用,所以this.age中的this指向window
// 在全局用var定义的变量都是window的属性(let,const定义的不是),所以this.age === window.age
// 打印的this.age是window.age
题6. obj对象方法fn1内 定义函数fn2, 在fn1内调用,打印结果为10 (只在第4题的基础上加个this)
var age = 10
var obj = {
age: 20,
fn1() {
function fn2() {
console.log(this.age); // 10
}
fn2()
}
}
obj.fn1()
// 这题很容易被迷惑,不要以为在一个对象里面看到this,这个this就一定指向该对象
// 记住公式二,fn2()执行时,并没有指定对象调用,所以this.age中的this指向window
// 打印的this.age是window.age
题7. fn1 函数作用域内 定义函数fn2, 在fn1内指定obj对象调用,打印结果为10
var obj = {
age: 10
}
var age = 30
function fn1() {
var age = 20;
function fn2() {
console.log(this.age);
}
fn2.call(obj)
}
fn1()
// 根据公式二,fn2()执行时,指定obj对象调用,所以this.age中的this指向obj
// 打印的this.age是obj.age