JavaScript快速入门笔记(8):全局对象和this指针

本系列随笔是本人的学习笔记,初学阶段难免会有理解不当之处,错误之处恳请指正。转载请注明出处:https://www.cnblogs.com/itwhite/p/12242109.html

全局对象

JavaScript 中有一个特殊的对象,称之为“全局对象”:

  • 它没有名字,你可以直接访问它的所有属性和方法(不需要指定它的名字),例如:console.log("ok") 中 console 就是它的一个属性;
  • 它位于作用域链的顶端,它的属性和方法实际上就是全局变量和全局函数,你自己创建的全局变量和全局函数也都将自动成为它的属性和方法;
  • 在最顶层代码(所有函数之外)中,this 指针默认指向它,因此你也可以通过 this 来访问它的属性和方法;
  • 在客户端脚本中,全局对象默认就是 window 对象。

示例:

this.console.log("global object testing"); // 同 console.log("global object testing")
var foo = 123;    // 全局变量
function bar() {  // 全局函数
  console.log("bar() is called");
}
console.log(this.foo);        // 123
this.bar();                   // bar() is called
console.log(this === window); // true

 

this指针

JavaScript 中还有一个特殊的关键字 this ,它的值会因运行时的上下文不同而不同:

  • 如果它在最顶层代码(所有函数之外)中,this 指向全局对象;
  • 如果它在函数中,this 指向的值会根据函数被调用的方式不同而不同:
    • 以普通函数的形式调用,例如:foo(),执行到该函数体中时, this 指向全局对象;
    • 以对象方法的形式调用,例如:o.bar(),执行到该函数体中时,this 指向对象 o;
    • 以构造函数的形式调用,例如:new Quz(),执行到构造函数中时,this 指向新创建的对象;
    • 通过 call() 或 apply() 方法间接调用,例如:bar.call(o, 123),执行到 bar() 函数体中时,this 指向对象o(call()的第一个参数)

 示例:

console.log(this === window); // true,在顶层代码中 this 指向全局对象
function foo() {
    if (this === window) {
        console.log("this points to global object");
    }
    else {
        console.log("this points to object:", this);
    }
}
foo();        // 以普通函数形式调用,输出:this points to global object
var o = {
    x: 1,
    y: 2,
    foo: foo
};
o.foo();      // 以对象方法形式调用,输出:this points to object: {x: 1, y: 2, foo: ƒ}
var o2 = new foo();  // 以构造函数形式调用,输出:this points to object: foo {} (foo在这里用作构造函数,创建了一个空对象)
foo.call(o);  // 用call()进行间接调用,输出:this points to object: {x: 1, y: 2, foo: ƒ}
foo.call(o2); // 用call()进行间接调用,输出:this points to object: foo {}

 上述提到的函数,包括嵌套函数,this 指针不是变量,也不遵守“作用域”的规则,它是运行时动态变化的(在执行函数调用时,JavaScript 解释器会自动替换 this 指针的值),它只会根据所在上下文(即当前所在函数被调用的形式)而变化,例如:

var x = 123;
var o = {
    x: 456,
    foo: function() {
        console.log(this.x); // 456
        function bar() {
            console.log(this.x); // 注意:这里的 this 也会根据 bar() 的调用形式不同而不同,并不会直接使用 o
        }
        bar();               // 123,表明 bar() 中的 this 指向全局对象
        bar.call(this);      // 456,表明 bar() 中的 this 指向对象 o
    }
};
o.foo();

 

完。

posted @ 2020-01-30 08:53  itwhite  阅读(390)  评论(0编辑  收藏  举报