前言:
现在各位老铁们对“python中的负数下标”大概比较珍视,同学们都需要剖析一些“python中的负数下标”的相关知识。那么小编同时在网摘上收集了一些关于“python中的负数下标””的相关知识,希望小伙伴们能喜欢,大家快快来学习一下吧!好程序员Java教程分享JavaScript面试问题及答案(二)
1、.写一个简单的函数(少于80个字符),要求返回一个布尔值指明字符串是否为回文结构。
下面这个函数在str是回文结构的时候返回true,否则,返回false。
functionisPalindrome(str){
str=str.replace(/\W/g,'').toLowerCase();return(str==str.split('').reverse().join(''));
}
例如:
console.log(isPalindrome("level"));//logs'true'console.log(isPalindrome("levels"));//logs'false'console.log(isPalindrome("Acar,aman,amaraca"));//logs'true'
2、.写一个sum方法,在使用下面任一语法调用时,都可以正常工作。
console.log(sum(2,3));//Outputs5console.log(sum(2)(3));//Outputs5
(至少)有两种方法可以做到:
方法1
functionsum(x){if(arguments.length==2){returnarguments[0]+arguments[1];
}else{returnfunction(y){returnx+y;};
}
}
在JavaScript中,函数可以提供到arguments对象的访问,arguments对象提供传递到函数的实际参数的访问。这使我们能够使用length属性来确定在运行时传递给函数的参数数量。
如果传递两个参数,那么只需加在一起,并返回。
否则,我们假设它被以sum(2)(3)这样的形式调用,所以我们返回一个匿名函数,这个匿名函数合并了传递到sum()的参数和传递给匿名函数的参数。
方法2
functionsum(x,y){if(y!==undefined){returnx+y;
}else{returnfunction(y){returnx+y;};
}
}
当调用一个函数的时候,JavaScript不要求参数的数目匹配函数定义中的参数数量。如果传递的参数数量大于函数定义中参数数量,那么多余参数将简单地被忽略。另一方面,如果传递的参数数量小于函数定义中的参数数量,那么缺少的参数在函数中被引用时将会给一个undefined值。所以,在上面的例子中,简单地检查第2个参数是否未定义,就可以相应地确定函数被调用以及进行的方式。
3、请看下面的代码片段:
for(vari=0;i<5;i++){varbtn=document.createElement('button');
btn.appendChild(document.createTextNode('Button'+i));
btn.addEventListener('click',function(){console.log(i);});document.body.appendChild(btn);
}
(a)当用户点击“Button4”的时候会输出什么到控制台,为什么?(b)提供一个或多个备用的可按预期工作的实现方案。
(a)无论用户点击什么按钮,数字5将总会输出到控制台。这是因为,当onclick方法被调用(对于任何按钮)的时候,for循环已经结束,变量i已经获得了5的值。(面试者如果能够谈一谈有关如何执行上下文,可变对象,激活对象和内部“范围”属性贡有助于闭包行为,则可以加分)。
(b)要让代码工作的关键是,通过传递到一个新创建的函数对象,在每次传递通过for循环时,捕捉到i值。下面是三种可能实现的方法:
for(vari=0;i<5;i++){varbtn=document.createElement('button');
btn.appendChild(document.createTextNode('Button'+i));
btn.addEventListener('click',(function(i){returnfunction(){console.log(i);};
})(i));document.body.appendChild(btn);
}
或者,你可以封装全部调用到在新匿名函数中的btn.addEventListener:
for(vari=0;i<5;i++){varbtn=document.createElement('button');
btn.appendChild(document.createTextNode('Button'+i));
(function(i){
btn.addEventListener('click',function(){console.log(i);});
})(i);document.body.appendChild(btn);
}
也可以调用数组对象的本地forEach方法来替代for循环:
['a','b','c','d','e'].forEach(function(value,i){varbtn=document.createElement('button');
btn.appendChild(document.createTextNode('Button'+i));
btn.addEventListener('click',function(){console.log(i);});document.body.appendChild(btn);
});
4、下面的代码将输出什么到控制台,为什么?
vararr1="john".split('');vararr2=arr1.reverse();vararr3="jones".split('');
arr2.push(arr3);console.log("array1:length="+arr1.length+"last="+arr1.slice(-1));console.log("array2:length="+arr2.length+"last="+arr2.slice(-1));
输出结果是:
"array1:length=5last=j,o,n,e,s""array2:length=5last=j,o,n,e,s"
arr1和arr2在上述代码执行之后,两者相同了,原因是:
调用数组对象的reverse()方法并不只返回反顺序的阵列,它也反转了数组本身的顺序(即,在这种情况下,指的是arr1)。
reverse()方法返回一个到数组本身的引用(在这种情况下即,arr1)。其结果为,arr2仅仅是一个到arr1的引用(而不是副本)。因此,当对arr2做了任何事情(即当我们调用arr2.push(arr3);)时,arr1也会受到影响,因为arr1和arr2引用的是同一个对象。
这里有几个侧面点有时候会让你在回答这个问题时,阴沟里翻船:
传递数组到另一个数组的push()方法会让整个数组作为单个元素映射到数组的末端。其结果是,语句arr2.push(arr3);在其整体中添加arr3作为一个单一的元素到arr2的末端(也就是说,它并没有连接两个数组,连接数组是concat()方法的目的)。
和Python一样,JavaScript标榜数组方法调用中的负数下标,例如slice()可作为引用数组末尾元素的方法:例如,-1下标表示数组中的最后一个元素,等等。
5、下面的代码将输出什么到控制台,为什么?
console.log(1+"2"+"2");console.log(1++"2"+"2");console.log(1+-"1"+"2");console.log(+"1"+"1"+"2");console.log("A"-"B"+"2");console.log("A"-"B"+2);
上面的代码将输出以下内容到控制台:
"122""32""02""112""NaN2"NaN
原因是…
这里的根本问题是,JavaScript(ECMAScript)是一种弱类型语言,它可对值进行自动类型转换,以适应正在执行的操作。让我们通过上面的例子来说明这是如何做到的。
例1:1+"2"+"2"输出:"122"说明:1+"2"是执行的第一个操作。由于其中一个运算对象("2")是字符串,JavaScript会假设它需要执行字符串连接,因此,会将1的类型转换为"1",1+"2"结果就是"12"。然后,"12"+"2"就是"122"。
例2:1++"2"+"2"输出:"32"说明:根据运算的顺序,要执行的第一个运算是+"2"(第一个"2"前面的额外+被视为一元运算符)。因此,JavaScript将"2"的类型转换为数字,然后应用一元+号(即,将其视为一个正数)。其结果是,接下来的运算就是1+2,这当然是3。然后我们需要在一个数字和一个字符串之间进行运算(即,3和"2"),同样的,JavaScript会将数值类型转换为字符串,并执行字符串的连接,产生"32"。
例3:1+-"1"+"2"输出:"02"说明:这里的解释和前一个例子相同,除了此处的一元运算符是-而不是+。先是"1"变为1,然后当应用-时又变为了-1,然后将其与1相加,结果为0,再将其转换为字符串,连接后的"2"运算对象,得到"02"。
例4:+"1"+"1"+"2"输出:"112"说明:虽然第一个运算对象"1"因为前缀的一元+运算符类型转换为数值,但又立即转换回字符串,当连接到第二个运算对象"1"的时候,然后又和最后的运算对象"2"连接,产生了字符串"112"。
例5:"A"-"B"+"2"输出:"NaN2"说明:由于运算符-不能被应用于字符串,并且"A"和"B"都不能转换成数值,因此,"A"-"B"的结果是NaN,然后再和字符串"2"连接,得到"NaN2"。
例6:"A"-"B"+2输出:NaN说明:参见前一个例子,"A"-"B"结果为NaN。但是,应用任何运算符到NaN与其他任何的数字运算对象,结果仍然是NaN。
6、下面的递归代码在数组列表偏大的情况下会导致堆栈溢出。在保留递归模式的基础上,你怎么解决这个问题?
varlist=readHugeList();varnextListItem=function(){varitem=list.pop();if(item){//processthelistitem...
nextListItem();
}
};
潜在的堆栈溢出可以通过修改nextListItem函数避免:
varlist=readHugeList();varnextListItem=function(){varitem=list.pop();if(item){//processthelistitem...
setTimeout(nextListItem,0);
}
};
堆栈溢出之所以会被消除,是因为事件循环操纵了递归,而不是调用堆栈。当nextListItem运行时,如果item不为空,timeout函数(nextListItem)就会被推到事件队列,该函数退出,因此就清空调用堆栈。当事件队列运行其timeout事件,且进行到下一个item时,定时器被设置为再次调用extListItem。因此,该方法从头到尾都没有直接的递归调用,所以无论迭代次数的多少,调用堆栈保持清空的状态。
7、JavaScript中的“闭包”是什么?请举一个例子。
闭包是一个可以访问外部(封闭)函数作用域链中的变量的内部函数。闭包可以访问三种范围中的变量:这三个范围具体为:(1)自己范围内的变量,(2)封闭函数范围内的变量,以及(3)全局变量。
下面是一个简单的例子:
varglobalVar="xyz";
(functionouterFunc(outerArg){varouterVar='a';
(functioninnerFunc(innerArg){varinnerVar='b';console.log("outerArg="+outerArg+"\n"+"innerArg="+innerArg+"\n"+"outerVar="+outerVar+"\n"+"innerVar="+innerVar+"\n"+"globalVar="+globalVar);
})(456);
})(123);
在上面的例子中,来自于innerFunc,outerFunc和全局命名空间的变量都在innerFunc的范围内。因此,上面的代码将输出如下:
outerArg=123innerArg=456outerVar=ainnerVar=bglobalVar=xyz
8、下面的代码将输出什么:
for(vari=0;i<5;i++){
setTimeout(function(){console.log(i);},i*1000);
}
解释你的答案。闭包在这里能起什么作用?
上面的代码不会按预期显示值0,1,2,3,和4,而是会显示5,5,5,5,和5。
原因是,在循环中执行的每个函数将整个循环完成之后被执行,因此,将会引用存储在i中的最后一个值,那就是5。
闭包可以通过为每次迭代创建一个唯一的范围,存储范围内变量的每个唯一的值,来防止这个问题,如下:
for(vari=0;i<5;i++){
(function(x){
setTimeout(function(){console.log(x);},x*1000);
})(i);
}
这就会按预期输出0,1,2,3,和4到控制台。
9、以下代码行将输出什么到控制台?
console.log("0||1="+(0||1));console.log("1||2="+(1||2));console.log("0&&1="+(0&&1));console.log("1&&2="+(1&&2));
并解释。
该代码将输出:
0||1=11||2=10&&1=01&&2=2
在JavaScript中,||和&&都是逻辑运算符,用于在从左至右计算时,返回第一个可完全确定的“逻辑值”。
或(||)运算符。在形如X||Y的表达式中,首先计算X并将其解释执行为一个布尔值。如果这个布尔值true,那么返回true(1),不再计算Y,因为“或”的条件已经满足。如果这个布尔值为false,那么我们仍然不能知道X||Y是真是假,直到我们计算Y,并且也把它解释执行为一个布尔值。
因此,0||1的计算结果为true(1),同理计算1||2。
与(&&)运算符。在形如X&&Y的表达式中,首先计算X并将其解释执行为一个布尔值。如果这个布尔值为false,那么返回false(0),不再计算Y,因为“与”的条件已经失败。如果这个布尔值为true,但是,我们仍然不知道X&&Y是真是假,直到我们去计算Y,并且也把它解释执行为一个布尔值。
不过,关于&&运算符有趣的地方在于,当一个表达式计算为“true”的时候,那么就返回表达式本身。这很好,虽然它在逻辑表达式方面计算为“真”,但如果你希望的话也可用于返回该值。这就解释了为什么,有些令人奇怪的是,1&&2返回2(而不是你以为的可能返回true或1)。
10、执行下面的代码时将输出什么?请解释。
console.log(false=='0')console.log(false==='0')
代码将输出:
truefalse
在JavaScript中,有两种等式运算符。三个等于运算符===的作用类似传统的等于运算符:如果两侧的表达式有着相同的类型和相同的值,那么计算结果为true。而双等于运算符,会只强制比较它们的值。因此,总体上而言,使用===而不是==的做法更好。!==vs!=亦是同理。
21.以下代码将输出什么?并解释你的答案。
vara={},
b={key:'b'},c={key:'c'};
a[b]=123;
a[c]=456;
console.log(a[b]);
这段代码将输出456(而不是123)。
原因为:当设置对象属性时,JavaScript会暗中字符串化参数值。在这种情况下,由于b和c都是对象,因此它们都将被转换为"[objectObject]"。结果就是,a[b]和a[c]均相当于a["[objectObject]"],并可以互换使用。因此,设置或引用a[c]和设置或引用a[b]完全相同。
标签: #python中的负数下标