JS中方法调用的陷阱

function F(){ function C(){ return this;}; return C(); } var a = new F(); alert(a == window);

通过对函数调用机制的学习,可以分析出上面变态笔试题的答案。

首先,函数调用有四种方式,主要是this的指向,然后return的方式

1. The Method Invocation Pattern,当函数为一个对象的属性时,此时的this指向的就是该对象

var myObject = { value:10, double:function(){ return this.value *= 2; } } alert(myObject.double());

2. The Function Invocation Pattern,当函数不是任何对象的属性时,此时的this指向的是global object,浏览器中是window

错误实例:

var myObject = { value:10, getValue:function(){return this.value;} } myObject.double = function(){ var multi = function(times){ //打开注解查看this值 //alert(this.value);//undefined //alert(this);//object //alert(this == window);//true return this.value *= times; } multi(this.value); } myObject.double(); alert(myObject.getValue());//10

对上述错误实例进行修改:

var myObject = { value:10, getValue:function(){return this.value;} } myObject.double = function(){ var thisObject = this; var multi = function(times){ return thisObject.value *= times; } multi(this.value); } myObject.double(); alert(myObject.getValue());//100

3. The Constructor Invocation Pattern,构造函数式的函数调用,this指向的是新创建的对象,使用new前缀的方式调用函数,会创建一个新对象,这个新对象有一个隐藏的链接指向该函数的prototype成员。

这种调用方式会改变return的行为:只要 new 表达式之后的 constructor 返回(return)一个引用对象(数组,对象,函数等),都将覆盖new创建的匿名对象,如果返回(return)一个原始类型(无 return 时其实为 return 原始类型 undefined),那么就返回 new 创建的匿名对象。

当使用第二种方式(The Function Invocation Pattern)调用构造函数时,会产生莫名其妙的问题

var House = function(add){ this.address = add; } House.prototype.getAdd= function(){ return this.address; }; var myHouse = new House("Beijing"); var err = House("Heaven"); alert(err);//undefined alert(myHouse.getAdd());//Beijing

如果在构造函数中return另一个对象,此时会丢掉new语义所生成的新对象

var House = function(add){ this.address = add; return new Date(); } House.prototype.getAdd= function(){ return this.address; }; var myHouse = new House("Beijing"); alert(myHouse.getAdd);//undefined alert(myHouse);//当前时间

4. The Apply Invocation Pattern,使用函数的apply方法,可以自定义this值

现在,我们可以清晰的分析开头提出的问题:

a. C()采用的是第二种方式调用,所以C函数中的this指向的是global object,此处就是window

b. var a = new F();是采用的第三种方式调用,并且return了一个对象,此时相当于采用的是第二种调用方式,所以a的值为C()返回的值,即window

c. 结论:这个问题输出的是true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值