@wy
2018-09-21T10:32:45.000000Z
字数 3806
阅读 589
面试题
var myObject = {foo: "bar",func: function() {var self = this;console.log("outer func: this.foo = " + this.foo);console.log("outer func: self.foo = " + self.foo);(function() {console.log("inner func: this.foo = " + this.foo);console.log("inner func: self.foo = " + self.foo);}());}};myObject.func();
var b = 1;function outer(){var b = 2function inner(){b++;var b = 3;console.log(b)}inner();}outer();
什么是NaN?它的类型是什么?如何可靠地测试一个值是否等于NaN?
什么是JavaScript中的“闭包”? 举一个例子。
以下代码的输出是什么?解释你的答案。
var a={},b={key:'b'},c={key:'c'};a[b]=123;a[c]=456;console.log(a[b]);
(function(x) {return (function(y) {console.log(x);})(2)})(1);
var hero = {_name: 'John Doe',getSecretIdentity: function (){return this._name;}};var stoleSecretIdentity = hero.getSecretIdentity;console.log(stoleSecretIdentity());console.log(hero.getSecretIdentity());
这段代码有什么问题,以及如何解决这个问题。
var length = 10;function fn() {console.log(this.length);}var obj = {length: 5,method: function(fn) {fn();arguments[0]();}};obj.method(fn, 1);
var myObject = {foo: "bar",func: function() {var self = this;// this => myObjectconsole.log("outer func: this.foo = " + this.foo);console.log("outer func: self.foo = " + self.foo);(function() {// this => windowconsole.log("inner func: this.foo = " + this.foo);console.log("inner func: self.foo = " + self.foo);}());}};myObject.func();
在控制台输出:
outer func: this.foo = barouter func: self.foo = barinner func: this.foo = undefinedinner func: self.foo = bar
解析:
func函数是myObject来调用的,所有this和self都引用myObject,因此都可以正确地引用和访问foo。
内部函数是个匿名函数自执行,就是直接调用的方式,这不再指向myObject,而指向window。因此,this.foo在内部函数中是未定义的,而对局部变量self的引用仍然在范围内并且可以在那里访问。
var b = 1;function outer(){var b = 2function inner(){b++;var b = 3;console.log(b)}inner();}outer();
在控制台输出: 3
解析:
在这个例子中有三个闭包,每个都有它自己的var b声明。当调用变量时,将按照从本地到全局的顺序检查闭包,直到找到实例。由于内部闭包有自己的b变量,这就是输出。
此外,由于提升内部的代码将被解释如下:
function inner () {var b; // b is undefinedb++; // b is NaNb = 3; // b is 3console.log(b); // output "3"}
var globalVar = "xyz";(function outerFunc(outerArg) {var outerVar = 'a';(function innerFunc(innerArg) {var innerVar = 'b';console.log("outerArg = " + outerArg + "\n" +"innerArg = " + innerArg + "\n" +"outerVar = " + outerVar + "\n" +"innerVar = " + innerVar + "\n" +"globalVar = " + globalVar);})(456);})(123);
参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
var a={},b={key:'b'},c={key:'c'};a[b]=123;a[c]=456;console.log(a[b]);
此代码的输出将是456
解析:
设置对象属性时,JavaScript会隐式地将参数值串联起来。在这种情况下,由于b和c都是对象,它们都将被转换为“[object Object]”。因此,a [b]和a [c]都等价于[“[object Object]”],并且可以互换使用。因此,设置或引用[c]与设置或引用[b]完全相同。
(function(x) {return (function(y) {console.log(x);})(2)})(1);
输出将为1,即使x的值从未在内部函数中设置。
解析:
闭包是一个函数,以及创建闭包时在范围内的所有变量或函数。在JavaScript中,闭包被实现为“内部函数”;即在另一功能的主体内定义的功能。闭包的一个重要特征是内部函数仍然可以访问外部函数的变量。
因此,在这个例子中,因为x没有在内部函数中定义,所以在外部函数的作用域中搜索一个定义的变量x,该变量的值为1。
var hero = {_name: 'John Doe',getSecretIdentity: function (){return this._name;}};var stoleSecretIdentity = hero.getSecretIdentity;console.log(stoleSecretIdentity());console.log(hero.getSecretIdentity());
这段代码有什么问题,以及如何解决这个问题。
该代码将输出:
undefinedJohn Doe
第一个console.log打印未定义,因为我们从hero对象中提取方法,所以stoleSecretIdentity()在_name属性不存在的全局上下文(即窗口对象)中被调用。
修复stoleSecretIdentity()函数的一种方法如下:
var stoleSecretIdentity = hero.getSecretIdentity.bind(hero);
var length = 10;function fn() {console.log(this.length);}var obj = {length: 5,method: function(fn) {fn();arguments[0]();}};obj.method(fn, 1);
运行结果:
102
解析:
为什么不是10和5?
首先,由于fn作为函数方法的参数传递。
方法绑定到obj上,obj.method用参数fn和1调用。虽然方法只接受一个参数,但调用它时已经传递了两个参数;第一个是函数回调,其他只是一个数字。
当在内部方法中调用fn()时,函数内部的this指向的是window
可以使用arguments []数组访问JavaScript函数中的任意数量的参数。
因此arguments[0]只不过是调用fn()。那么此时调用函数的对象是arguments,而arguments是类数组,是有length的,返回时2.
以上参考:https://juejin.im/entry/5af036cbf265da0b8070aa5f?utm_source=gold_browser_extension