【JavaScript】关于this的代码输出题总结

1.在Javascript中,this指向函数执行时的当前对象

function foo() {
  console.log( this.a );
}

function doFoo() {
  foo();
}
  • 该处的执行foo()的时候,执行环境为doFoo函数,而该函数为普通函数,this指向window

2.箭头函数时不绑定this的,它的this来自原其父级所处的上下文

var a = 10
var obj = {
  a: 20,
  say: () => {
    console.log(this.a)
  }
}
obj.say() //10

var anotherObj = { a: 30 } 
obj.say.apply(anotherObj)  //10

  • 该代码的obj对象是在全局定义的,故箭头函数say()方法继承其父级所处的上下文,即windows,所以第一个输出仍然是10,后面虽然让say方法指向了另外一个对象,但是仍不能改变箭头函数的特性,它的this仍然是指向全局的,所以依旧会输出10。
  • 若为say为普通函数,其this指向指向他所在的对象,即输出obj其中的a的值

3.如果call第一个参数传入的对象调用者是null或者undefined,call方法将把全局对象(浏览器上是window对象)作为this的值

function a() {
  console.log(this);
}
a.call(null); 
  • 输出window对象
  • 但若开启了严格模式,null 就是 null,undefined 就是 undefined
'use strict';

function a() {
    console.log(this);
}
a.call(null); // null
a.call(undefined); // undefined
var a = 10; 
 var obj = { 
   a: 20, 
   fn: function(){ 
     var a = 30; 
     console.log(this.a)
   } 
 }
 obj.fn();  // 20
 obj.fn.call(); // 10
 (obj.fn)(); // 20
  • obt.fn.call():这里call的参数啥都没写,就表示null,我们知道如果call的参数为undefined或null,那么this就会指向全局对象this,所以会打印出 10;
  • (obj.fn)():相当于立即执行 obj.fn()

4. 使用new构造函数时,其this指向的是全局环境window

var obj = { 
  name : 'cuggz', 
  fun : function(){ 
    console.log(this.name); 
  } 
} 
obj.fun()     // cuggz
new obj.fun() // undefined

5. 对象不构成单独的作用域

var obj = {
   say: function() {
     var f1 = () =>  {
       console.log("1111", this);
     }
     f1();
   },
   pro: {
     getPro:() =>  {
        console.log(this);
     }
   }
}
var o = obj.say;
o(); //1111 window对象
obj.say(); //1111 obj对象
obj.pro.getPro(); //window对象
  • 调用o():注意此时调用的环境是在全局作用域下,f1() 箭头函数继承父级say function() 在全局作用域中,故打印出window;
  • obj.say():谁调用say,say 的this就指向谁,所以此时this指向的是obj对象;
  • obj.pro.getPro():由于getPro处于pro中,而对象不构成单独的作用域,所以箭头的函数的this就指向了全局作用域window;

6.立即执行函数调用this指向window,对象方法调用this指向该方法所属对象

var myObject = {
    foo: "bar",
    func: function() {
        var self = this;
        console.log(this.foo);  
        console.log(self.foo);  
        (function() {
            console.log(this.foo);  
            console.log(self.foo);  
        }());
    }
};
myObject.func();
//bar bar undefined bar
  • func是由myObject调用,this指向myObject,故self也指向myObject
  • 立即执行匿名函数表达式的this指向window 。立即执行匿名函数的作用域处于myObject.func的作用域中,在这个作用域找不到self变量,沿着作用域链向上查找self变量,找到了指向 myObject对象的self

7. 对象中若存在立即执行函数会直接执行后销毁

window.number = 2;
var obj = {
 number: 3,
 db1: (function(){
   console.log(this);
   this.number *= 4;
   return function(){
     console.log(this);
     this.number *= 5;
   }
 })()
}
var db1 = obj.db1;
db1();
obj.db1();
console.log(obj.number);     // 15
console.log(window.number);  // 40

  • 输出:
    在这里插入图片描述
  • 一开始在初始化obj对象时,立即执行函数this指向window,此时已经执行this.number *= 4window.number为8
  • 然后执行db1()由于返回的是一个普通函数,在全局中调用,this指向window,故window.number为8*5 = 40
function(){
     console.log(this);
     this.number *= 5;
   }
  • 最后执行obj.db1(),this指向obj对象,执行返回的函数,obj.number为3*5 = 15

8.this的指向通常是调用函数的时候确定的,一般指向调用者

var length = 10;
function fn() {
    console.log(this.length);
}
 
var obj = {
  length: 5,
  method: function(fn) {
    fn();
    arguments[0]();
  }
};
 
obj.method(fn, 1);
  • 调用fn()的时候在method方法中执行,对象不构成作用域,故this指向的是window,输出10
  • arguments[0]为fn(),相当于arguments调用方法,this指向arguments,而这里传了两个参数,故输出arguments长度为2

9. 注意对象中函数的写法,函数调用的时机

var a = 1;
function printA(){
  console.log(this.a);
}
var obj={
  a:2,
  foo:printA, //此时的printA还没有被调用
  bar:function(){
    printA(); //已调用
  }
}

obj.foo(); // 2
obj.bar(); // 1
var foo = obj.foo;
foo(); // 1

  • obj.foo(),foo 的this指向obj对象,所以a会输出2;
  • obj.bar(),printA在bar方法中执行,所以此时printA的this指向的是window,所以会输出1;
  • foo(),foo是在全局对象中执行的,所以其this指向的是window,所以会输出1;

10.

var x = 3;
var y = 4;
var obj = {
    x: 1,
    y: 6,
    getX: function() {
        var x = 5;
        return function() {
            return this.x;
        }();
    },
    getY: function() {
        var y = 7;
        return this.y;
    }
}
console.log(obj.getX()) // 3
console.log(obj.getY()) // 6
  • 匿名函数的this是指向全局对象的,所以this指向window,会打印出3;
  • getY是由obj调用的,所以其this指向的是obj对象,会打印出6;

11.

function a(xx){
  this.x = xx;
  return this
};
var x = a(5);
var y = a(6);

console.log(x.x)  // undefined
console.log(y.x)  // 6
  • 函数a是在全局作用域调用,所以函数内部的this指向window对象,故x的值为window,而window对象中没有x属性,所以会输出undefined
  • 当执行y.x时,y为window,并会给全局变量中的x赋值为6,所以会打印出6

12.this绑定的优先级:new绑定 > 显式绑定 > 隐式绑定 > 默认绑定

function foo(something){
    this.a = something
}

var obj1 = {
    foo: foo
}

var obj2 = {}

obj1.foo(2); 
console.log(obj1.a); // 2

obj1.foo.call(obj2, 3);
console.log(obj2.a); // 3

var bar = new obj1.foo(4)
console.log(obj1.a); // 2
console.log(bar.a); // 4
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值