什么是this?
this是函数内部的另一个对象,this引用的是函数执行的环境对象,换句话说,哪个对象执行这个函数,函数的this就指向谁!
window.color="blue";
var o={
color:"red" //字面量只有一行不能用引号
};
function sayColor(){
alert(this.color);
}
sayColor();
//sayColor.call(o);
o.sayColor=sayColor;//把函数赋给对象o
//函数不带括号相当于变量指针
o.sayColor();
sayColor();
的执行环境是window,此时的this指向window,变量sayColor赋给o(函数名相当于指针)然后执行。
其实这里也可以通过sayColor的call方法,前面说了,this是函数内的一个对象,call()
实际上等于设置函数体内this对象的值,那么如果执行sayColor.call(o)
代表this指向了o。
隐式原型和instanceof
原型链和继承
所有的对象的原型链都会找到Object.prototype,因此所有的对象都会有Object.prototype的方法。这就是所谓的“继承”。
执行上下文
一段js代码拿过来真正一句一句运行之前,浏览器已经做了一些“准备工作”
在“准备工作”中完成了哪些工作:
变量、函数表达式——变量声明,默认赋值为undefined;
this——赋值;
函数声明——赋值;
这三种数据的准备情况我们称之为“执行上下文”或者“执行上下文环境”。
全面理解this
在一个函数上下文中,this由调用者提供,由调用函数的方式来决定。如果调用者函数,被某一个对象所拥有,那么该函数在调用时,内部的this指向该对象。如果函数独立调用,那么该函数内部的this,则指向undefined。但是在非严格模式中,当this指向undefined时,它会被自动指向全局对象。
var a = 20;
var foo = {
a: 10,
getA: function () {
return this.a;
}
}
console.log(foo.getA()); // 10
var test = foo.getA;
console.log(test()); // 20
foo.getA()中,getA是调用者,他不是独立调用,被对象foo所拥有,因此它的this指向了foo。而test()作为调用者,尽管他与foo.getA的引用相同,但是它是独立调用的,因此this指向undefined,在非严格模式,自动转向全局window。
构造函数与原型方法上的this
function Person(name, age) {
// 这里的this指向了谁?
this.name = name;
this.age = age;
}
Person.prototype.getName = function() {
// 这里的this又指向了谁?
return this.name;
}
// 上面的2个this,是同一个吗,他们是否指向了原型对象?
var p1 = new Person('Nick', 20);
p1.getName();
我们已经知道,this,是在函数调用过程中确定,因此,搞明白new的过程中到底发生了什么就变得十分重要。
通过new操作符调用构造函数,会经历以下4个阶段。
创建一个新的对象;
将构造函数的this指向这个新对象;
指向构造函数的代码,为这个对象添加属性,方法等;
返回新对象。
因此,当new操作符调用构造函数时,this其实指向的是这个新创建的对象,最后又将新的对象返回出来,被实例对象p1接收。因此,我们可以说,这个时候,构造函数的this,指向了新的实例对象,p1。
而原型方法上的this就好理解多了,根据上边对函数中this的定义,p1.getName()中的getName为调用者,他被p1所拥有,因此getName中的this,也是指向了p1。