关于this指向
- 如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是
window。
var a="陇锦";
function foo() {
var a="掘金";
console.log(this.a);
console.log(this)
};
foo();
复制代码
- 如果一个函数中有this,这个函数被上一级的对象所调用,那么this指向的就是上一级的对象。
var a="陇锦";
var foo = {
a:"掘金",
fn:function(){
console.log(this.a);
}
};
foo.fn();
复制代码
- 如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的
var a={
b:"陇锦",
c:{
fn:function() {
console.log(this.b);
}
}
};
a.c.fn();
复制代码
- this指向永远都是最后调用他的对象,可以对比一下前面的例子。这里q被赋值为fn函数,运行q,他的this就会改变。
var a={
b:"陇锦",
c:{
fn:function() {
console.log(this.b);
console.log(this);
}
}
};
var q=a.c.fn;
q();
复制代码
当 this 碰到 return
- 如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。
function fn() {
this.b="陇锦";
return {
b:"掘金"
};
};
var a=new fn;
console.log(a.b);
复制代码
function fn() {
this.b="陇锦";
function (){}
};
var a=new fn;
console.log(a.b);
复制代码
- 但需要注意的是,虽然null也是对象,但是在这里this还是指向那个函数的实例,因为null比较特殊。
function fn() {
this.b = '陇锦';
return null;
}
var a = new fn;
console.log(a.user);
复制代码
如何改变this指向
- 通过new:用变量a创建了一个Fn的实例(相当于复制了一份Fn到对象a里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象a,
那么this指向的自然是对象a,那么为什么对象a中会有user,因为你已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份.
function Fn(){
this.b = "掘金";
}
var a = new Fn();
console.log(a.b);
复制代码
- call方法和apply方法
- 每个函数都包含两个非继承而来的方法:call()方法和apply()方法。
- 相同点:这两个方法的作用是一样的。都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。
window.color = 'red';
document.color = 'yellow';
var s1 = {color: 'blue' };
function changeColor(){
console.log(this.color);
};
changeColor.call();
changeColor.call(window);
changeColor.call(document);
changeColor.call(this);
changeColor.call(s1);
复制代码
window.number = 'one';
document.number = 'two';
var s1 = {number: 'three' };
function changeColor(){
console.log(this.number);
};
changeColor.apply();
changeColor.apply(window);
changeColor.apply(document);
changeColor.apply(this);
changeColor.apply(s1);
复制代码
- 不同点:接收参数的方式不同
- apply()方法 接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。
- 语法:apply([thisObj [,argArray] ]);,调用一个对象的一个方法,2另一个对象替换当前对象。
- 说明:如果argArray不是一个有效数组或不是arguments对象,那么将导致一个TypeError,如果没有提供argArray和thisObj任何一个参数,那么Global对象将用作thisObj。
- call()方法 第一个参数和apply()方法的一样,但是传递给函数的参数必须列举出来。
- 语法:call([thisObject[,arg1 [,arg2 [,...,argn]]]]);,应用某一对象的一个方法,用另一个对象替换当前对象。
- 说明: call方法可以用来代替另一个对象调用一个方法,call方法可以将一个函数的对象上下文从初始的上下文改变为thisObj指定的新
对象,如果没有提供thisObj参数,那么Global对象被用于thisObj。
function add(c,d){
return this.a + this.b + c + d;
}
var s = {a:1, b:2};
console.log(add.call(s,3,4));
console.log(add.apply(s,[5,6]));
复制代码
var a = {
user:"掘金",
fn:function(){
console.log(this.user);
}
};
var b = a.fn;
b.bind(a);
复制代码
- 我们发现代码没有被打印,因为bind方法返回的是一个修改过后的函数。
var a = {
user:"掘金",
fn:function(){
console.log(this.user);
}
}
var b = a.fn;
var c = b.bind(a);
console.log(c);
复制代码
var a = {
user:"掘金",
fn:function(){
console.log(this.user);
}
};
var b = a.fn;
var c = b.bind(a);
c();
复制代码
- 同样bind也可以有多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序进行的。
var a = {
user:"掘金",
fn:function(e,d,f){
console.log(this.user);
console.log(e,d,f);
}
};
var b = a.fn;
var c = b.bind(a,10);
c(1,2);
复制代码
- call和apply都是改变上下文中的this并立即执行这个函数,bind方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在
执行的时候添加,这是它们的区别
参考博客:追梦子blog http://www.cnblogs.com/pssp/
内容如有错误,欢迎指正。文章只写给需要的人,大牛忽略。