JavaScript中this的绑定

this绑定的规则

1.默认绑定

独立函数调用

foo(){
console.log(this)
}
foo() //window

在浏览器中foo()函数时保存在window对象中,所以指向的是window

function test() {
  console.log(this);//window
}
function test1() {
  console.log(this);//window
  test();
}
function test2() {
  console.log(this); //window
  test1();
}
test2();

同理test2也是保存在window对象中,是window对象调用了test2函数,所以当前的this指向的是window,但是test1函数的执行还是window调用的,当前的this还是指向window

2.隐式绑定

通过某个对象发起的函数调用

function foo() {
  console.log(this); //obj
}
var obj = {
  foo: foo,
};
obj.foo();

这里的函数调用是obj调用的,所以指向的是obj

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

这里的foo的调用还是指向的是obj,因为foo函数是obj调用的,obj1调用obj,obj又调用了foo,所以当前的this指向还是obj

3.显示绑定

  • 必须在调用的对象内部有一个对函数的引用(比如一个属性)
  • 如果没有这样的引用,在进行调用时,会报找不到该函数的错误
  • 正是通过这个引用,间接的将this绑定到了这个对象上
//通过apply绑定
function foo(num1, num2) {
  console.log(this);
  console.log(num1 + num2);
}
//第一个参数表示的是需要绑定的this,可以是任意的数据类型
 //apply调用函数的参数是放在数组中
foo.apply("bbbb", [20, 30]);//“bbbb”
//通过call调用
function foo(num1, num2) {
  console.log(this);
  console.log(num1 + num2);
}
//第一个参数表示的是需要绑定的this,可以是任意的数据类型
//call调用函数的参数直接写
foo.call("aaa", 20, 30); //“aaa”
//通过bind调用
function foo(num1, num2) {
  console.log(this);
  console.log(num1 + num2);
}
var bar = foo.bind("adc", 30, 20); //bind绑定this之后返回一个函数
bar();

4.new绑定

//new绑定
function Person(name, age) {
 console.log(this); //person{}
  this.name = name;
  this.age = age;
}

var p1 = new Person("jack", 18);
console.log(p1);//person{name:"jack",age:18}
console.log(p1.name, p1.age);

通过new关键字来创建一个新的类,创建出来的类的this会绑定返回时的对象

一些其他的函数this指向

定时器

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

可以理解为独立函数的调用

DOM事件监听

const boxdiv = document.querySelector('.box');
boxdiv.addEventListener('click', function () {
  console.log(this);//boxdiv元素
});
boxdiv.onclick = function () {
  console.log(this);//boxdiv元素
};

数组foreach,map

var names = ['jack', 'mask', 'kobe'];
names.forEach(function (item) {
  console.log(item, this); //item+window
});//这里添加第二个参数可以指定this的指向

names.map(function (item) {
  console.log(item, this); //item+window
});//这里添加第二个参数可以指定this的指向

规则的优先级

1.默认绑定的优先级最低
2.显示高于隐式绑定

  • call和apply
var obj = {
  foo: function () {
    console.log(this);
  },
};
obj.foo.call('adc'); //string{"adc"} ,apply也是一样的
  • bind
function foo() {
  console.log(this);
}
var obj = {
  foo: foo.bind('adc'),
};
obj.foo();//string{"adc"} 
  1. new高于隐式绑定
var obj = {
  foo: function () {
    console.log(this);
  },
};
var bar = new obj.foo();//foo函数
  1. new高于显示绑定
    new和call/apply都是主动调用改变的this的指向,所以一般不会同时使用,这里用new和bind进行实验
function foo() {
  console.log(this);
}
var bar = foo.bind('adc');

var ad = new bar();//foo函数

new > 显示绑定>隐式绑定>默认绑定(独立函数调用)

5.其他的一些绑定

call/apply/bind绑定null/undefined

var obj = {
  foo: function () {
    console.log(this);
  },
};
obj.foo.call(null);//window
obj.foo.apply(undefined);//window
var bar = obj.foo.bind(null);//window
bar();

间接函数的引用

var obj = {
  foo: function () {
    console.log(this);
  },
};

var obj1 = {
  name: 'jack',
};
(obj.bar = obj.foo)();//window,可以理解为独立函数的调用
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容