this的指向性问题
1.默认绑定
独立的函数调用我们可以理解成函数没有被绑定到某个对象上进行调用;
主要看在函数调用的位置有没有对函数进行绑定
一般 直接调用函数,函数被当成参数调用,函数链式调用 都是没有绑定对象的
2.隐式绑定
一般是指 某个对象调用了函数,就会被隐式绑定到该对象上面
PART1:
function foo() {
console.log(this); // obj对象
}
var obj = {
name: "why",
foo: foo
}
obj.foo();
PART2:
function foo() {
console.log(this); // obj1对象
}
var obj1 = {
name: "obj1",
foo: foo
}
var obj2 = {
name: "obj2",
obj1: obj1
}
obj2.obj1.foo();
PART3:隐式丢失
function foo() {
console.log(this);
}
var obj1 = {
name: "obj1",
foo: foo
}
// 将obj1的foo赋值给bar
var bar = obj1.foo;
bar();
3.显式绑定
3.1 call、apply、bind函数
通过apply call bind函数来改变 this的指向
apply和call的区别,第一个参数都是传递需要改成的this对象,apply方法的第二个参数是传递一个数组
call方法第二个参数是传递一个参数列表
function foo() {
console.log(this);
}
foo.call(window); // window
foo.call({name: "why"}); // {name: "why"}
foo.call(123); // Number对象,存放时123
bind方法是返回一个函数,并且这个函数不会执行
传入参数为 null 或者undefined的时候,会绑定到全局对象
3.2内置函数
在setTimeout中 this的指向通常是window
在forEach() 中,this的指向为 window
4.new绑定
JavaScript中的函数可以当做一个类的构造函数来使用,也就是使用new关键字。
使用new关键字来调用函数时,会执行如下的操作:
- 1.创建一个全新的对象;
- 2.这个新对象会被执行Prototype连接;
- 3.这个新对象会绑定到函数调用的this上(this的绑定在这个步骤完成);
- 4.如果函数没有返回其他对象,表达式会返回这个新对象;
// 创建Person
function Person(name) {
console.log(this); // Person {}
this.name = name; // Person {name: "why"}
}
var p = new Person("why");
console.log(p);
5.规则的优先级
1.默认绑定规则优先级最低
2.显示绑定优先级高于隐式绑定
3.new绑定优先级高于隐式绑定
4.new绑定优先级高于bind
new绑定和call、apply是不允许同时使用的,所以不存在谁的优先级更高