前端笔试题网易之一-js函数体内的名称解析问题

这是师姐去年去网易面试时遇到的一个问题。

function A(){

alert(a);

var a=10;

alert(this.a);

}

A();//undefined undefined

new A();//undefined  undefined

为什么两个都是undefined?

   我认为这是涉及打了函数体内的变量名称解析的问题。

    首先看第一个A();这个是在全局作用域中调用A函数,和普通的函数调用一样,此时的函数A作为了全局变量window对象的方法被调用,所以此时this指向的是window,由于window对象中没有一个名称为a的属性,所以alert(this.a)为undefined。为什么第一个alert(a)也为undefined,是因为在调用A函数之前,读取A函数的方法体,发现声明了变量a,于是将a放到了作用域的前端(但是没有初始化a,等到执行var a=10;这句语句时,才初始化a,这就是变量声明提升),所以第一个alert为undefined。

   如果我在window全局变量中放入一个属性a,那么,this.a就只向了window全局变量中a,alert 20.

       var a=20;
function A(){
alert(a);
var a=10;
alert(this.a);
}
A();//undefined 20

总结:在一个函数体内直接调用变量名alert(a)和alert(this.a)是不一样的,前者是在作用域链中搜寻对应的变量,而通过this.属性进行访问变量,该函数被作为哪个对象的方法被调用,就在this就指向该对象,就在该对象中搜索该属性(准确的说是在该对象的原型链中搜索该属性,下面会细讲),也就是说this.属性 的值和作用域没有关系,由于js中没有类域的概念(在java中在一个类中声明的实例变量a,那么在这个类中this.a 和a 是一样的),所以想要访问当前对象的属性,必须通过this.属性 ,否则访问的都只是函数的作用域中的变量。如下面的例子:

var a=20;

function A(){
alert(a);
var a=10;
alert(this.a);//通过this.属性或方法,是在原型链上进行解析的
}
//A();
var o={
a:1000
};
o.A=A;
o.A();//undefined 1000

看第二个语句   new A();在js中执行一个new方法时(实际上要进行四个步骤的操作,详见我的下一篇文章《new一个对象,需要几步?》):首先需要创建一个对象,然后将构造函数的作用域复制给该对象,此时的this实际就执向了该对象,然后再执行构造函数,最后返回这个对象。为了更加明确的说明this的指向以及this.属性的查找,我换了一个使用了继承的例子。

alert(this.a);//1000,该a位于B的原型中。


alert(this.a);//1000  a位于父类的父类Object的原型中。所以说构造函数中的this.属性的查找是沿着原型链进行的。其实不仅是构造函数,一切普通函数中的this.属性的查找都是沿着原型链进行的。而alert(a);依旧是undefined,是沿着作用域查找的。





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值