非严格模式下JavaScript语句中“this”默认指向全局对象(window)

发布时间 2023-11-09 09:43:43作者: 龙陌

请阅读以下代码

var obj = {};
obj.log = console.log;
obj.log.call(console,this);

该代码在浏览器中执行,输出的日志结果是什么?

obj.log.call(console,this) = console.log(this)。

this这里指window,所以最后的表达式是 console.log(window)

这道题看似在考this的绑定问题,实际上是通过this绑定为幌子,考察非严格模式下JavaScript语句中“this”默认指向全局对象(window)。

题目的关键点在第3行,我们知道,this绑定的优先级是new>bind>call(apply)>obj.func()>默认绑定。也就是说obj.log.call(console, this)语句中,实际上log函数内的this实际上指代的是console(这也是本题最大的陷阱!)。
然而实际上这一语句中obj.log.call(console, this)这一语句中打印的this是在外部传进去的,和函数内的this对象根本没有关系!也就是说此时log函数内的this指代console,但是打印的是从外面传进去的this对象,也就是window!

为了证明这一点,读者朋友们可以把obj.log.call(console, this)中的console改成任意一个对象,然后在非严格模式下执行,会发现结果都是window。

非严格模式下JavaScript语句中“this”默认指向全局对象(window)。其实严格模式下上面代码也是指向全局对象(window),只是在普通函数内部的this才不会指向window。
function goodboy(){console.log(this);}
goodboy();
这种情况下的this才会受"use strict"的干扰

obj.log和console.log指向同一个函数, 使用obj.log.call(console)其实就是调用console.log()。 console.log(message)接受参数message并打印 obj.log.call(console, this)与console.log(this)相同,而在全局作用域下这个this为window!

全局执行环境中this 都指向全局对象;

在函数内部,this的值取决于函数被调用的方式。

let obj = {}
// example1
function fn(e){
console.log('传参',e) // 传参 window{}
console.log('内部',this) // 内部 {}
}
fn.call(obj, this)

// example2
let o = {
foo:function(){
function fn(e){
console.log('传参',e) // 传参 {foo: ƒ}
console.log('内部',this) // 内部 {}
}
fn.call(obj,this)
}
}
o.foo()
fn(e){}

1、this作为参数传入fn执行时取决于当前执行函数的执行上下文

2、fn函数内部的this才受call绑定影响。

obj.log = console.log

obj.log.call(console,this)等于console.log.call(console,this)等于console.log(this)

关于这个this的指向问题,我一开始以为是console,但是出来的结果是Window,可以尝试通过下面的代码理解

function test(mingzi){
this.name = mingzi;
this.check = function(){
console.log(this);
}
}

new test('小明').check();

上文中的代码通过check方法执行console.log(this),输出的是当前对象test,那么如果在JS中直接输出this呢?
这个this指向的对象是什么呢?答案就是Window。使用chrome的同学可以尝试在F12 console里面直接输入this,指向的正是Window