JavaScript中函数声明,函数提升,对象属性和原型属性等问题

冷不防 2022-06-10 06:18 234阅读 0赞
  1. function Foo() {
  2. getNumber = function () { console.log (1); };
  3. return this;
  4. }
  5. Foo.getNumber = function () { console.log (2);};
  6. Foo.prototype.getNumber = function () { console.log (3);};
  7. var getNumber = function () { console.log (4);};
  8. function getNumber() { console.log (5);}

则:

  1. 1. Foo.getNumber();//2
  2. 2. getNumber();//4
  3. 3. Foo().getNumber();//1
  4. 4. getNumber();//1
  5. 5. new Foo.getNumber();//2
  6. 6. new Foo().getNumber();//3
  7. 7. new new Foo().getNumber();//3

分析如下:

(1)第一问,首先定义了Foo函数,该函数为全局变量getNumber(这里的变量)创建了一个getNumber方法。之后又为Foo创建了一个getNumber(这里的是属性)的静态属性并存储了一个匿名函数。

第一问毫无疑问是访问的Foo的静态属性,因此输出2;

(2)第二问,getNumber()方法直接指向window对象,即window对象调用getNumber方法。此时涉及到函数提升的问题。

var getNumber=function(){…}这个为函数表达式,function getNumber(){…}为函数声明,函数声明能提升函数到这一层最上面,所以实际上的执行顺序是:

  1. function getNumber() { console.log (5);}
  2. var getNumber = function () { console.log (4);};

下面的函数表达式覆盖了上面的函数声明,所以此时的getNumber输出4,属于window对象,因此这一问输出4.

(3)第三问,Foo().getNumber(),这里Foo()执行了该函数,返回this,因为这里是window调用Foo,因此Foo()返回的是window,也就是window.getNumber(),因为getNumber前面没有var,所以指向window的getNumber,因此window的getNumber被重新覆盖,调用该方法后输出1;

(4)第四问,这里直接调用了window的getNumber,因为已经被第三问修改,所以这里还是输出1;

(5)‘.’的优先级高于new,因此从左往右执行,因为构造函数Foo.getNumber()没有返回值,因此直接实例化对象,并输出2;

(6)括号的优先级高于new,因此,执行顺序为

  1. (new Foo()).getNumber()

改构造函数返回实例化对象本身,之后调用实例化对象的getNumber函数,因为构造函数并没有为对象添加任何属性,因此到当前对象的原型对象(prototype)中寻找getName,因此输出3;

(7)执行顺序为

  1. new ((new Foo()).getNumber()

先初始化Foo的实例化对象,然后将其原型对象上的getNumber函数作为构造函数再次new

发表评论

表情:
评论列表 (有 0 条评论,234人围观)

还没有评论,来说两句吧...

相关阅读

    相关 原型对象属性共享问题

    原型模式为了省略为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都取得相同的属性值。在某些情况下这会带来一些不便,但更为严重的问题则是包含引用类型值得的属性时的共享