直接上题目:
第 1 题
var name = 'shenjiu';
var object = {
name: 'zhangsan',
getNameFunc: function() {
return function() {
return this.name;
};
}
};
console.log('object.getNameFunc()():', object.getNameFunc()());
//输出
object.getNameFunc()(): shenjiu
解析: 先执行object.getNameFunc() 返回的是一个函数
function() {
return this.name;
};
再执行
(function() {
return this.name;
})();
此时,this指向的是window, 因此,this.name输出全局变量name的值
第 2 题
var name = 'shenjiu';
var object = {
name: 'zhangsan',
getNameFunc: function() {
var that = this;
return function() {
return that.name;
};
}
};
console.log('object.getNameFunc()():', object.getNameFunc()());
//输出
object.getNameFunc()(): zhangsan
解析: object.getNameFunc()时,this指向的是object, var that = this, 所以,此时,that指向的也是object,object.getNameFunc()返回一个函数, 函数中的that指向的是object, 所以 that.name是object中的name的值
第 3 题
(function() {
var a = (b = 3);
console.log('a:', a);
})();
console.log('typeof a:', typeof a);
console.log('typeof b:', typeof b);
console.log("typeof a === 'undefined':", typeof a === 'undefined');
console.log("typeof b === 'undefined':", typeof b === 'undefined');
//输出
typeof a: undefined
typeof b: number
typeof a === 'undefined': true
typeof b === 'undefined': false
解析: 自执行函数, var a = (b = 3); 的伪代码是
b = 3;
var a = b;
由于b没有经由var等操作符声明,因此,b是全局变量, a是函数作用域内局部变量,在外面访问时,会出现ReferenceError: a is not defined,但是typeof检测未声明的变量不会报错,会直接返回undefined b的值是3, typeof b的值是number
第 4 题
var a = 6;
setTimeout(function() {
a = 666;
}, 0);
console.log('a:', a);
//输出
a:6
var a = 6;
setTimeout(function() {
a = 666;
}, 0);
setTimeout(() => {
console.log('a:', a);
}, 0);
//输出
a:666
解析: setTimeout为宏任务,所以即使设置延时0ms,也是等待同步代码执行完才执行
第 5 题
function fn1() {
var a = 2;
function fn2() {
a++;
console.log('a:', a);
}
return fn2;
}
var f = fn1();
f();
f();
//输出
a:3
a:4
解析: var f = fn1(); 先执行fn1(),返回fn2 赋值给f,此时产生了闭包,因此fn2中访问a取的是fn1作用域中的变量a的值,因此第一次a++,之后a为3,第二次之后a为4。
第 6 题
var a = (function(foo){
return typeof foo.bar;
})({foo:{bar:1}});
console.log('a:', a);
//输出
a: undefined
解析:伪代码为
function fn1(foo) {
console.log('foo:', foo);
console.log('bar:', foo.bar);
console.log('bar:', foo.foo.bar);
return typeof foo.bar;
//return typeof foo.foo.bar;
}
var a = fn1({ foo: { bar: 1 } });
console.log('a:', a);
//输出
foo: {foo: { bar: 1 }}
bar: undefined
bar: 1
a: undefined
实参foo的值为{foo: { bar: 1 }}
因此typeof foo.bar为undefined。
typeof foo.foo.bar为number。
第 7 题
function f() {
return f;
}
console.log(new f() instanceof f);
//输出
false
instanceof
运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上。
由于构造函数f的返回值为f。因此new f()的值为f。所以console.log(new f() instanceof f)为console.log(f instanceof f),即 false。
第 8 题
function A() {}
A.prototype.n = 1;
var b = new A();
A.prototype = {
n: 2,
m: 3
};
var c = new A();
console.log('b.n:', b.n);
console.log('b.m:', b.m);
console.log('c.n', c.n);
console.log('c.m', c.m);
//输出
b.n: 1
b.m: undefined
c.n: 2
c.m: 3
解析: var b = new A() 时,A的prototype只有一个属性n:1
var c = new A() 时,A的prototype有两个 n: 2, m: 3
*第 9 题
var F = function() {};
var O = {};
Object.prototype.a = function() {
console.log('a');
};
Function.prototype.b = function() {
console.log('b');
};
var f = new F();
F.a();
F.b();
O.a();
O.b();
//输出
a
b
a
TypeError: O.b is not a function
解析: F为函数,它能访问Object原型上的方法, O为对象,不能访问function原型上的方法。
F的原型链为:
F => F.__proto__ => Function.prototype => Function.prototype.__proto__ => Object.prototype
由于Object.prototype在F的原型链上,所以F能访问Object.prototype上的属性和方法, 即F.a() , F.b() 能正常访问
O的原型链为:
O => O.__proto__ => Object.prototype
由于Function.prototype不在O的原型链上,所以O.b()抛出错误
第 10 题
function Person() {
getAge = function() {
console.log(10);
};
return this;
}
Person.getAge = function() {
console.log(20);
};
Person.prototype.getAge = function() {
console.log(30);
};
var getAge = function() {
console.log(40);
};
function getAge() {
console.log(50);
}
Person.getAge();
getAge();
Person().getAge();
new Person.getAge();
getAge();
new Person().getAge();
//输出
20
40
10
20
10
30
解析:
1、Person.getAge() 此时执行的是Person函数的getAge方法
Person.getAge = function() {
console.log(20);
};
所以输出:20
2、getAge() 执行的是全局的getAge函数,所以执行的是
var getAge = function() {
console.log(40);
};
输出的是:40
3、Person().getAge() 先执行Person(),由于是单独执行Person(),此时作用域中的this绑定的是window, 下一步.getAge(),相当于window.getAge(),执行的都是全局 getAge 方法。但是Person()执行时,内部执行了
getAge = function() {
console.log(10);
};
因此,此时全局的 getAge 方法现在是
function() {
console.log(10);
};
所以输出的是:10
4、new Person.getAge() 此时相当于实例化Person.getAge()这个函数, 伪代码:
const a = Person.getAge();
new a();
所以输出的是:20
5、getAge() 执行全局的 getAge 方法,由于Person().getAge()中给全局的 getAge 赋值为
function() {
console.log(10);
};
所以输出的是:10
6、new Person().getAge() 此时调用的是 Person 原型链上的 getAge 方法
Person.prototype.getAge = function() {
console.log(30);
};
所以输出的是: 30