浅聊一下
舔狗处处有,js特别多。在js中,掘友们想必也见过this
这个舔狗。不过在我的多日观察后发现,他和普通的舔狗不太一样,那到底是哪里不一样呢?本文将带你深度窥探一下this
究竟在舔谁😍😍...
摸底
先向没见过this
的掘友们解释一下this
关键字。
js
function identify(context){
return context.name.toUpperCase()
}
function speek(context){
var greeting = "Hello,I'm" +identify(context);
console.log(greeting);
}
var me ={
name:"Tom"
}
speek(me)//Hello,I'm TOM
在上面这段代码中,就是我们日常写出来的最普通的方法,在方法中显示传递进去一个参数,再在方法里进行调用。 那这跟this
有什么关系呢?我们先用this
将上面的代码改进一下。
js
function identify(){
return this.name.toUpperCase()
}
function speek(){
var greeting = "Hello,I'm" +identify(this);
console.log(greeting);
}
var me ={
name:"Tom"
}
speek.call(me)//Hello,I'm TOM
掘友们可以看到,方法中的形参不见了!
this
关键字是用于引用当前执行上下文中的对象,它允许我们访问对象的属性和方法,创建新的对象实例,显式绑定函数的上下文,以及在箭头函数中继承父级作用域的"this"值。这使得JavaScript编程更加灵活和便捷
那些年,this舔过的女神
1. 默默舔
要说this
最爱的是谁,毫无疑问,那当然是window了,有小伙伴问我:何出此言?且听我细细道来...
js
function foo() {
var a=1
console.log(this.a);
}
var a = 2;
foo(); // 输出:2
按我们以前的套路来说,这里肯定是输出1啦~毕竟在foo中就可以找到a,又何必大费周章跑出去找a呢?
但是,答案是输出2,那是为什么呢?
原来,在默认条件下,我们的this对于函数的词法作用域爱的深沉...
他始终舔在了函数声明的词法作用域中,而这里foo声明在了全局,可想而知,输出的a当然等于2...
这就是默认绑定 --- 函数在哪个词法作用域里生效,this就指向哪里
2. 偷偷舔
this
绝对不是一个合格的舔狗,因为他还偷偷舔着别人...
this
偷偷找了一个对象obj
,obj
简直把他迷的神魂颠倒...
本来this是默认舔着全局的,这里全局并没有a变量,所以应该输出undefind
但是你若再问this:这里到底输出什么?他会跟你说: 2!!!!!!!!!!!!!!!!!!
这就是隐式绑定 --- 当函数被一个对象所拥有,再调用时,此时this会指向该对象
js
function foo(){
console.log(this.a);
}
var obj={
a:2,
foo:foo
}
obj.foo()
但是,你不要忘了,我说过this
绝对不是一个合格的舔狗🤡...给obj
舔着舔着舔丢了
js
var obj = {
a: 1,
foo: function() {
console.log(this.a);
}
};
var bar = obj.foo;
var a = 2;
bar(); // 输出:2
这里给bar赋值为对象obj中的foo方法,所以bar是一个函数
在全局定义一个a,当调用bar时,输出结果为全局的2,而并不是obj的1
这就是隐式丢失 --- 当函数被多个对象链式调用时,this指向引用函数的对象
3.明着舔
舔狗就是舔狗,相传有call bind apply
三大法宝
不管是谁,只要他们用这三大法宝对this
说:你快来舔我,速度速度
this
就会马上屁颠屁颠的跑过去
js
function foo(n){
console.log(this.a,n);
}
var obj = {
a:2
}
foo.call(obj,2)// 2 2
foo.apply(obj,[100])//用数组装参数 2 100
var bar = foo.bind(obj,100)//bind的执行结果返回一个函数体
bar(200)//2 100
本来,foo的中的this是默默舔着全局的,输出结果应该是undefined
但来了个obj,分别用call bind apply对this摧残了一遍...this不得不过去舔着他
于是输出结果为
2 2
2 100
2 100
显示绑定规则 --- 用call,apply,bind指定this指向
4.喜新厌旧地舔
什么叫喜新厌旧的舔,就是this爱舔new出来的对象
js
function Person(name, age) {
this.name = name;
this.age = age;
}
var person1 = new Person('Alice', 25);
console.log(person1.name); // 输出:Alice
console.log(person1.age); // 输出:25
在上述代码中,我们定义了一个构造函数 Person
,它接受 name
和 age
作为参数,并将它们分别赋值给 this.name
和 this.age
。然后,我们使用 new
关键字创建一个新的对象 person1
,并传入相应的参数。
在这个过程中,new
关键字会自动创建一个新的空对象,并将该对象绑定到 this
。接着,调用构造函数 Person
,并在这个构造函数的上下文中设置属性和方法。最后,返回新创建的对象。
这就是 new 绑定 --- this指向实例对象
this最后的倔强
this说:虽然我是一个舔狗,但是我也是一个有原则的舔狗,兔子还不吃窝边草呢!我也不吃
js
function foo(){//[[scope]]
var a = 2;
this.bar()
}
function bar(){
console.log(this.a);
}
我们可以看到,在foo方法中调用了bar
按照之前的默默舔来说,这里调用了全局的bar方法
那么我们应该输出的是undefined呀,可是结果是什么呢?
结果报错了!!!!!!
原来this觉得bar就是跟foo在同一个词法作用域的窝边草,于是this有了脾气,直接报错
this不能引用一个词法作用域中的内容
尾声
不得不说,this是一个善变的舔狗,但是看完本篇文章,相信不管遇到什么情况,你都能知道this在舔谁😍 (提醒一句:掘友们可千万不要当舔狗啊!!!)