前言
本文整理了js的this的五种绑定规则以及常见js指向问题,如果对答案有不一样见解的同学欢迎评论区补充讨论,当然有问题,也欢迎在评论区指出。
一、理解this
this是什么?首先this不是指向自身!this 是一个指针,指向调用函数的对象。其次需要知道this的五种绑定规则
二、this五种绑定规则
优先级:5>4 > 3(bind>apply/call)> 2 > 1
1、默认绑定规则:直接调用,this 指向 window。
2、隐式绑定规则:谁调用就指向谁。this 永远指向最后调用它的那个对象
3、显式绑定规则:this 指向 call、apply、bind 函数的第一个传参。
4、new 绑定规则:this 指向构造函数产生的对象。
5、箭头函数
三、this的指向问题
1、箭头函数
- this 不会被改变
- 创建箭头函数时,箭头函数内的 this 指向外层的 this。
2、new
当使用 new 关键字调用函数时,函数中的 this 一定是 JS 创建的新对象。
function func(){
console.log(this);
}
new func() // this指向func {}
3、bind
bind 是指 Function.prototype.bind()。
bind() 函数会创建一个新的绑定函数,需要加一个()调用,调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。多次调用bind(),以第一个bind为主
function func() {
console.log(this); // 1
}
func.bind(1,2,3).bind(2)()
绑定函数也可以使用new运算符构造,(bind和new)
function func() {
console.log(this) //func {}
}
fun = func.bind(1);
new fun() //优先级高
4、apply和call
apply() 和 call()的this都被指定为第一个参数,且都是直接调用,而bind是创建一个新函数,区别是
-
apply的其余参数放到数组中。
-
call的其余参数是用逗号分隔的。
function func(args) { console.log(this,args) //[Number: 1] 2 } func.apply(1,[2,3]); func.call(1,2,3)
5、隐式绑定操作,谁调用就指向谁
function func() {
console.log(this) //{ name: 'hzy', func: [Function: func] } --- 指向obj
}
obj = {name:'hzy'} //赋值操作
obj.func = func;
obj.func()
var name = "windowsName";
var a = {
name: "Cherry",
fn : function () {
console.log(this.name); // Cherry
}
}
window.a.fn(); //最后调用的是a,所以指向a
var name = "windowsName";
var a = {
name : null,
// name: "Cherry",
fn : function () {
console.log(this.name); // windowsName
}
}
var f = a.fn; //虽然将 a 对象的 fn 方法赋值给变量 f 了,但是没有调用
// 如果这样的话:var f=a.fn() --- 会打印null
f(); //最后调用的是fn,所以指向window,打印windowName
6、直接调用
在函数不满足前面的场景,被直接调用时,this 将指向全局对象。在浏览器环境中全局对象是 Window,在 Node.js 环境中是 Global。
function func() {
console.log(this) // window/global
}
func()
function outerFunc() {
console.log(this) // { x: 1 }
function func() {
console.log(this) // Window
}
func()
}
outerFunc.bind({ x: 1 })()
7、不在函数里
不在函数中的场景,可分为浏览器的 < scrip >标签里,或 Node.js 的模块文件里。this指向window或global
8、Prototype
Array.prototype._map = function (callback) {
if(typeof callback !== 'function') {
throw new Error('callback is not function')
}
console.log(this) //this---------------------------> 实例对象 [1,5,6]
return this.reduce((prev,item,index,arr) => {
prev.push(callback(item, index, arr))
return prev
}, [])
}
let val = [1, 5, 6]._map(item => item+ 1)
总结
觉得写得好的,对你有帮助的,可以分享给身边人,知识越分享越多,千万不要吝啬呀
后续更新前端其它小知识总结,请关注我,整理好,分享给你们,我们一起学前端