this指向的四项规则

举报
骁M_M 发表于 2021/03/27 18:26:01 2021/03/27
【摘要】 this指向规则

一、默认绑定规则

console.log(this === window);// true
console.log({}==={});// false
// 函数的独立调用
function test(){
  console.log(this === window);// true
}
test(); // 相当于window.test();

二、隐式绑定规则:谁调用就指向谁

var a =0;
var obj = {
  a = 2,
  foo: function(){
    console.log(this);//obj
    function test(){
      console.log(this);//window
    }
    test();
    // (function(){
     // console.log(this);//window
    //})();函数声明后在浏览器中立即执行IFEthis指向window,在node中执行会指向相应的全局对象
  }
}
obj.foo();

每一个函数执行都会有一个自身的this指向
预编译会产生Global Object与Activity Object,this已经存在,但如果函数不执行this没有意义。

  • 闭包中的this指向
    当函数执行的时候,导致函数被定义,并抛出,会产生闭包(不严谨的描述,但这句话也是对的,只是方便理解)

    var obj = {
        a = 2,
        foo: function(){
          console.log(this);//obj
          function test(){
            console.log(this);//window
          }
          return test;
        }
      }
      obj.foo()();//相当于test的独立调用,主要看函数的调用方式
    

当对函数存在赋值的时候存在隐式丢失,不管是变量赋值还是参数赋值

  var a = 0;
  function foo(){
     console.log(this);
  }
  var obj = {
     a = 2,
     foo: foo
  }
  obj.foo();//obj
   var bar = obj.foo;//当对函数存在赋值的时候存在隐式丢失  var bar = foo;
  bar();//window 相当于独立调用

var a = 0;
function foo(){
    console.log(this);
}
function bar(fn){
      fn();
      //fn.bind(obj)();
}
//父函数有能力决定子函数的this指向
var obj = {
     a = 2,
     foo: foo
}
bar(obj.foo);//window 预编译过程中形参与实参存在一个浅拷贝过程,也是一个赋值过程

//子函数又叫做回调函数
var arr = [1,2,3];
arr.forEach(function(item,index,arr){
    console.log(this);//obj
},obj);

arr.sort(function(a,b){
   console.log(this);//window
   return a-b;
});

setInterval(function(){
   console.log(this);//window
})

三、显示绑定:call、apply、bind
传参方式不一样

 var a = 0;
function foo(){
    console.log(this);
}
function bar(fn){
      fn();
      //fn.bind(obj)();
}
bar.call(obj,1,2,3);//第一个参数是要绑定的this指向
bar.apply(obj,[1,2,3]);
bar.bind(obj)(1,2,3);//bin返回一个函数需要执行一下
bar.call(1,2,3)//Number
bar.call(undefied,2,3)//window undefied没有包装类绑定失败使用默认指向
bar.call(null,2,3)//window null没有包装类绑定失败使用默认指向

四、new绑定:new绑定优先级大于显示绑定大于隐式绑定大于默认绑定

function Person(){
  var this = {};
  this.a = 1;
  return this;//this是实例化之后的对象
  return 1;//this的指向不受影响
  return {};//this的指向会发生改变
}
var person = new Person();实例是对象

// 证明显示绑定优先级高于隐式绑定优先级
function foo() {
    console.log(this.a);
}

var obj1 = {
    a:1,
    foo: foo
}

var obj2 = {
    a:2,
    foo:foo
}

obj1.foo.call(obj2);//2
obj2.foo.call(obj1);//1

// 证明new 绑定优先级高于显示绑定
function foo(b) {
   this.a = b;
}
var obj1 = {};
var bar = foo.bind(obj1);
bar(2);
console.log(obj1.a);//2
var baz = new bar(3);
console.log(obj1.a);//2
console.log(baz.a);//3

五、箭头函数

var a = 0;
function foo() {
    var that = this;
    function test() {
        console.log(this);
    }
    test();
}

foo();// window

如果想让test中的this跟随外层foo的指向
第一种方法 将外层作用域的this,保留在that中,内部使用that

function foo() {
    var that = this;
    function test() {
        console.log(that);
    }
    test();
}

var obj = {
   a:1,
   foo:foo
}
obj.foo();// obj

第二种方法 调用test的时候使用显示绑定指向当前作用域this

function foo() {
    function test() {
        console.log(this);
    }
    test.call(this);
}

var obj = {
   a:1,
   foo:foo
}
obj.foo();// obj

第三种方法 利用箭头函数直接取到外层作用域指向

箭头函数本身是没有this指向的,它的this指向实际上是使用外层作用域的this

function foo() {
    console.log(this);
    var test = ()=> {
        console.log(this);
    }
    test();
}

var obj = {
   a:1,
   foo:foo
}
obj.foo();// obj,obj

对于箭头函数,所有绑定规则都不适用,箭头函数的this指向取决于父环境中的this指向,箭头函数本身不存在this指向
1.默认绑定规则

var a = 0;
function foo() {
    console.log(this);
    var test = ()=> {
        console.log(this);
    }
    return test;
}

var obj1 = {
   a:1,
   foo:foo
}

var obj2 = {
   a:2,
   foo:foo
}

obj1.foo()(); // 默认绑定规则(独立调用对箭头函数)无效

2.显示绑定规则

var a = 0;
function foo() {
 console.log(this);
    var test = ()=> {
        console.log(this);
    }
  return test;
}

var obj1 = {
   a:1,
   foo:foo
}

var obj2 = {
   a:2,
   foo:foo
}
var bar = foo().call(obj2); // 显示绑定规则对箭头函数this指向无效,如果test是一般函数是有效的

3.隐式绑定规则

var obj1 = {
       a:1,
       foo:() => {
           console.log(this);
       }
    }
obj.foo();// window 隐式绑定规则无效

4.new不能实例箭头函数

 var foo = () => {
    console.log(this);
 }

new foo();// 报错
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。