JS函数中的this指向(下)

1、内置函数的this绑定(一些函数的this分析)

1.1 setTimeout (独立函数调用)

setTimeout(function () {
  console.log(this); // window
}, 2000);

1.2 监听点击(隐式绑定)

<body>
    <div class="box"></div>
</body>    

//监听点击
const boxDiv = document.querySelector(".box");
boxDiv.onclick = function () {
  console.log(this);   //<div class="box"></div>
};

boxDiv.addEventListener("click", function () {
  console.log(this);    //<div class="box"></div>
});

1.3 数组的forEach (若没有绑定,默认window)

// 数组.forEach/map/filter/find
var names = ["abc", "cba", "nba"];
names.forEach(function (item) {
  console.log(item, this);
}, "abc");
//abc String {'abc'}
//cba String {'abc'}
//nba String {'abc'}

names.map(function (item) {
  console.log(item, this);
}, "cba");

//abc String {'cba'}
//cba String {'cba'}
//nba String {'cba'}

2、规则优先级

①默认绑定的优先级最低
②call/apply的显示绑定高于隐式绑定
③bind的优先级高于隐式绑定
④new的优先级高于隐式绑定,高于bind

默认绑定(独立函数调用) < 隐式绑定(obj.foo()) < 显示绑定(apply/call/bind) < new绑定

注意:
new绑定和call、apply是不允许同时使用的,所以不存在谁的优先级更高
new绑定可以和bind一起使用,new绑定优先级更高

//bind的优先级高于隐式绑定
function foo() {
  console.log(this);
}

var obj = {
  name: "obj",
  foo: foo.bind("aaa"),
};

obj.foo(); //String {'aaa'}
var obj = {
  name: "obj",
  foo: function () {
    console.log(this);
  },
};

// new的优先级高于隐式绑定
var f = new obj.foo(); //foo {}
// new的优先级高于bind
function foo() {
  console.log(this);
}

var bar = foo.bind("aaa");

var obj = new bar(); //foo {}

3、this规则之外

3.1 忽略显示绑定:

如果在显示绑定中,我们传入一个null或者undefined,那么这个显示绑定
会被忽略,使用默认绑定规则

function foo() {
  console.log(this);
}
  
foo.apply("abc");    // String {'abc'}
foo.apply({});      //{}

// apply/call/bind: 当传入null/undefined时, 自动将this绑定成全局对象
foo.apply(null);     //Window
foo.apply(undefined);   //Window

var bar = foo.bind(null);
bar();   //Window

3.2、 间接函数引用:

创建一个函数的 间接引用,这种情况使用默认绑定规则

var obj1 = {
  name: "obj1",
  foo: function () {
    console.log(this);
  },
};

var obj2 = {
  name: "obj2",
};

obj2.bar = obj1.foo;
obj2.bar();   //obj2对象

(obj2.bar = obj1.foo)(); //Window
//赋值(obj2.foo = obj1.foo)的结果是foo函数
//foo函数被直接调用,那么是默认绑定

3.3、 ES6箭头函数

(1)
①箭头函数不使用this的四种标准规则(也就是不绑定this),而是根据上层作用域来决定this。
②定义对象的时候没有产生作用域

注意:箭头函数不会绑定this,arguments属性
不能作为构造函数来使用(不能和new一起使用,会抛出错误)

(2)箭头函数中this的指向

var name = "why";

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

foo(); //Window
var obj = { foo: foo };
obj.foo(); //Window
foo.call("abc"); //Window
// 2.应用场景
var obj = {
  data: [],
  getData: function () {
     console.log(this);  //obj对象
    // 发送网络请求, 将结果放到上面data属性中
    // 在箭头函数之前的解决方案
    // var _this = this
    // setTimeout(function() {
    //   var result = ["abc", "cba", "nba"]
    //   _this.data = result
    // }, 2000);
    // 箭头函数之后
    setTimeout(() => {
      console.log(this);   //obj对象
      var result = ["abc", "cba", "nba"];
      this.data = result;
    }, 2000);
  },
};

obj.getData(); //到上层作用域中,找到getData函数作用域,绑定的是obj对象
//因此这里第15行绑定的也是obj对象

(3)箭头函数有一些常见的简写:

//简写一: 如果参数只有一个, ()可以省略
nums.forEach(item => {
  console.log(item)
})
// 简写二: 如果函数执行体只有一行代码, 那么{}也可以省略
// 强调: 并且它会默认将这行代码的执行结果作为返回值
nums.forEach(item => console.log(item))
var newNums = nums.filter(item => item % 2 === 0)
console.log(newNums)

// filter/map/reduce
var result = nums.filter(item => item % 2 === 0)
                 .map(item => item * 100)
                 .reduce((preValue, item) => preValue + item)
console.log(result)
// 简写三: 如果一个箭头函数, 只有一行代码, 并且返回一个对象, 这个时候如何编写简写
//在对象外面加上一个小括号()
// var bar = () => {
//   return { name: "why", age: 18 }
// }

var bar = () => ({ name: "why", age: 18 })
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值