你会吗,jser?

269 阅读2分钟
function Foo() {
    getName = function() {
        console.log(1)
    };
    return this;
}
Foo.getName = function() {
    console.log(2)
}
Foo.prototype.getName = function() {
    console.log(3)
}
var getName = function() {
    console.log(4)
}
function getName() {
    console.log(5)
}

1.Foo.getName()
2.getName()
3.Foo().getName()
4.getName()
5.new Foo.getName()
6.new Foo().getName()
7.new new Foo().getName()

首先,进行变量提升(变量提升和function提升和定义):

函数Foo提升,变量getName定义未赋值,函数getName提升fun->5

代码执行:

变量getName进行赋值fun->4

Foo是一个堆内存,包含代码字符串,对象属性(getName,prototype,name等)
  getName: fun->2,
  prototype:(当前也是堆地址,constructor:Foo)fun->3
故:1.中Foo.getName输出 2; 2.中getName输出 4

Foo()为普通函数执行,getName:fun->1,修改全局的getName,return this->window
故:3.中Foo().getName输出 1; 4.中getName输出 1

js运算符的优先执行顺序问题:

3.new Foo.getName(): new Foo是无参数列表,优先级为18,Foo.getName()为成员访问,优先级为19
先执行Foo.getName()=>fun->2,再执行new  fun->2还是执行函数fun->2

4.new Foo().getName(): new Foo()是new带参数列表,优先级为19 xxx.getName()是成员访问,优先
级为19,同优先级为从左到右执行
执行new Foo()创建实例,.getName是寻找prototype上的getName:fun->3

5.new Foo创建实例xxx,变为 new xxx.getName()
  优先级问题先执行 xxx.getName=>fun->3,最后执行new fun->3

闭包
var a = 0,b=0;
function A(a) {
    A = function(b) {
        alert(a + b++);
    }
    alert(a++);
}
A(1)
A(2)

//首先,变量提升,全局下有全局变量a,b为undefined,和function A,
//function A先提升(引用变量为堆地址,其中保存的是代码字符串),ab赋值=0
函数A1)执行
上下文环境中(ECstack)函数传入全局变量a=1,函数function A = function(为堆地址,存储:
字符串代码'alert(a + b++)'),全局下function A被重写,堆地址被改变,全局函数中function A占用
了自己内部的匿名函数的堆地址,内部匿名函数执行在当前上下文中无法释放堆地址,形成闭包;
在执行'alert(a++)', a++先执行后加,故此时alert('1'),此时变量a=2.
函数A2)执行
新的上下文环境中function A = function(b)...,函数执行'alert(a + b++)',先执行a+b,在执行b++,
故alert('4'),b=3,内存地址释放
但是全局a,b不变 =0