js前端开发那些事儿

JavaScript的this(一)

2021-06-14  本文已影响0人  踏莎行

this是js的关键字,当前环境执行期上下文对象的一个属性,在不同的环境,不用的作用下,表现也是不同的

全局上下文

无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this 都指向全局对象。

console.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
console.log(window); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
console.log(window === this); // true

在全局下声明的变量都会挂载到window上,也可以理解在全局下this和window是同一个

var a = 1
var b = function(){
  return 'function'
}
console.log(window.a); // 1
console.log(window.b); // ƒ (){ return 'function' }
console.log(window.a === a); // true
console.log(window.b === b); // true

函数上下文

var a = 'global -> a'
            
var obj = {
  a: 'obj -> a',
  test: function(){
    console.log(a); // global -> a
    console.log(window.a); // global -> a
    console.log(this) // {a: "obj -> a", test: ƒ}
    console.log(this.a); // obj -> a
  }
}
obj.test()

谁调用的函数,那么函数内部的this指向默认就指向谁,上面的例子中,是obj调用的test方法,所以默认test的this指向是obj

var a = 1
function test() {
  console.log(this); // window
  console.log(this.a); // 1
}
test()

当代码在浏览器里执行时,全局作用域里的所有全局变量和函数都在window对象里定义,所以在全局函数里使用this,它指代window对象并储存着该对象的值
在松散模式下,函数可以返回this来获取全局对象,而在严格模式下,this返回的就是undefined

function test() {
  'use strict'
  console.log(this); // undefined
}
test()

上面也说了谁调用的函数,那么函数内部的this指向默认就指向谁,如果使用window.test的方式调用函数,this就会指向window

function test() {
  'use strict'
  console.log(this); // window
}
window.test()

在node环境中

var a = 'global -> a'       
var obj = {
  a: 'obj -> a',
  test: function(){
    console.log(window.a);
  }
}
obj.test()

执行后就会报错
ReferenceError: window is not defined,在node中,全局是global。而且上面的var a = 'global -> a' 是不会挂载到global上的,

var a = 'global -> a'
            
var obj = {
  a: 'obj -> a',
  test: function(){
    console.log(a); // 'global -> a'
    console.log(global.a); // undefined
    console.log(a === global.a); // false
    console.log(global); 
          /*<ref *1> Object [global] {
              global: [Circular *1],
              clearInterval: [Function: clearInterval],
              clearTimeout: [Function: clearTimeout],
              setInterval: [Function: setInterval],
              setTimeout: [Function: setTimeout] {
                [Symbol(nodejs.util.promisify.custom)]:[Function(anonymous)]},
              queueMicrotask: [Function: queueMicrotask],
              clearImmediate: [Function: clearImmediate],
              setImmediate: [Function: setImmediate] {
[Symbol(nodejs.util.promisify.custom)]: [Function (anonymous)]
            }
      }*/
    }
}
obj.test()

可以看出,在global上就没有一个a的属性,如果要在全局上添加一个属性就需要手动的添加

global.xxxx = xxx
global.a = 'global -> a'
            
var obj = {
  a: 'obj -> a',
  test: function(){
    console.log(a); //  'global -> a'
    console.log(global.a); //  'global -> a'
    console.log(a === global.a) // true
  }
}
obj.test()

这时再打印global,它上面就有属性a了

获取全局对象的方法

浏览器环境

console.log(window);
console.log(this); // 全局下访问才能获取到全局对象
console.log(self);
console.log(frames);
var obj = {
  test: function(){
    console.log(window);
    console.log(this);
    console.log(self);
    console.log(frames);
  }
}
obj.test()
Snipaste_2021-06-14_14-37-49.png

node环境

worker环境

通用方式

console.log(globalThis);

浏览器环境
不能在hbuilder的内置浏览器中查看,否则报错
“Uncaught ReferenceError: globalThis is not defined”

Snipaste_2021-06-14_14-44-34.png
node环境
Snipaste_2021-06-14_14-49-04.png
worker不再演示
上一篇下一篇

猜你喜欢

热点阅读