获取全局对象

  • web:window、self、frames、globalThis、this
  • node:global
  • worker:self
  • 通用:globalThis
1
2
3
4
5
6
7
var a = '全局属性 a'
console.log(`window: ${window.a}、self: ${self.a}
frames: ${frames.a}、globalThis: ${globalThis.a}、this: ${this.a}`)
console.log('window === self', window === self)
console.log('self === frames', self === frames)
console.log('frames === globalThis', frames === globalThis)
console.log('globalThis === this', globalThis === this)

this:Javascript 关键字,当前环境执行上下文对象的属性,存在作用域问题

  1. 全局作用域 this === window
  2. 作用域内部 this 指向调用者

类 this

Class:理解为容器、作用域、壳子,严格模式
new Class 指向 Class 内部的 constructor 构造器函数

1
2
3
4
5
6
7
8
9
10
11
class Test{
constructor(){}
say(){}
static do(){}
}
// 理解为:
const Test = (function(){
function Test(){}
Test.prototype.say = function(){}
Test.do = function(){}
})()
  • 类的非静态方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Test{
constructor(){
// 类的非静态方法,new 实例化阶段添加到 this
this.a = function(){
console.log('none-static:' + this)
}
// c 函数内 this 指向固定 Test
this.c = this.c.bind(this)
}

this.b = function(){
console.log('none-static:' + this)
}

// 类的静态方法
// 定义的时候,存在 Test.prototype{ ... }
// new 实例化时,this -> {} -> __proto__ -> Test.prototype
c(){
console.log('static:' + this)
}
}
const test = new Test()
test.test() // 输出 ‘none-static:[object object]’

类继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Father{
constructor(){
this.age = 44
}
swim(){ console.log('go swimming!!!')}
}

class Son extends Father{
constructor(){
super()
this.hobby = 'traval'
console.log(this.age)
}
study(){
console.log(this)
this.swim()
}
}
let son = new Son()
son.study()

Must call super constructor in derived class before accessing 'this' or returning from derived constructor

子类 constructor 中必须调用 super(),在使用 this 之前

  • super()

调用 Father 的 constructor
生成 this 绑定,Father 中 this 指向 Son 实例
Son 中 this 指向 new Father() -> {age}

构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Test(){
this.a = 1
this.b = 2
console.log(this)

return { // ②
x: 1,
y: 2
}
}
new Test()
// this -> {a:1, b:2}

var test = new Test()
// test -> {x:1, y:2} ②

call、apply、bind

fn.call(obj, a, b, c)
fn.apply(obj, [a, b, c])

bind:使用方法和 call 一样,效果只会生效一次

1
2
3
4
5
6
let obj = {a: 1}
let tbj = {a: 100}
function test(...arg){
console.log(this.a, ...arg)
}
let t = test.bind(obj, 3,4,5).bind(tbj, 9,8,7)

箭头函数

箭头函数忽略任何形式的 this 指向改变,静态 this 指向
箭头函数一定不是一个构造器
箭头函数的 this 不是谁调用指向谁,而是指向外层非箭头函数作用域的 this

对象

对象内部的 this,就近引用,谁调用指向谁

1
2
3
4
5
6
7
8
9
10
11
12
13
var obj = {
a: 1,
b: 2,
test: function(){
function t(){
console.log(this)
}
t()
}
}
obj.test()
// 输出结果为 window
// t() 不属于任何对象,孤立函数,指向 window

Object.create({...指定原型 || null:创建无链对象})

1
2
3
4
5
6
7
8
9
Object.defineProperty(obj, 'a', {
get: function(){
// 属性拦截
},
get: function(){
// 属性拦截
}
})
// this 指向 obj

事件处理函数

谁绑定处理函数,this 指向谁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
;(function(doc){
var oBtn = doc.getElementById('Id')
function Plus(a,b){
this.a = a
this.b = b

this.init()
}
Plus.prototype.init = function(){
this.bindEvent()
}
Plus.prototype.bindEvent = function(){
oBtn.addEventListener('click', this.handleBtnClick.bind(this), false)
// bind 更改 this 指向
}
Plus.prototype.handleBtnClick = function(){
console.log(this.a + this.b)
}
window.Plus = Plus
})(document)