即使`this`是'undefined`,如何在严格模式下的函数中定义`alert`?

Lon*_*ner 2 html javascript

我认为我们可以使用alert('foo')而不是window.alert('foo')因为在浏览器上下文中,this = window默认情况下,所以alert('foo')会自动表示this.alert('foo')哪个等价window.alert('foo').

所以,我没想到的alert功能,在一个函数中定义严格模式,因为当启用了严格模式,thisundefined在功能.

这是代表我的困惑的代码.

function foo() {
  console.log('----- foo -----')
  console.log('this: ' + this);
  console.log('window: ' + window);
  console.log('alert: ' + alert)
  console.log('window.alert: ' + window.alert)
  console.log('this.alert: ' + this.alert)
}

function bar() {
  'use strict'
  console.log('----- bar -----')
  console.log('this: ' + this); // this is undefined
  console.log('window: ' + window);
  console.log('alert: ' + alert) // how is alert defined when this is undefined?
  console.log('window.alert: ' + window.alert)
  console.log('this.alert: ' + this.alert)
  console.log('----- end -----')
}

foo();
bar();
Run Code Online (Sandbox Code Playgroud)

这是输出.

"----- foo -----"
"this: [object Window]"
"window: [object Window]"
"alert: function alert() {
    [native code]
}"
"window.alert: function alert() {
    [native code]
}"
"this.alert: function alert() {
    [native code]
}"
"----- bar -----"
"this: undefined"
"window: [object Window]"
"alert: function alert() {
    [native code]
}"
"window.alert: function alert() {
    [native code]
}"
TypeError: this is undefined
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 7

我认为我们可以使用alert('foo')而不是window.alert('foo')因为在浏览器上下文中,默认情况下这是= window

不,可变分辨率(技术标识符分辨率)与thisJavaScript 无关.(您可能正在考虑Java或C#,其中实例成员可以this.在实例方法中使用或不使用.JavaScript与Java或C#this非常不同 this.)我们可以使用alert或者window.alertalert全局变量的原因.

标识符解析的工作方式如下:如果标识符未在当前作用域中定义,则JavaScript引擎会查看最近的封闭作用域,然后查看下一个最近的封闭作用域等.全局作用域是整个容器,因此全局变量可用到处(除非被给定范围内的声明所遮蔽).例如:

// (In loose mode)
var foo = "bar";
function Ctor() {
    console.log("this is window? " + (this === window));     // false
    console.log(foo);                                        // "bar"

    function level2() {
        console.log("this is window? " + (this === window)); // true
        console.log(foo);                                    // "bar"
    }

    level2();
}
var c = new Ctor();
console.log("this is window? " + (this === window));         // true
console.log(foo);                                            // "bar"
Run Code Online (Sandbox Code Playgroud)

注意它是什么并不重要this.

至于为什么alert既可以单独使用(也可以作为全局),也可以作为以下属性window:在浏览器中,window是一个引用全局对象的全局变量(this在全局范围内也可以以松散模式使用).在ES2015之前,所有全局变量也是全局对象的属性,alert全局变量window.alert也是等效属性.(与您的问题不完全相关,但为了完整性:在ES2015中,通过var或函数声明创建的全局变量仍然是全局对象的属性,但也可以创建不是全局对象属性的全局变量[与let,const以及class].但是,所有的Web环境中定义的标准的人保持旧式的全局,同时也是性能.)