JavaScript面试的题目,主要考察的内容还是逻辑性为主。基础的部分,主要是对内置函数的使用,比如String, Math, Array对象。还有一个比较讨面试喜欢的,就是正则表达式。
JS核心部分需要理解的一个重要部分。
var a = 1;
a.a = 2;
console.log(a.a);
这一题需要理解的是点的作用,在JS解释器中,首先会判断左侧的变量是什么类型,如果是普通对象,会创建一个新的对象作用域,然后挂载a属性。console.log部分的a也是又创建了一个封装对象,但是这个对象下面的a是没有赋值的。
var a = {n:1};
var b = a;
a.x = a = {n:2};
alert(a.x);// --> undefined
alert(b.x);// --> [object Object]
这个涉及到了连续赋值的情况,详情参考javascript 连等赋值问题.在程序运行到之后,先确定好了 a.x 和 a 的引用,再从右往左开始赋值的。还有一点就是可以理解的是.
运算优先级高于=
运算符,所以会先创建a.x
对象,然后在执行赋值过程。赋值顺序从右向左。
JS核心部分的另一个需要理解的重要部分。
比较时候的转换的原则:
运算过程的转换原则:
function foo1(a){
return a + '01';
}
foo1(01);
function foo2(a){
return a + '010';
}
foo2(010);
console.log(0.2 + 0.4);
var foo = "11"+2-"1";
console.log(foo);
console.log(typeof foo);
#fffff
类型的数据转换为rgb(255,255,255)
形式如果使用了\s
作为匹配的情况,有没有消除不了的情况(是有的),具体是什么?
function escapeHtml(str) {
return str.replace(/[<>”&]/g, function(match) {
switch (match) {
case “<”:
return “<”;
case “>”:
return “>”;
case “&”:
return “&”;
case “\””:
return “"”;
}
});
}
if (!String.prototype.trim) {
String.prototype.trim = function() {
return this.replace(/^\s+/, "").replace(/\s+$/,"");
}
}
// test the function
var str = " \t\n test string ".trim();
alert(str == "test string"); // alerts "true"
// 方法一:
Object.prototype.clone = function(){
var o = this.constructor === Array ? [] : {};
for(var e in this){
o[e] = typeof this[e] === "object" ? this[e].clone() : this[e];
}
return o;
}
//方法二:
/**
* 克隆一个对象
* @param Obj
* @returns
*/
function clone(Obj) {
var buf;
if (Obj instanceof Array) {
buf = []; //创建一个空的数组
var i = Obj.length;
while (i--) {
buf[i] = clone(Obj[i]);
}
return buf;
}else if (Obj instanceof Object){
buf = {}; //创建一个空对象
for (var k in Obj) { //为这个对象添加新的属性
buf[k] = clone(Obj[k]);
}
return buf;
}else{ //普通变量直接赋值
return Obj;
}
}
myArray.filter(function(elem, pos,self){return self.indexOf(elem)== pos;})
filter是过滤的意思,filter通过一个函数的参数来选择什么项需要被filter掉,函数返回true保留,false干掉。
函数参数带三个参数,第一个elem是这一项元素,第二个pos是这一项所在的位置,第三个self指的是执行filter的数组。那么,你看,巧妙吗:self.indexOf(elem) 是指这个项目在数组中的位置,位置是第一个,也就是说同样的项目在第一位和第5位都出现了,他返回的是0,而此时pos还是4,所以通过self.indexOf(elem) == pos 能判断出这一项是不是重复出现的项,如果是(返回false),则干掉它。
var query = function(selector) {
var reg = /^(#)?(\.)?(\w+)$/img;
var regResult = reg.exec(selector);
var result = [];
//如果是id选择器
if(regResult[1]) {
if(regResult[3]) {
if(typeof document.querySelector === "function") {
result.push(document.querySelector(regResult[3]));
}
else {
result.push(document.getElementById(regResult[3]));
}
}
}
//如果是class选择器
else if(regResult[2]) {
if(regResult[3]) {
if(typeof document.getElementsByClassName === 'function') {
var doms = document.getElementsByClassName(regResult[3]);
if(doms) {
result = converToArray(doms);
}
}
//如果不支持getElementsByClassName函数
else {
var allDoms = document.getElementsByTagName("*") ;
for(var i = 0, len = allDoms.length; i < len; i++) {
if(allDoms[i].className.search(new RegExp(regResult[2])) > -1) {
result.push(allDoms[i]);
}
}
}
}
}
//如果是标签选择器
else if(regResult[3]) {
var doms = document.getElementsByTagName(regResult[3].toLowerCase());
if(doms) {
result = converToArray(doms);
}
}
return result;
}
function converToArray(nodes){
var array = null;
try{
array = Array.prototype.slice.call(nodes,0);//针对非IE浏览器
}catch(ex){
array = new Array();
for( var i = 0 ,len = nodes.length; i < len ; i++ ) {
array.push(nodes[i])
}
}
return array;
}
数组的sort方法,默认是按照ascii排序的,为了对数字进行区分,还是手动传入一个sort函数。
var arr = [11,2,28,5,8,4]
arr.sort(function(a,b){return a-b})
sort的参数是一个排序函数,我们可以把参数a当作数组里靠后的元素,b当作数组里靠前的元素,排序函数return的值如果是正的,才执行排序,所以最后排下来是从小到大,相反,如果return的是b-a,那么就是从大到小排序。
对于apply和call两者在作用上是相同的,即是调用一个对象的一个方法,以另一个对象替换当前对象。将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
但两者在参数上有区别的。对于第一个参数意义都一样,但对第二个参数: apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。 如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3]) 。
伪数组(类数组):无法直接调用数组方法或期望length属性有什么特殊的行为,但仍可以对真正数组遍历方法来遍历它们。典型的是函数的argument参数,还有像调用getElementsByTagName,document.childNodes之类的,它们都返回NodeList对象都属于伪数组。可以使用Array.prototype.slice.call(fakeArray)将数组转化为真正的Array对象。
function a(x){
return function b(y){
return y+x++
}
}
var a1 = a(10)
var a2 = a(20)
a1(10)
a2(10)
var a = {n:1};
var b = a; // 持有a,以回查
a.x = a = {n:2};
alert(a.x);// --> undefined
alert(b.x);// --> [object Object]
[].forEach.call($ $(""),function(a){
a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)
})
原理参考: 通过一行代码学习javascript
++[[]][+[]]+[+[]] = 10
?答案参考: [为什么 ++[[]][+[]]++[]] = 10?