每日 3 题
1 以下代码执行后,控制台中的输入内容为?
var foo = function bar() {return 123;};
console.log(typeof foo);
console.log(typeof foo());
console.log(typeof bar());
2 以下代码执行后,控制台中的输入内容为?
var obj = {
a: 1,
foo: function () {return this.a;},
};
var fun = obj.foo;
console.log(obj.foo());
console.log(fun());
3 以下代码执行后,控制台中的输入内容为?
function A(x) {this.x = x;}
function B(x) {this.x = x;}
A.prototype.x = 1;
B.prototype = new A();
var a = new A(2);
var b = new B(3);
delete b.x;
console.log(a.x);
console.log(b.x);
解析
1、答案:function number 报错
解析:
- 这是一个命名函数表达式,被函数表达式赋值的变量类型为
function
,故typeof foo
为 function - foo 调用后返回 123,故类型为 number
- 无关命名函数表达式,MDN 文档中是这么形容的:
命名函数表达式(Named function expression)如果你想在函数体外部援用以后函数,则须要创立一个命名函数表达式。而后函数名称将会(且只会)作为函数体(作用域内)的本地变量
命名函数表达式的函数名只在其函数体内无效
所以在内部调用 bar() 会报错
2、答案:1 undefined
- 间接调用 obj.foo() 时,它的后面加上了对 obj 的援用。当函数援用有上下文对象是,
隐式绑定
规定会把函数调用中的 this 绑定到这个上下文对象。因为调用 obj.foo() 时 this 被绑定到 obj,因而 this.a 和 obj.a 是一样的,所以后果为 1 - 尽管 fun 是
obj.foo
的一个援用,然而它援用的是 foot 函数自身,因而 fun() 实际上是一个不带任何润饰的函数调用,此时利用默认绑定
规定,即 this 指向全局对象。而全局对象不存在属性 a,故输入 undefined
3、答案:2 undefined
考查 原型链
- JS 中每个函数都有一个 prototype 属性,指向一个对象(称为原型对象)
- 每个对象都有一个
__proto__
属性,指向该对象的构造函数的原型对象 - 原型对象也有
__proto__
属性,于是一个对象能够沿着__proto__
层层向上,直到一个对象的原型对象为 null,null 没有原型,即为原型链的起点 - 拜访对象的属性时,如果对象不存在该属性,则会沿着原型链向上寻找该属性,直到达到原型链的起点
回到题目:
- a.x,对象 a 上存在属性 x 为 2,所以输入 2
-
b.x,对象 b 上的属性 x 被 delete,所以向上寻找,首先查看 b.__proto__,即 B.prototype,为 new A(),因为没传入 x,所以 x 为 undefined,找到属性 x,最终返回 undefined
公众号【明天也要写 bug】