web前端笔试题(一)

时间:2021-03-03 14:41:30
 1、javascript中如何对一个对象进行深度clone?
//深度克隆
function deepClone(obj){
    var result,oClass=isClass(obj);
        //确定result的类型
    if(oClass==="Object"){
        result={};
    }else if(oClass==="Array"){
        result=[];
    }else{
        return obj;
    }
    for(key in obj){
        var copy=obj[key];
        if(isClass(copy)=="Object"){
            result[key]=arguments.callee(copy);//递归调用
        }else if(isClass(copy)=="Array"){
            result[key]=arguments.callee(copy);
        }else{
            result[key]=obj[key];
        }
    }
    return result;
}
//返回传递给他的任意对象的类
function isClass(o){
    if(o===null) return "Null";
    if(o===undefined) return "Undefined";
    return Object.prototype.toString.call(o).slice(8,-1);
}
var oPerson={
    oName:"rookiebob",
    oAge:"18",
    oAddress:{
        province:"beijing"
    },    
    ofavorite:[
        "swimming",
        {reading:"history book"}
    ],
    skill:function(){
        console.log("bob is coding");
    }
};
//深度克隆一个对象
var oNew=deepClone(oPerson);
 
oNew.ofavorite[1].reading="picture";
console.log(oNew.ofavorite[1].reading);//picture
console.log(oPerson.ofavorite[1].reading);//history book
 
oNew.oAddress.province="shanghai";
console.log(oPerson.oAddress.province);//beijing
console.log(oNew.oAddress.province);//shanghai

  2、如何控制alert中的换行?

 添加 “\n”  即可实现换行,有些浏览器则可能添加 “\r\n”

        3、请编写一个javascript函数parseQueryString,它的用途是把URL参数解析为一个对象

var url = "http://www.taobao.com/index.php?key0=0&key1=1&key2=2";
var obj = parseQueryString(url);
       
function parseQueryString(argu){
  var str = argu.split('?')[1];
  var result = {};
  var temp = str.split('&');
  for(var i=0; i<temp.length; i++)
  {
     var temp2 = temp[i].split('=');
     result[temp2[0]] = temp2[1];
  }
  return result;
}

  4、如何控制网页在网络传输过程中的数据量?

  1. 减少http请求次数:css spirit,data uri

  2.  JS,CSS源码压缩
  3.  前端模板 JS 数据,减少由于HTML标签导致的带宽浪费,前端用变量保存AJAX请求结果,每次操作本地变量,不用请求,减少请求次数
  4.  用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能
  5.  用setTimeout来避免页面失去响应
  6.   用hash-table来优化查找
  7.  当需要设置的样式很多时设置className而不是直接操作style 
  8.  少用全局变量
  9.  缓存DOM节点查找的结果
  10.  避免使用CSS Expression
  11.   图片预载
  12.  避免在页面的主体布局中使用table,table要等其中的内容完全下载之后才会显示出来,显示比div css布局慢

       5、以下代码运行结果    //889

function say(){
    var num=888;
    var sayAlert=function(){alert(num)}; 
    num++;
    return sayAlert;
}

var sayAlert=say();
sayAlert()

  6、请实现ES5中的Object.getPrototypeOf()函数

function Fn(){
            
            }
var fn = new Fn();
 //通过getPrototypeOf静态方法,获得对象fn的prototype
var proto = Object.getPrototypeOf(fn);
 //将获得的prototype添加一个name属性,并赋值
 proto.name = 'Monkey';
//输出对象fn.name
 console.log(fn.name);//Monkey
//判断proto是否是Fn.prototype
 console.log( 'proto === Fn.prototype? ' + (proto === Fn.prototype) );
//proto === Fn.prototype? true

  7、如何实现Array.prototype.forEach

 
array.forEach(callback(currentValue,index,array){
 
},this)
array.forEach(callback[,  thisArg])
callback
为数组中每个元素执行的函数,该函数接收三个参数:
currentValue(当前值)
数组中正在处理的当前元素。
index(索引)
数组中正在处理的当前元素的索引。
array
forEach()方法正在操作的数组。
thisArg可选
可选参数。当执行回调 函数时用作this的值(参考对象)。
 

 

function logArrayElements(element, index, array) {
    console.log("a[" + index + "] = " + element);
}

// 注意索引2被跳过了,因为在数组的这个位置没有项
[2, 5, ,9].forEach(logArrayElements);

// a[0] = 2
// a[1] = 5
// a[3] = 9

[2, 5,"" ,9].forEach(logArrayElements);
// a[0] = 2
// a[1] = 5
// a[2] = 
// a[3] = 9

[2, 5, undefined ,9].forEach(logArrayElements);
// a[0] = 2
// a[1] = 5
// a[2] = undefined
// a[3] = 9


let xxx;
// undefined

[2, 5, xxx ,9].forEach(logArrayElements);
// a[0] = 2
// a[1] = 5
// a[2] = undefined
// a[3] = 9

  7、如何将arguments转为数组

  1. Array.prototype.slice.apply(arguments)这是运行效率比较快的方法(看别人资料说的),为什么不是数组也可以,因为arguments对象有length属性,而这个方法会根据length属性,返回一个具有length长度的数组。若length属性不为number,则数组长度返回0;所以其他对象只要有length属性也是可以的哟,如对象中有属性0,对应的就是arr[0],即属性为自然数的number就是对应的数组的下标,若该值大于长度,当然要割舍啦。
  2. Array.prototype.concat.apply(thisArg,arguments)。,thisArg是新的空数组,apply方法将函数this指向thisArg,arguments做为类数组传参给apply。根据apply的方法的作用,即将Array.prototype.slice方法在指定的this为thisArg内调用,并将参数传给它。用此方法注意:若数组内有数组,会被拼接成一个数组。原因是apply传参的特性。
  3. 利用Array的构造函数,如Array(1,2,3,4,5,6);可以返回一个传入的参数的数组,那Array.apply(thisArg,arguments)也可以将arguments转化为数组,果然实验是可以的;有没有什么影响呢,就是乱用了构造函数,但这也是js的特性嘛。构造函数也是函数。用此方法注意:若数组内有数组,会被拼接成一个数组。原因是apply传参的特性。
  4. 用循环,因为arguments类似数组可以使用arguments[0]来访问实参,那么将每项赋值给新的数组每项,直接复制比push要快,若实参有函数或者对象,就要深拷贝。

       8、以下程序运行结果

var ninja=function myNinja(){
    alert(ninja==myNinja);
};
ninja();//true
myNinja(); //myNinja is not defined

  9、兼容浏览器的获取指定元素的样式属性的方法

function getStyle(elem, name){
  //如果属性存在于style[]中,直接取
  if(elem.style[name]){
    return elem.style[name];
  } 
  //否则 尝试IE的方法
  else if(elem.currentStyle){
    return elem.currentStyle[name];
  }
  //尝试W3C的方式
  else if(document.defaultView && document.defaultView.getComputedStyle){
    //W3C中为textAlign样式,转为text-align
    name = name.replace(/([A-Z])/g, "-$1");
    name = name.toLowerCase();
    
    var s = document.defaultView.getComputedStyle(elem, "");
    return s && s.getPropertyValue(name);
  } else {
    return null;
  }
  
}