【js】5种this绑定简析
this绑定/this指向
- 默认绑定 - window
- 隐式绑定 - context
- 显示绑定 - call、apply、bind
- new绑定 - 新对象
- 箭头函数绑定 - 上层作用域
function fn1() {
let a = 1;
let fn2 = function () {
console.log(this);
console.log(this.a);
}
fn2();
return fn2
}
var a = 2;
fn1() //window 2
fn1()() //window 2 window 2
无论函数在哪声明或调用,调用时函数前
无对象
,this最终都指向window
2.隐式绑定
function fn() {
console.log(this.name);
}
let obj1 = {
name: "boj1",
fn
}
let obj2 = {
name: "obj2",
obj1
}
obj2.obj1.fn() //obj1
【【js】5种this绑定简析】函数调用前
有对象
时,this就近
指向上下文对象
若未寻找到属性返回
undefined
,不会在obj2上找
隐式丢失- 参数传递
- 变量赋值
let name = "window"
function fn() {
console.log(this.name);
}
let obj1 = {
name: "obj1",
fn
}
let obj2 = {
name: "obj2",
obj1
}
function func(param) {
param()
}
func(obj2.obj1.fn) //window
fn作为参数在func中调用,this指向丢失,默认指向window变量赋值
let name = "window"
function fn() {
console.log(this.name);
}
let obj1 = {
name: "obj1",
fn
}
let obj2 = {
name: "obj2",
obj1
}
let func = obj2.obj1.fn
func();
//window
将fn赋给func,func的调用this默认指向window3.显示绑定
- bind
- call
- apply
let name = "window"
function fn() {
console.log(this.name);
}
let obj1 = {
name: "obj1",
fn
}
let obj2 = {
name: "obj2",
obj1
}
function func1(param) {
param()
}
func1(obj1.fn.bind(obj2)) //obj2
let func2 = obj1.fn.bind(obj2)
func2() //obj2
call绑定
:fn.bind(obj) 将fn绑定在obj上并返回一个函数,不管是参数传递还是变量赋值都不会出现绑定丢失
的情况
参数
:bind第一个参数为绑定的对象,后面的可以追加参数作为函数的实参,传递一个数组
时不会自动解构
优先级
:显示绑定>隐式绑定>默认绑定
硬绑定
:绑定后不可使用bind、call、apply再重新绑定
let name = "window"
function fn() {
let name = this.name
return function fn1() {
console.log(name, this.name);
}
}
let obj1 = {
name: "obj1",
fn
}
let obj2 = {
name: "obj2",
obj1
}
function func1(param) {
param()
}
func1(obj1.fn.call(obj2)) //obj2 window
let func2 = obj1.fn.call(obj2)
func2() //obj2 window
func2.call(obj1) //obj2 obj1
apply绑定
:call绑定不同与bind的返回一个绑定的函数,而是立即执行
这个函数
参数
:与bind相同,this指向第一个参数,后续参数作为实参,数组不自动解构
软绑定
:本次调用时为绑定,下次执行还需要再次绑定
闭包
:在绑定时只绑定最外层作用域,父函数返回的函数在调用时为默认绑定
,当对其绑定时,其this会被绑定,不影响外层作用域
let arr = ["param1", "param2"]
let name = "window"
function fn(...arr) {
console.log(this.name, arr[0], arr[1]);
}
let obj1 = {
name: "obj1",
fn
}
let obj2 = {
name: "obj2",
}
obj1.fn.apply(obj2, arr)//obj2 param1 param2
4.new绑定绑定
:apply与call相同,会立即执行
被绑定的函数,同样也是软绑定
参数
:第一个参数也是绑定的对象,后面与call不同,apply传递的数组会解构
赋给函数的的形参
function fn(name) {
this.name = name
}
let obj = new fn("obj")
console.log(obj.name);
//obj
console.log(new fn("new"));
// {name:new}
用new去调用函数,会将该函数作为一个构造函数,把该函数的this指向一个新创建的对象,返回该对象5.箭头函数 可以与call中的例子对比
let name = "window"
function fn() {
let name = this.name
return () => {
console.log(name, this.name);
}
}
let obj1 = {
name: "obj1",
}
let obj2 = {
name: "obj2",
}
let func2 = fn.call(obj2)
func2() // obj2 obj2
func2.call(obj1) // obj2 obj2
let func1 = fn.call(obj1)
func1() //obj1 obj1
箭头函数没有自己的this
,它会使用上一层作用域的this
对箭头函数的绑定是没有效果的,修改指向需要修改上层作用域的this
推荐阅读
- 宽容谁
- 我要做大厨
- 增长黑客的海盗法则
- 画画吗()
- 2019-02-13——今天谈梦想()
- 远去的风筝
- 三十年后的广场舞大爷
- 叙述作文
- 20190302|20190302 复盘翻盘
- 学无止境,人生还很长