JS函数中的this指向(上)
1、this在全局作用域下
①this在浏览器中测试就是指向window(GlobalObject)
②在node环境中,打印this,是一个空对象 { }
2、this在函数中使用
函数在调用时,this指向什么,和定义的位置(编写的位置)没有关系,
与函数调用的方式有关
案例:
function foo() {
console.log(this);
}
// 1.直接调用这个函数
foo(); //window对象
// 2.创建一个对象, 对象中的函数指向foo
var obj = {
name: "why",
foo: foo,
};
obj.foo(); //obj对象
// 3.apply调用
foo.apply("abc"); //String {'abc'}
3、绑定规则
3.1、规则一:默认绑定(独立函数调用):
可以理解成函数没有被绑定到某个对象上进行调用;
this就是指向window对象
案例:
// 1.案例一:
function foo() {
console.log(this);
}
foo(); //window
// 2.案例二:
function foo1() {
console.log(this); //window
}
function foo2() {
console.log(this); //window
foo1();
}
function foo3() {
console.log(this); //window
foo2();
}
foo3();
// 3.案例三:
var obj = {
name: "fifi",
foo: function () {
console.log(this);
},
};
var bar = obj.foo;
bar(); // window
// 4.案例四:
function foo() {
console.log(this);
}
var obj = {
name: "fifi",
foo: foo,
};
var bar = obj.foo;
bar(); // window
// 5.案例五:
function foo() {
function bar() {
console.log(this);
}
return bar;
}
var fn = foo();
fn(); // window
var obj = {
name: "fifi",
eating: fn,
};
obj.eating(); // 隐式绑定 obj对象
3.2、 规则二 :隐式绑定:
通过某个对象进行调用的;也就是它的调用位置中,是通过某个对象发起的函数调用。
this指向调用这个函数的对象
扫描二维码关注公众号,回复:
15657407 查看本文章
隐式绑定的一个前提条件:必须在调用的对象内部有一个对函数的引用(比如一个属性)
如果没有这样的引用,在进行调用时,会报找不到该函数的错误;正是通过这个引用,间接的将
this绑定到了这个对象上;
隐式绑定:object.fn()
object对象会被js引擎绑定到fn函数的中this里面
案例:
// 1.案例一:
function foo() {
console.log(this);
}
var obj = {
name: "fifi",
foo: foo,
};
obj.foo(); // obj对象
// 2.案例二:
var obj = {
name: "fifi",
eating: function () {
console.log(this.name + "在吃东西");
},
running: function () {
console.log(obj.name + "在跑步");
},
};
obj.eating(); //fifi在吃东西
obj.running(); //fifi在跑步
var fn = obj.eating;
fn(); //独立函数调用 //在吃东西
// 3.案例三:
var obj1 = {
name: "obj1",
foo: function () {
console.log(this);
},
};
var obj2 = {
name: "obj2",
bar: obj1.foo,
};
obj2.bar(); //obj2
3.3、 规则三:显式绑定:call、apply、bind
(不希望在 对象内部 包含这个函数的引用,同时又希望在这个对象上进行强制调用),这三个可以指定this绑定的对象
call和apply 的区别:
第一个参数相同,都是传入想让this绑定的对象,
后面的参数,apply通过数组的形式传入,call通过参数列表的形式传入
//call和apply有什么区别?
function sum(num1, num2, num3) {
console.log(num1 + num2 + num3, this);
}
sum.call("call", 20, 30, 40); //90 String {'call'}
sum.apply("apply", [20, 30, 40]); //90 String {'apply'}
案例:
//案例一:
function foo() {
console.log("函数被调用了", this);
}
var obj = {
name: "obj",
};
// call / apply是可以指定this的绑定对象;
foo.call(obj); //函数被调用了 (obj对象){name: 'obj'}
foo.apply(obj); //函数被调用了 obj对象
foo.apply("aaaa"); // 函数被调用了 String {'aaaa'}
//案例二:
function foo() {
console.log(this);
}
foo.call("aaa"); //String {'aaa'}
// 默认绑定和显示绑定bind冲突: 优先级(显示绑定)
var newFoo = foo.bind("aaa");
newFoo(); //String {'aaa'}
var bar = foo;
console.log(bar === foo); //true
console.log(newFoo === foo); //false
3.4、 规则四:new绑定:
通过一个new关键字调用一个函数时(这个函数可以当作一个类的构造器),
这个时候this是在调用这个构造器时创建出来的对象,this指向创建出来的对象
案例:
function Person(name, age) {
this.name = name;
this.age = age;
}
var p1 = new Person("fifi", 18);
console.log(p1.name, p1.age); //fifi 18
var p2 = new Person("haha", 30);
console.log(p2.name, p2.age); //haha 30