您好,欢迎访问一九零五行业门户网

JS概念问题总结答疑

这次给大家带来js概念问题总结答疑,使用js概念问题的注意事项有哪些,下面就是实战案例,一起来看一下。
q:描述 javascript 中的继承和原型链,并举例子。
javascript 是基于原型的面向对象语言,并无传统的基于类的继承系统。
在 js 中,每个对象都会在内部引用一个叫做prototype的对象,而这个原型对象本身也会引用自己的原型对象,并以此类推。这样就形成了一条原型引用链,这个链的末尾是一个以 null 为原型的对象。js 就是通过原型链的方式来实现继承的,当一个对象引用了不属于自己的属性时,将遍历原型链,直到找到引用的属性为止(或者直接找到链的末尾,这种情况说明该属性未定义)。
一个简单的例子:
function animal() { this.eatsveggies = true; this.eatsmeat = false; }function herbivore() {} herbivore.prototype = new animal();function carnivore() { this.eatsmeat = true; } carnivore.prototype = new animal();var rabbit = new herbivore();var bear = new carnivore();console.log(rabbit.eatsmeat); // logs "false"console.log(bear.eatsmeat); // logs "true"
q:在下面的代码片段中,alert 将会显示什么?请解释你的答案。
var foo = new object();var bar = new object();var map = new object(); map[foo] = "foo"; map[bar] = "bar"; alert(map[foo]); // what will this display
这里 alert 将会弹出 bar ,js 对象本质上是键值对哈希表,其中 key 总是字符串。事实上,当字符串以为外的对象被用作 key 时,并不会发生错误,js 会隐式的将其转换为字符串,并将该值用作 key。
所以,上面的代码中 map 对象在使用 foo 对象作为 key 时,会自动调用 foo 对象的tostring()方法,那么这里就会调用其默认实现。则会得到字符串"[object object]"。然后再看上面的代码,解释如下:
var foo = new object(); var bar = new object(); var map = new object(); map[foo] = "foo"; // --> map["[object object]"] = "foo"; map[bar] = "bar"; // --> map["[object object]"] = "bar"; // note: second mapping replaces first mapping! alert(map[foo]); // --> alert(map["[object object]"]); // and since map["[object object]"] = "bar", // this will alert "bar", not "foo"!! // surprise! ;-)
q:请解释 javascript 中的闭包。什么是闭包?它们有什么独特的特性?你如何以及为什么要使用它们?请举一个例子。
闭包是一个函数,包含在创建闭包时处于作用域内的所有变量或其他函数。在 javascript 中,闭包通过“内部函数”的形式来实现,也就是在另一函数的主体内定义的函数。这是一个简单的例子:
(function outerfunc(outerarg) { var outervar = 3; (function middlefunc(middlearg) { var middlevar = 4; (function innerfunc(innerarg) { var innervar = 5; // example of scope in closure: // variables from innerfunc, middlefunc, and outerfunc, // as well as the global namespace, are all in scope here. console.log("outerarg="+outerarg+ " middlearg="+middlearg+ " innerarg="+innerarg+"\n"+ " outervar="+outervar+ " middlevar="+middlevar+ " innervar="+innervar); // --------------- this will log: --------------- // outerarg=123 middlearg=456 innerarg=789 // outervar=3 middlevar=4 innervar=5 })(789); })(456); })(123);
闭包的一个重要特性是,即使是在外部函数返回后,内部函数仍然可以访问外部函数的变量。这是因为,在 javascript 中,当函数被执行时,它们仍然使用创建函数时有效的作用域。
然而,如果内部函数在被调用时(而不是在创建时)访问外部函数变量的值,就会导致混淆。为了测试候选人对此细微差别的理解,请使用以下代码片段,它将动态创建五个按钮,并问候选人当用户单击第三个按钮时将显示什么内容:
function addbuttons(numbuttons) { for (var i = 0; i < numbuttons; i++) { var button = document.createelement('input'); button.type = 'button'; button.value = 'button ' + (i + 1); button.onclick = function() { alert('button ' + (i + 1) + ' clicked'); }; document.body.appendchild(button); document.body.appendchild(document.createelement('br')); } }window.onload = function() { addbuttons(5); };
很多人会错误地回答,当用户点击第三个按钮时,会显示“button 3 clicked”。实际上,上面的代码包含了一个错误(基于对 closure 的误解),当用户点击五个按钮中的任何一个,都将显示“button 6 clicked”。这是因为,在调用 onclick 方法时(对于任意一个按钮),for 循环已经完成并且变量 i 的值已经是 5。
接下来可以问候选人如何解决上述代码中的错误,以便产生预期的行为(即点击按钮 n 将显示“button n clicked”)。如果候选人能给出正确答案,说明他们懂得如何正确使用闭包,如下所示:
function addbuttons(numbuttons) { for (var i = 0; i < numbuttons; i++) { var button = document.createelement('input'); button.type = 'button'; button.value = 'button ' + (i + 1); // here's the fix: // employ the immediately-invoked function expression (iife) // pattern to achieve the desired behavior: button.onclick = function(buttonindex) { return function() { alert('button ' + (buttonindex + 1) + ' clicked'); }; }(i); document.body.appendchild(button); document.body.appendchild(document.createelement('br')); } }window.onload = function() { addbuttons(5); };
相信看了本文案例你已经掌握了方法,更多精彩请关注其它相关文章!
推荐阅读:
怎样使用li进行水平排列
怎样操作页面、可视区、屏幕等宽高属性
以上就是js概念问题总结答疑的详细内容。
其它类似信息

推荐信息