每日 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】
相关文章
暂无评论...