JS函数this指向

函数在调用时,javaScript会默认给this绑定一个值,this的绑定和调用方式以及调用的位置有关系,this是在运行时被绑定的。

在全局作用域下this指向
  • 在Node环境中this指向的是空对象(内部源码通过call绑定的exports, exports ={})
  • 在浏览器之中指向的是window
this的绑定规则
1. 默认绑定

独立函数调用属于默认绑定,独立函数调用是指函数调用无任何前缀的情景。
默认绑定时,

  • 在非严格模式下this指向全局对象,再严格模式中,this指向undefined,
    在这里插入图片描述
2.隐式绑定

通过某对象进行调用,this指向调用它的那个对象
在这里插入图片描述

3.显示绑定

隐式绑定有一个前提条件,必须在调用的对象内部有一个对函数的引用;正是通过这个引用,间接的将this绑定到了这个对象上;当我们不在对象内部包含这个函数的引用,同时又希望在这个对象上进行强制调用,这时候我们就可以通过call、apply、bind进行显示绑定。

call、apply、bind
  • 这三个函数的第一个参数都是要指向的对象,在调用这个函数时,会将this绑定到这个传入的对象上。如果为null或undefined时,那么这个显示绑定会被忽略,使用默认规则
  • bind和call传递的调用参数参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,而apply的是参数数组
  • call和apply都会在绑定后立即执行,但是bind会返回一个永久改变this指针的函数,方便之后调用
  • call和apply都只能一次性传入参数,bind可以分开传递参数
call(thisArg, arg1,arg2,arg3, ...)
bind(thisArg,arg1,arg2,arg3,...);
apply(thisArg,[ arg1,arg2,arg3,...])
4.new绑定

javaScript中的函数可以当作一个类的构造函数来使用,也就是new关键字

new关键字会进行如下操作
  1. 创建一个空的简单JavaScript对象(即{})
  2. 为步骤1创建的对象添加属性_proto_将该属性链接到构造原型对象
  3. 将步骤1创建的对象作为this的上下文
  4. 如果该函数没有返回对象,则返回this
function Person(){
	this.name = name
}
var p = new Person(‘小明’)
规则优先级
  1. 默认规则的优先级最低
    默认规则的优先级是最低的,因为存在其他规则时,就会通过其他规则的方式来绑定this
  2. 显示绑定优先级高于隐式绑定
function foo(){
	console.log(this)//[String: 'aaa']
}
let obj = {
	foo: foo
}
obj.foo.call(‘aaa’) 
  1. new绑定优先级高于隐式绑定
function foo(){
	console.log(this) // foo {}
}
let obj = {
	foo: foo
}
let item = new obj.foo()
  1. new绑定优先级高于bind
  • new绑定和call、apply是不允许同时使用的,所以不存在谁的优先级更高
  • new绑定可以和bind一起使用,new绑定优先级更高
function foo() {
  console.log(this)//foo {}
}

var bar = foo.bind("aaa")

var obj = new bar() 
内置函数的绑定思考

有时候,我们会调用一些javaScript的内置函数,或者第三方库中的内置函数,这些内置函数会要求我们传入另外一个函数,这些函数中的this是怎么绑定的呢?

1. setTimeout

setTimeout在传入非箭头函数的情况下this始终指向window,无论是严格模式还是非严格模式下,其内部执行使用的是apply将this指向window

setTimeout(function() {
  console.log(this) // window
}, 2000)
2. forEach/map/filter/find

第一个参数:必须。函数,数组中的每个元素都会执行这个函数
函数参数。
第二个参数:可选。对象作为该执行回调时使用,传递给函数,用作 “this” 的值。如果省略了 thisValue,或者传入 null、undefined,那么回调函数的 this 为全局对象。

let array = ["11", "22", "33"]
array.forEach(function(item) {
  console.log(item, this)
}, "abc")
3. div的点击

this指向的是元素对象

const boxDiv = document.querySelector('.box')
boxDiv.onclick = function() {
  console.log(this)
}
this规则之外 - 间接函数引用

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

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

var obj2 = {
  name: "obj2"
};
console.log(obj2.bar = obj1.foo);  // 返回foo

(obj2.bar = obj1.foo)()  // window
  • 赋值(obj2.bar = obj1.foo)的结果是foo,
  • foo函数被直接调用,是默认绑定
this规则之外 – ES6箭头函数

箭头函数不使用this的四种标准规则(也就是不绑定this),而是根据外层作用域来决定this。箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。

箭头函数

MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions

基础语法

(param1, param2, …, paramN) => { statements }

当只有一个参数时,圆括号是可选的

singleParam => { statements }

没有参数的函数应该写成一对圆括号

() => { statements }

如果函数执行体只有一行代码, 那么{}也可以省略,并且它会默认将这行代码的执行结果作为返回值

() =>  statements 

如果一个箭头函数, 只有一行代码, 并且返回一个对象

let foo = () => ({ name: "why", age: 18 })
箭头函数与普通函数的区别
  • 箭头函数是匿名函数
  • 箭头函数不能作为构造函数来使用,不能使用new,没有原型(prototype)属性
  • 箭头函数不能绑定arguments,用rest参数解决
  • 箭头函数不会绑定this,根据外层作用域来决定
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值