引入this的初衷就是想在原型继承的情况下,拿到函数的调用者
this 指向的四种绑定方式是:默认绑定、隐式绑定、显示绑定、new 绑定四种
(1)在全局环境下 this 指向 window
(2)在函数独立调用的时候,this 指向 window;
(3)被嵌套的函数独立调用时,this 默认绑定到 window
(3)自执行函数,this 指向 window
(4)闭包中,this 默认指向 window
解释:
(1)因为全局变量和全局函数,都是挂载到 window 对象下的,打印 this 相当于用 window. 的方式调用
(2)独立调用, 就是函数调用模式 是 函数名(参数){}
, 不加任何其他的东西, 像对象 o.fuc() 就不是;
(4)闭包中的 this 重定向:由于闭包的 this 默认绑定到 window 对象,但又常常需要访问嵌套函数的 this,所以常常在嵌套函数中使用 var that = this,然后在闭包中使用 that 替代 this,使用作用域查找的方法来找到嵌套函数的 this 值
(1)被直接对象所包含的函数调用时,也称为方法调用,this 隐式绑定到该直接对象
隐式丢失
隐式丢失就是,之前隐式绑定不是 直接绑到调用它的直接对象上嘛,但这个对象又发生改变了,丢失了绑定对象,this 就又默认绑定到 window 上
(1) 为函数调用创建别名; 比如函数又被赋值到另一个变量上,这个变量跟这个函数的 this 没有关系,就会指向 window
function foo(){
console.log(this.a);
}
var obj={
a:2,
foo:foo
}
var bar=obj.foo;
var a="window";
bar()//window
(2)传入回调函数; 把函数当做参数传递到另一个函数中,也会发生隐式丢失的情况,父函数可以决定子函数的 this 指向
function foo(){
console.log(this.a);
}
function doFoo(fn){
fn();
}
var obj={
a:2,
foo:foo
}
var a="window";
doFoo(obj.foo)//window
(3)内置函数 setInterval 和 setTimeout,内部第一个参数的回调函数默认指向 window,因为这两个方法是 window 的方法
function setTimeout(fn,delay){
//等待delay毫秒
fn();
}
显示绑定就是用 call
, apply,
bind
方法用来改变 函数体内部的 this 指向
< 不同之处 >
它们在功能上是没有区别的,都是改变 this 的指向;
call
和 apply
方法都是在调用之后立即执行。而 bind
调用之后是返回原函数,需要再调用一次才执行call
和 bind
方法都是直接传入参数,而 apply
是以数组的形式传入;<body>
<script>
var obj = {
name: '静静',
objAge: this.age,
myFun: function () {
console.log(this.name + '年龄 ' + this.age);
}
}
var db = {
name: '小张',
age: 99
}
// 输出都是 "小张的年龄 99", 可以看到调用 obj.myFun 时其中的 this 本来应该指向 obj
// 我们通过 call, apply, bind 将 this 改向了 db, 就能获得 db 中的值了;
obj.myFun.call(db);
obj.myFun.apply(db);
obj.myFun.bind(db)();
</script>
</body>
<body>
<script>
var obj = {
name: '小颖',
objAge: this.age,
myFun: function (from, to) {
// 下面都打印: 小张年龄99, 来自成都, 去往上海
console.log(this.name + '年龄' + this.age + ', 来自' + from + ', 去往' + to);
}
}
var db = {
name: '小张',
age: 99
}
obj.myFun.call(db, '成都', '上海');
obj.myFun.apply(db, ['成都', '上海']);
obj.myFun.bind(db, '成都', '上海')();
</script>
</body>
< 实际应用 >
Object.prototype.toString.call()
Math.max.apply(null, arr);
和最小值 Math.min.apply(null, arr);
<script>
let arr = [10, 52, 6, 80];
let maxNum = Math.max.apply(null, arr);
console.log(maxNum); // 80
</script>
(1)new 构造函数中的 this 指向的是当前实例化的对象;
<script>
function Person(name, age) {
this.name = name;
this.age = age;
console.log(this); // Person {name: "Tom", age: 18}
}
var v1 = new Person('Tom', 18);
</script>
(2)箭头函数的 this 指向
箭头函数没有自己的 this, 它的 this 是继承而来的,是源于外层代码块中的 this,箭头函数的 this 是在定义函数时绑定的,函数在定义的时候,this 就继承了定义函数的对象;
箭头函数和普通函数的区别?