Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一道综合面试题(原型、this、作用域、构造函数、运算符优先级) #10

Open
amandakelake opened this issue Feb 8, 2018 · 0 comments
Labels
interview 面试相关:面试题目、面经之类

Comments

@amandakelake
Copy link
Owner

amandakelake commented Feb 8, 2018

function Foo() {
    getName = function () { alert (1); };
    return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}

//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
function Foo() {
  getName = function () { alert (1); };
  return this;
} 
// 为Foo创建了一个叫getName的静态属性存储了一个匿名函数
Foo.getName = function () { alert (2);};
// 为Foo的原型对象新创建了一个叫getName的匿名函数
Foo.prototype.getName = function () { alert (3);};
// 通过函数变量表达式创建了一个getName的函数
var getName = function () { alert (4);};
// 通过函数声明一个getName函数,注意提升,所以getName最后应该是上一行的4
function getName() { alert (5);}//提升

//请写出以下输出结果:
Foo.getName(); //2    Foo上面的静态属性
getName(); // 4  当前上文作用域内的叫getName的函数,所以跟1 2 3都没什么关系,但函数声明被提升了  所以函数表达式在后
Foo().getName(); // 1
// Foo函数的第一句  getName = function () { alert (1); };  是一句函数赋值语句,注意它没有var声明
// 所以先向当前Foo函数作用域内寻找getName变量,没有。再向当前函数作用域上层,找到了,这时候是4,然后赋值为1
// 此处实际上是将外层作用域内的getName函数修改了
// 此处若依然没有找到会一直向上查找到window对象,若window对象中也没有getName属性,就在window对象中创建一个getName变量
// 此时,Foo返回了this,如果函数独立调用,那么严格模式下该函数内部的this,则指向undefined,现在是非严格模式,所以指向window
// Foo函数返回的是window对象,相当于执行 window.getName() ,而window中的getName已经被修改为alert(1),
getName(); // 与上一问相同,已经被改为1了
new Foo.getName(); //2
// 这里考察运算符优先级
// 圆括号 > (成员访问.号 > new) > 函数调用 > 其他(具体再看)
// 这里成员访问.号优先级高于new   相当于  new (Foo.getName)()  相当于将getName()函数当做构造函数,这个构造函数现在是foo的静态属性2
new Foo().getName(); //3
// 相当于  (new Foo()).getName()
// 这里构造函数Foo返回了实例化的对象,然后去原型对象中找到的getName, (Foo.prototype.getName = function () { alert (3);};)
new new Foo().getName(); // 3
// new ((new Foo()).getName)();
// 先初始化Foo的实例化对象,然后将其原型上的getName函数作为构造函数再次new。
构造函数的返回值

构造函数可以有返回值也可以没有

  • 没有返回值则按照其他语言一样返回实例化对象。
  • 若有返回值则检查其返回值是否为引用类型。如果是非引用类型,如基本类型(string,number,boolean,null,undefined)则与无返回值相同,实际返回其实例化对象。
  • 若返回值是引用类型,则实际返回值为这个引用类型。

如果返回this,而this在构造函数中本来就代表当前实例化对象,遂最终Foo函数返回实例化对象

@amandakelake amandakelake added the interview 面试相关:面试题目、面经之类 label Feb 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interview 面试相关:面试题目、面经之类
Projects
None yet
Development

No branches or pull requests

1 participant