javascript经典面试题理解this 发表于 2016-09-19 | 分类于 javascript javascript this 经典面试题12345678910function Foo(){ getName = function(){console.log("1");};//这个不属于Foo的属性 return this ; //如果作为构造函数,那么返回的this就是实例化对象, //如果作为函数直接执行,那么返回的this就是全局的window对象 } Foo.getName = function(){console.log("2"); }; Foo.prototype.getName = function(){ console.log("3");}; var getName =function(){console.log("4");}; function getName(){console.log("5");}; 预解析之后 12345678910var getName;//只提升变量声明 function getName(){console.log("5");};//提升函数声明,覆盖变量var声明 function Foo(){ getName = function(){console.log("1");};//这个不属于Foo的属性 return this ;//如果作为构造函数,那么返回的this就是实例化对象,如果作为函数直接执行,那么返回的this就是全局的window对象 } Foo.getName = function(){console.log("2"); }; Foo.prototype.getName = function(){ console.log("3");}; getName =function(){console.log("4");}; 可以在控制台输出看下数据结构 123console.dir(Foo);var res = Foo.getName();//注意没有返回值,如果将Foo看成对象,console.log(res); 看下面的求值过程 1234567891011121314 Foo.getName();//2 getName();//4 Foo().getName();//1 先执行了Foo() 函数,Foo函数第一句,getName没有用var声明,改变了输出4的getName,变为输出1//2 第二句 返回了this,代表当前指向环境的window;相当于执行了 window.getName(); getName();//1 直接调用getName ,上面一行代码改变后的结果//运算符的优先级 () > 成员访问 . > new 操作符 new Foo.getName();//2 new一个构造函数的时候,构造函数内部的代码会一行一行执行;// 等价于 new (Foo.getName)(); new Foo().getName();//3 Foo作为构造哦函数,没有给实例化的对象添加任何属性,只能去原型上找// 等价于 (new Foo()).getName(); new new Foo().getName();//3// 等价于 new (new Foo().getName)(); ————————————- = 运算符面试题 12345678910111213141516 /* 面试题 */ // 基本类型和引用类型 // 引用类型变量和对象属性(在内存实际上就是内存地址) var a = {n:1}; var b = a; a.x = a = {n:2};//运算符的优先级 .的优先级最高 赋值操作是从右向左运算的 console.log(a.x);//undefined console.log(b.x);//{n:2}/*我们可以先尝试交换下连等赋值顺序(a = a.x = {n: 2};),可以发现输出不变,即顺序不影响结果。那么现在来解释对象连等赋值的问题:按照es5规范,题中连等赋值等价于a.x = (a = {n: 2});,按优先获取左引用(lref),然后获取右引用(rref)的顺序,a.x和a中的a都指向了{n: 1}。至此,至关重要或者说最迷惑的一步明确。(a = {n: 2})执行完成后,变量a指向{n: 2},并返回{n: 2};接着执行a.x = {n: 2},这里的a就是b(指向{n: 1}),所以b.x就指向了{n: 2}。*/