js中对this指向的理解
牢记:this是在函数执行的时候回才明确他的执行的上线文。
1.以函数的形式调用时,this永远都是window。比如fun();相当于window.fun();
2.以方法的形式调用时,this是调用方法的那个对象
3.以构造函数的形式调用时,this是新创建的那个对象
4.使用call和apply调用时,this是指定的那个对象
先看一下下面的例子
例1
var name = "The Window"; var object = { name: "My Object", getNameFunc: function () { return function () { return this.name; }; } }; console.log(object.getNameFunc()());
// The Window
object.getNameFunc()调用返回一个函数。再调用的时候指向window
例2
var name = "The Window"; var object = { name: "My Object", getNameFunc: function () { var that = this; return function () { return that.name; }; } }; console.log(object.getNameFunc()()); // My Object
相比于上面的代码,这个是用到了闭包,相当于我们在object对象中把this保存到一个变量that中,所以打印的是Object.
例3
function Foo() { getName = function () { alert (1); }; return this; } Foo.getName = function () { alert (2);}; Foo.prototype.getName = function () { alert (3);}; var getName = function () { alert (4);}; function getName() { alert (5);} //请写出以下输出结果: Foo.getName(); getName(); Foo().getName(); getName(); new Foo.getName(); new Foo().getName(); new new Foo().getName();
//2 4 1 1 2 3 3
解读代码:一共5句话:第一句定义了一个叫Foo的函数,第二句为Foo创建了一个叫getName的静态属性,存储了一个匿名函数;第三句为Foo的原型对象新创建了一个叫getName的匿名函数。第四句定义了一个函数表达式getName的函数,第五句声明了一个叫getName的函数。
在执行之前会进行变量的提升,函数的整体提升,注意Foo函数中的getName是全局变量
考察了 js运算符的优先级 ()> . >new . 为成员访问的意思。
输出:
1 Foo.getName();访问Foo函数存储的属性, 弹出2
2 getName(); 函数表达式变量提升,函数声明整体提升,表达式的赋值在下面,会覆盖函数声明的部分, 弹出 4
3 Foo().getName(); 先执行Foo函数,然后调用Foo函数的返回值对象的getName属性函数。
Foo函数的返回值为this,这里直接执行Foo函数,所以this指向window对象;所以这里相当于执行window.getName(),注意Foo函数中的getName是全局变量,当执行Foo函数的时候会重新给getName赋值,也就是alert(4)函数,将此变量的值赋值为 function(){alert(1)}。 弹出1
4 getName();因为第三步在执行Foo函数的时候已经重新给getName赋值,所以 弹出 1
5 new Foo.getName();这里考察了js中的元素符 实际上应该是new(Foo.getName)();这里把Foo.getName函数当做了构造函数来执行,访问Foo函数存储的属性, 弹出2
6 new Foo().getName(); 这里相当于(new Foo()).getName();执行前面一部分
(new Foo()),有返回值,返回的类型为this,而this在构造函数中代表的是当前实例化对象,然后调用的是实例化对象的getName函数,(而本题中没有给实例化对象添加任何属性(因为构造函数的后面的小括号里面灭有传任何参数))所以会到当前对象的原型对象上去寻getName,所以弹出是3 。
关于构造函数的返回值:
1 没有返回值则按照其他语言一样返回实例化对象。
2 若有返回值检查返回值是否为引用类型。若是基本类型,则与无返回值相同,实际返回歧视例化对象;若是引用类型,则实际返回值为这个引用类型
7 new new Foo().getName();同第6问,弹出的为3
。。。。。仅仅作为了解this。。。。
例4
function A(x){ this.x = x; } A.prototype.x = 1; function B(x){ this.x = x; } B.prototype = new A();//这句意思是B的实例的原型对象为A;继承了A的原型中 的属性 var a = new A(2), b = new B(3); delete b.x; console.log(a.x) console.log(b.x)
代码执行完以后,a.x和b.x的结果是什么?分别为:2,undefined
第一个输出为2,直接给构造函数A传进去一个参数(2),输出为2,没有问题。
第二个输出为undefined,delete表示的是把B上的x属性被删除了,所以会去原型链上去找,B继承A,先去A的内部找,找到了为undefined。