关于全局环境中的this指向,我们可以直接打印this:console.log(this); //输出window
在全局作用域中this指向的是window。
我们先看一个例子:
var name = "ygl";
function foo() {
var name = "qtb";
console.log(this.name); //打印ygl
console.log(this); //打印window
}
foo(); //等同于window.foo();
由上面的例子可以看到,最终打印的name并不是函数里声明的name的值,而是全局变量name的值,这里是因为,调用foo函数是全局调用的,因此this指向的是window。
再看一个例子:
var name = "ygl";
var obj = {
name: "qtb",
fn: function() {
console.log(this.name); //打印qtb
}
};
obj.fn();
这里的打印的结果是qtb,调用fn函数的是obj,因此this指向的是obj,由上面两个例子可以得出一个初步结论:
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象。
我们再来看一个例子:
var name = "ygl";
var obj = {
name: "qtb",
fn: function() {
console.log(this.name); //打印qtb
}
};
window.obj.fn();
这里最终是由window调用的,但是这里的打印结果是qtb,却不是我们想象中的ygl。上面的结果是错的吗?别着急我们接着往下看:
var obj = {
a: 10,
b: {
a: 12,
fn: function() {
console.log(this.a); //打印12
}
}
};
obj.b.fn();
这里的话最终是由obj调用的,按照上面的结论,理应打印出10,但是结果却是12。其实上面的结果并不是错误,只是不那么准确,一般分为三种情况:
1.如果一个函数有this,但是它没有被上一级对象所调用,那么它指向的就是window。在严格模式下指向的是undefined。
2.如果一个函数中有this,这个函数有被上一级所调用,那么它指向的就是调用它的对象。
3.如果一个函数中有this,且这个函数外层被多个对象包含,尽管最终这个函数是被最外层的对象所调用,this指向的也只是函数上一级的对象。
证明情况3的例子:
var obj = {
a: 10,
b: {
//a: 12,
fn: function() {
console.log(this.a); //打印undefined
}
}
};
obj.b.fn();
虽然函数fn最终是被obj调用,哪怕对象b中没有a这个属性,this指向的依然是对象b,所以打印的结果为undefined。
再来看一个例子:
var obj = {
a: 10,
b: {
a: 12,
fn: function() {
console.log(this.a);
console.log(this);
}
}
};
var j = obj.b.fn;
j();
这里的话this最终打印的是undefined,却不是我们想象中的12,这是因为我们重新声明变量j,并把fn函数赋值给它,最后执行函数j()的时候,调用j()是window对象。如果你不明白,说明你对这句话还不理解:
this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的。
JQ中的$(this)和原生的this的区别:
$(this)是jquery对象,能调用jquery的方法,例如click(), keyup()。
而this,则是html元素对象,能调用元素属性,例如this.id,this.value。
假设已经使得this和$(this)都指向了input对象了,若要获得input的值,可以this.value,但$(this)就得$(this).val()。
放一个2014年百度笔试题:
var myObject = {
foo:"bar",
func: function() {
var self = this;
console.log("outer func: this.foo = " + this.foo);
console.log("outer func: self.foo = " + self.foo);
(function (){
console.log("inner func: this.foo = " + this.foo);
console.log("inner func: self.foo = " + self.foo);
}());
}
};
myObject.func();
//这里会打印出什么?
2017.08.26更新:
补充知识点:
new操作符会改变this的指向,看如下代码:
function Test() {
this.name = "qtb";
}
var fn = new Test();
console.log(fn.name);
这里的Test是一个构造函数,原本的构造函数是window的方法,如果不用new操作符而直接调用构造函数的话,那么this指向的就是window,现在用了new操作符后this指向的就是新生成的对象。
用new操作符创建对象时有如下步骤:
1.创建一个Object对象实例;
2.将构造函数的执行对象赋给这个新生成的实例;
3.执行构造函数中的代码;
4.返回新生成的对象实例。
实际上面代码中的var fn = new Test();和var fn = new Object(); Test.apply(fn);是一样的效果。
如果你在本文中发现错误或者有异议的地方,可以在评论区留言,谢谢!