零
// 函数直接调用
function get(content){
console.log(content)
}
get('Nice')
// 等同于
get.call(window,.Nice)
// 作为对象的方法调用
var person = {
name:"zwj",
say:function(){
console.log(this.name)
},
Hello:function(fn){
fn() // 函数直接使用 fn.call(window)
}
}
person.say()
// 等同于
person.call(person)
一、默认绑定
全局环境中,this默认绑定到window函数独立调用时,this默认绑定到window被嵌套的函数独立调用时,this默认绑定到window
函数独立调用
// 默认绑定(全局范围)
function fn(){
console.log(this)
}
fn() // windwo
被嵌套的函数独立嵌套调用
var name = "summer";
var person = {
name : "zwj",
sayName:function(){
function test(){
console.log(this.name); //summer
}
test();
}
}
person.sayName();
//=================================
// 等同于下方的立即执行函数
var name = "summer";
var person = {
name : "zwj",
sayName:function(){
(function test(){
console.log(this.name); //summer
})()
// test()
}
}
person.sayName();
闭包
var name = "summer";
var person = {
name : "zwj",
sayName:function(){
// 闭包的this指向是window 此时可以使用变量将this保存下来
// var that = this;
return function test(){
console.log(this.name); // summer
// console.log(that.name); // zwj
}
}
}
console.log(person.sayName())
//test(){
// console.log(this.name);
// }
console.log(person.sayName()())
// summer
二、隐式绑定
被直接对象所包含的函数调用时,也称为方法调用,this隐式绑定到该直接对象
// 隐式绑定 this指向调用对象
var people = {
name:"zwj",
age:18,
detail(){
console.log(this)
console.log('姓名:'+this.name)
console.log('年龄:'+this.age)
}
}
people.detail()
隐式丢失
函数别名
隐式丢失是指被隐式绑定的函数丢失绑定对象,从而默认绑定到window
var name ="summer"
var age =50
var people = {
name:"zwj",
age:18,
detail(){
console.log('姓名:'+this.name)
console.log('年龄:'+this.age)
}
}
var other = people.detail
other()
// ============================
// 等同于下方代码部分
var other = detail(){
console.log('姓名:'+this.name)
console.log('年龄:'+this.age)
}
other()
传递参数
var a = 0;
function foo(){
console.log(this.a);
};
function bar(fn){
fn();
}
var obj = {
a : 2,
foo:foo
}
//把obj.foo当作参数传递给bar函数时,有隐式的函数赋值fn=obj.foo。与上例类似,只是把foo函数赋给了fn,而fn与obj对象则毫无关系
bar(obj.foo);//0
三、显式绑定
通过call()、apply()、bind()方法把对象绑定到this上
// 硬绑定
var person = {
name:"zwj",
age:18,
sayName(){
console.log('我的名字是:'+this.name)
}
}
var personOne = {
name:"Henry"
}
var personTwo = {
name:"Bucky"
}
// 使用call、apply绑定this的指向
person.sayName.call(personOne) // 我的名字是:Henry
person.sayName.call(personTwo) // 我的名字是:Bucky
person.sayName.apply(personOne) // 我的名字是:Henry
person.sayName.apply(personTwo) // 我的名字是:Bucky
四、构造函数绑定
// 构造函数绑定
function showPerson(name){
this.name = name
this.sayName = function(){
console.log('我的名字是:'+this.name)
}
}
var name = 'Summer'
var Bingo = new showPerson('Bingo')
Bingo.sayName() // 我的名字是:Bingo
五、严格模式
严格模式下,独立调用的函数的this指向undefined
function fn(){
'use strict';
console.log(this);//undefined
}
fn();
function fn(){
console.log(this);//window
}
fn();
练习
function a(){
function b(){
// 没有明确指明调用的对象 默认绑定 全局 window
console.log(this)
function c(){
"use strict";
// 严格模式下 undefined
console.log(this)
}
c()
}
b()
}
a()
var name = "小白"
function special(){
console.log('姓名3:' + this.name) // 小红
}
var person = {
name:'小红',
detail(){
console.log('姓名1:'+this.name) // 小红
},
other:{
name:'小黄',
detail(){
console.log('姓名2:'+this.name) // 小黄
}
},
special:special
}
// 隐式绑定 this指向调用对象 person调用detail方法
person.detail()
person.other.detail()
// person调用special方法 this指向person对象 调用person对象的name
person.special()
var name = "小红"
function a(){
var name = "小白"
console.log('姓名1:'+this.name)
}
function d(i){
return i()
}
var b = {
name:"小黄",
detail(){
console.log('姓名2:'+this.name)
},
bibi(){
return function(){
console.log('姓名3:'+this.name)
}
}
}
var c = b.detail;
b.a = a
var e = b.bibi()
// 全局调用a方法(window)、this.name = 小红
a()
// 因为前面 var c = b.detail; 所以此时相当于 c 就相当于只是个函数 detail(){} 全局 this.name = 小红
c()
// 此时就是b调用了方法 a 此时的this指向b this.name = 小黄
// var b = { a:function(){var name = "小白" console.log('姓名1:'+this.name)}}
b.a()
// d函数内部传递过去 b.detail 直接执行b.detail 全局下的d调用 this.name = 小红
d(b.detail)
// 因为 var e = b.bibi() 所以此时的e() = function(){console.log('姓名3:'+this.name) } 全局调用 所以 this.name =小红
e()
var name = 222
var a = {
name:111,
say:function(){
console.log(this.name)
}
}
var fun = a.say // fun 赋值 a.say的方法
fun() // 222 全局调用 指向window
a.say() // 111 // 谁调用 指向谁 a.name = 111
var b = {
name:333,
say:function(fn){
fn()
}
}
b.say(a.say) //222 立即执行函数 指向window
b.say =a.say // 将a的say方法 赋值给b的say方法
b.say() // 333 谁调用 指向谁 b.name = 333
本文深入探讨了JavaScript中this的绑定规则,包括默认绑定、隐式绑定、显式绑定、构造函数绑定和严格模式下的行为。通过实例分析了函数调用的各种情况,如独立调用、作为对象方法调用、闭包以及方法别名和参数传递时this的指向变化。同时,文章还介绍了如何通过call、apply、bind方法强制改变this的绑定,并提供了相关练习题加深理解。
427

被折叠的 条评论
为什么被折叠?



