javascript 中的 this几种情况

全局的 this(浏览器)

console.log(this.document === document);  //true
console.log(this === window); //true

this.a = 37;  // 相当于创建了一个全局变量 a
console.log(window.a); //37

一般函数的 this(浏览器)

function f1() {
    
    
	return this;
}
f1() === window; //true, global object
这里在浏览器就是 window, 如果是 node 中就是 global 全局对象

------------------
严格模式下: 一般函数调用的 this 是指向 undefined

function f2() {
    
    
	"use strict"
	return this;
}
f2() === undefined; //true

作为对象方法的函数 this

更常见的使用 this 的时候是将作为对象方法去用

函数如果作为对象的属性,比如
var o = {
    
    
  prop:37,
  f:function() {
    
    
    return this.prop;
  }
};

console.log(o.f());  //logs 37

o 有一个属性 f, 值是一个函数, 这样一种方式也叫做对象的方法.
这种作为对象的方法去调用的时候,
比如 o.f() 调用的情况下, this 一般指向对象 o,就相当于 return o.prop
所以返回 37

-------------------------------

上面这种是定义成函数字面量的这种对象,
如果这里定义一个对象 o, 一个独立的 independent 函数, 比如

var o = {
    
    prop:37},

function independent() {
    
    
  return this.prop
}

o.f = independent;

console.log(o.f()) // 37

如果直接调用 independent 函数的话, 里面的 this 指向浏览器里的window
如果通过赋值方式临时创建一个属性 f, 并且指向为这个函数对象的时候,拿到 37
所以这里不是看函数是怎么创建的, 而是只要将该函数作为对象的方法去做 o.f 调用的话
这个 this 就指向该对象


对象原型链上的 this

创建一个对象 o, 里面有一个属性 f, 并且函数作为对象属性的值;
再创建一个对象 p, 该对象是空对象, 并且他的原型指向 o
通过 p.a 和 p.b 创建对象上的属性, 
调用原型上的方法的时候, this.a 和 this.b 仍然取到对象上的 a 和 b
这里注意的是 p 的原型才是 o
所以调用 p.f 的时候调用的对象原型链上 o 这个函数上的属性f

var o = {
    
    f:function() {
    
     return this.a + this.b }};
var p = Object.create(o);
p.a = 1;
p.b = 4;

console.log(p.f()) //5

get/set 方法与 this

也指向 getset 方法所在的对象里面

构造器中的 this

正常如下调用是指向全局对象, 在浏览器里是 window
function MyClass() {
    
    
  this.a = 37;
}

但是如果用 new 把它作为构造器来调用的话, 
这里 this 指向原型为 MyClass.prototype 属性这样一个空对象
调用的时候由于 this.a = 37赋值, 所以最后的 this 作为返回值,
所以 o 就有 a 属性

var o = new MyClass();
console.log(o.a) //37

类似
function C2() {
    
    
	this.a = 37;
	return {
    
     a: 38 }
}
这时函数里有了 return 语句, 返回值返回一个对象
那么这时o.a 就不是 37 了
o = new C2();
console.log(o.a) //38

call / apply 方法与 this

除了不同的调用方式以外, 每一个函数对象也有一些方法可以去修改函数执行时的 this

function add(c,d) {
    
    
  return this.a + this.b + c + d;
}

var o = {
    
    a:1, b:3};

add.call(o,5,7); // 1+3+5+7 = 16
add.apply(o,[10,20]); //1+3+10+20 = 34

定义一个变量 o 有两个属性 a 和 b,
通过对象的 call 方法
(第一个参数是想作为 this 的对象, 
这里是 o, 57 是想要添加的参数, 5 赋值给 c, 7 赋值给 d)
最终调用的结果是 16

call 和 apply 基本没差别, 差别在于传参方式. 

何时用 call 和 apply?

function bar() {
    
    
  console.log(Object.prototype.toString.call(this))
}
这里想调用Object.prototype.toString, 但是想把 this 指定的时候

bind方法与 this

function f() {
    
    
  return this.a
}

var g = f.bind({
    
    a:"test"});
console.log(g()); //test

有一个函数对象 f,
通过 bind 方法中有一个参数对象 a, 
这个对象就是想将某一个对象作为 this 的时候, 来传入的对象
这样就拿到一个新的 g 对象, 这个 g 对象在调用的时候
就已经指向了 bind 参数所以拿到 a 的 test

var o = {
    
    a:37, f: f,g : g};
console.log(o.f(),o.g()) //37, test

猜你喜欢

转载自blog.csdn.net/m0_48446542/article/details/109006203