this的指向
Posted y-dt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了this的指向相关的知识,希望对你有一定的参考价值。
this的指向
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象,因不好理解,下面以实例来说明
this的情景
- 当函数作为对象的方法调用时,this指向该对象。
var person = {
a: function(){
console.log(this);
}
}
person.a(); // person{a: ?}
window.person.a(); //person{a: ?}
这里a()是由person调用的,所以this就是person。
window.person实质就是window对象的person属性,所以a()还是由person所调用。
另外一个例子:
var person = {
a: this
}
person.a; //window
this没有被函数调用,所以默认指向了window。
- 当函数直接被调用时,this指向全局对象,即window对象
function person(){
console.log(this);
}
person(); //Window
也不难理解,因为person()的调用是在全局中,也就相当于:
window.person() === person(); //true
所以在person里定义的this.xx,其实都是全局变量。
- 构造函数中的this指向新创建的对象(使用new调用,不用new就和2情景相同)
function Person(){
console.log(this);
}
var yan = new person();
yan; //Person{}
- 嵌套函数中的this不会继承上层函数的this,如果需要,可以用一个变量保存上层函数的this
var person = {
out : function() {
var that = this;
// 内部函数
var inside = function() {
console.log(that);
console.log(this);
};
inside();
}
};
person.out();
//person{out: ?}
//window
- 如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的
对象所调用,this指向的也只是它上一级的对象
var person = {
one:{
fn:function(){
console.log(this);
}
}
}
person.one.fn(); //one{fn: ?}
依旧实质为one对象调用了fn()。
特殊情况:将方法赋值后调用
var y = person.one.fn();
y(); //window
开头说过,this在定义时是无效的,最终还是要看调用对象,上面的赋值操作并没有执行函数,所以y()就相当于函数的直接调用,即window.y()。
所以在借用对象方法的时候,就需要改变this的指向,例如:y.call()的形式。
setInterval等window方法的this,指向就是window,因其被window调用
this总结
无论this在哪个位置,只要找到它的调用对象即可。
箭头函数的this
箭头函数是==没有this==的,所以它的this实际上是外层代码的this。
call/apply方法与this
改变函数的this的指向
apply与call只是传参的形式有区别。
apply 方法传入两个参数:一个是作为函数上下文的对象,另外一个是作为函数参数所组成的数组。
call 方法第一个参数也是作为函数上下文的对象,但是后面传入的是一个参数列表,而不是单个数组。
对于什么时候该用什么方法,其实不用纠结。如果你的参数本来就存在一个数组中,那自然就用 apply,如果参数比较散乱相互之间没什么关联,就用 call
apply 和 call 的用法
1. 改变 this 指向
var obj = {
name: ‘yan‘
}
function func() {
console.log(this.name);
}
func.call(obj); // yan
我们知道,call 方法的第一个参数是作为函数上下文的对象,这里把 obj 作为参数传给了 func,此时函数里的 this 便指向了 obj 对象。此处 func 函数里其实相当于
function func() {
console.log(obj.name);
}
2. 借用别的对象的方法
var Person1 = function () {
this.name = ‘yan‘;
}
var Person2 = function () {
this.getname = function () {
console.log(this.name);
}
Person1.call(this);//调用Person1的构造函数
}
var person = new Person2();
person.getname(); // yan
从上面我们看到,Person2 实例化出来的对象 person 通过 getname 方法拿到了 Person1 中的 name。因为在 Person2 中,Person1.call(this) 的作用就是使用 Person1 对象代替 this 对象,那么 Person2 就有了 Person1 中的所有属性和方法了,相当于 Person2 继承了 Person1 的属性和方法。
3. 调用函数
apply、call 方法都会使函数立即执行,因此它们也可以用来调用函数。
function func() {
console.log(‘yan‘);
}
func.call();//yan
bind方法与this
它和 call 很相似,接受的参数有两部分,第一个参数是是作为函数上下文的对象,第二部分参数是个列表,可以接受多个参数。
call 和 bind 的区别
1. bind 返回值是函数
var obj = {
name: ‘yan‘
}
function func() {
console.log(this.name);
}
var func1 = func.bind(obj);
func1();// yan
2. 参数的使用
function func(a, b, c) {
console.log(a, b, c);
}
var func1 = func.bind(null,‘yan‘);
func(‘A‘, ‘B‘, ‘C‘);// A B C
func1(‘A‘, ‘B‘, ‘C‘);// yan A B
func1(‘B‘, ‘C‘);// yan B C
func.call(null, ‘linxin‘);// yan undefined undefined
call 是把第二个及以后的参数作为 func 方法的实参传进去,而 func1 方法的实参实则是在 bind 中参数的基础上再往后排。
以上是关于this的指向的主要内容,如果未能解决你的问题,请参考以下文章
ngx-translate实现国际化:this.translate.use()this.translate.get()this.translate.instant()onLangChange(代码片段
在 webview_flutter 中启用捏合和缩放,在哪里添加代码片段 [this.webView.getSettings().setBuiltInZoomControls(true);]