小学生

- 金币
- 110
- 好评
- 0
- 信誉
- 100

|
1.this指向的几条规律
在函数体中,非显式或隐式地简单调用函数时,在严格模式下,函数内的this会被绑定到undefined上,在非严格模式下则会被绑定到全局对象window/global 上。
一般使用new方法调用构造函数时,构造函数的this会被绑定到新创建的对象上。
一般通过call/apply/bind 方法显式调用函数时,函数体内的this会被绑定到指定参数的对象上。
一般通过上下文对象调用函数时,函数体内的this会被绑定到该对象上。
在箭头函数中,this的指向是由外层(函数或全局)作用域来决定的。
2.探究函数中的this
function f1(){
console.log(this);
}
function f2(){
'use strict'
console.log(this);
}
f1();//window
f2();//undefined
示例1
var test = {
value :100,
fn:function(){
console.log(this); //window
console.log(this.value); //undefined
console.log(this.test.value) //100
}
}
var test2 = test.fn;//赋值给test2后,test2仍然是在window的全局环境中执行的
test2();
示例2
var test = {
value :100,
fn:function(){
console.log(this); //{value: 100, fn: ƒ}
console.log(this.value); //100
}
}
test.fn();//在test上调用fn()函数,this指向test
3.通过bind、call、apply改变this指向
var name = '张三',age = 26;
var obj = {
name:'李四',
age:this.age,
fn:function(var1,var2){
console.log(this.name + '年龄是'+this.age,'喜欢的运动:'+var1+',喜欢的水果:'+ var2);
}
}
var data = {
name:'王五',
age : 22
}
obj.fn.call(data,'羽毛球','苹果');//王五年龄是22 喜欢的运动:羽毛球,喜欢的水果:苹果
obj.fn.apply(data,['羽毛球','苹果']);//王五年龄是22 喜欢的运动:羽毛球,喜欢的水果:苹果
obj.fn.bind(data,'羽毛球','苹果')();//王五年龄是22 喜欢的运动:羽毛球,喜欢的水果:苹果
bind返回的是一个函数,你必须调用它才会被执行。
4.构造函数和this
function Foo(){
this.user = 'lucy';
const o = {};
return o;
}
var instance = new Foo();
console.log(instance.user);//undefined
以上示例 instance返回一个空对象
function Foo(){
this.user = 'lucy';
return 1;
}
var instance = new Foo();
console.log(instance.user);//lucy
以上示例 instance返回的是目标对象示例 this。
从以上两个示例,可以得出:
如果构造函数中显式返回一个值,且返回的是一个对象,那么this就指向这个返回的对象;如果返回的不是一个对象,那么this仍然指向实例。
5.箭头函数中的this
var foo = {
fn:function(){
setTimeout(function(){
console.log(this);
})
}
}
console.log(foo.fn());
this指向window对象
var foo = {
fn:function(){
setTimeout(()=>{
console.log(this);
})
}
}
console.log(foo.fn());
箭头函数使得this指向foo这个对象
箭头函数中this指向是由其所属函数或全局作用域决定的
6.this优先级
示例1
function foo(a){
console.log(this.a);
}
var obj1 = {
a:1,
foo:foo
}
var obj2 = {
a:2,
foo:foo
}
obj1.foo.call(obj2);//2
obj2.foo.call(obj1);//1
call,apply的显示绑定一般来说优先级更高。
示例2
function foo(a){
this.a = a;
}
var obj1 = {};
var bar = foo.bind(obj1);//将foo方法绑定到obj1对象中
bar(2);
console.log(obj1.a);//2
通过bind将bar函数中的this绑定为obj1对象。执行bar(2)后,obj1.a的值为2,即执行bar(2)后,obj1的对象为{a:2}
那我们再执行以下代码
var bar2 = new bar(3);
console.log(bar2.a)//3
被new调用的时候,返回的实例已经与obj1解绑了,也就是new绑定修改了bind绑定的this指向
示例3
function foo(){
return a=>{
console.log(this.a);
}
}
var obj1 = {
a:2
}
var obj2 = {
a:3
}
var bar = foo.call(obj1);
console.log(bar.call(obj2));//2
由于foo中的this被绑定到了obj1,所以bar中的this也会被绑定到obj1上,箭头函数的绑定无法被修改。
实例4
var a = 123;
var foo = () => a =>{
console.log(this.a)
}
var obj1 = {
a:2
}
var obj2 = {
a:3
}
var bar = foo.call(obj1);
console.log(bar.call(obj2));//123
foo修改为完全箭头函数,foo.call(obj1)无法改变this的指向。 |
|