面试题以及案例

155 阅读5分钟

一维数组数字从小到大和从大到小排序:

<script type="text/javascript">
var arr=[15,2,433,10000,8888]; 
document.write("<p>原数组为:" + arr + "</p>");
document.write("<p>从小到大排序:" + arr.sort(function(a,b){return a-b}) + "</p>");
document.write("<p>从大到小排序:" + (arr.sort(function(a,b){return a-b})).reverse() + "</p>");
document.write("<p>从大到小排序:" + (arr.sort(function(a,b){return b-a})) + "</p>");
</script>

多维数组数字从小到大和从大到小排序:

<script type="text/javascript">
var arrs=[15,2,443,[56,678],[10,4,99]];
var arr=arrs.join(",").split(","); //转化为一维数组
document.write("<p>转化后的一维数组为:" + arr + "</p>");
document.write("<p>从小到大排序:" + arr.sort(function(a,b){return a-b}) + "</p>");
document.write("<p>从大到小排序:" + (arr.sort(function(a,b){return a-b})).reverse() + "</p>");
document.write("<p>从大到小排序:" + (arr.sort(function(a,b){return b-a})) + "</p>");
</script>

删除数组最后一个元素

第一种::

很简单的解决方案,声明一个新数组,循环遍历到原数组的倒数第二项push进新数组,返回新数组

function truncate(arr) {
   var m = [];
   for(var i = 0; i < arr.length - 1; i++){
       m.push(arr[i]);
   }
   return m;
}
第二种::

利用splice()的删除、增加、替换功能

function truncate(arr) {
  var m = arr.slice(0);
  m.splice(m.length-1,1);
  return m;
}
第三种:

利用slice()浅克隆,进行复制到末端的元素


functiontruncate(arr) {
   returnarr.slice(0,-1);
}

[]==false:true ![]==false: true

instanceof:检测某一个实例是否隶属于这个类

in:检测当前对象是否存在某个属性(不管当前这个属性是对象的私有属性还是公有属性,只要有结果就是TRUE)

hasOwnProperty:检测当前属性是否为对象的私有属性(不仅要有这个属性,而且必须还是私有的才可以)

THIS

1.给当前元素的某个事件绑定方法, 当事件触发方法执行的时候,方法中的THIS是当前操作的元素对象

2.普通函数执行,函数中的THIS取决于执行的主体,谁执行的,THIS就是谁(执行主体:方法执行,看方法名前面是否有“点”,有的话,点前面是谁this就是谁,没有this是window)

回流 重绘

reflow(回流):当render树的一部分或者全部因为大小边距等问题发生改变而需要重建的过程,叫做回流

repaint(重绘):当诸如颜色背景等不会引起页面布局变化,而只需要重新渲染的过程叫做重绘

什么会引起回流

页面渲染初始化

DOM结构变化,比如删除了某个节点;骨头都被打断了,肯定比抽脂更严重,所以会引发回流

render树变化,比如减少了padding;也就是进行抽脂手术

窗口resize事件触发

最复杂的一种:获取某些属性,引发回流 很多浏览器会对回流做优化,他会等到足够数量的变化发生,在做一次批处理回流。 但是除了render树的直接变化。 当获取一些属性时,浏览器为了获得正确的值也会触发回流。这样就使得浏览器的优化失效了 这些属性包括

offsetTop, offsetLeft, offsetWidth, offsetHeight

scrollTop/Left/Width/Height

clientTop/Left/Width/Height

width,height

调用了getComputedStyle(), 或者 IE的 currentStyle

var s = document.body.style;
s.padding = "2px"; // 回流+重绘
s.border = "1px solid red"; // 再一次 回流+重绘
s.color = "blue"; // 再一次重绘
s.backgroundColor = "#ccc"; // 再一次 重绘
s.fontSize = "14px"; // 再一次 回流+重绘
// 添加node,再一次 回流+重绘
document.body.appendChild(document.createTextNode('abc!'));

可以看出,回流一定伴随着重绘,而重绘却可以单独出现

减少回流

1.避免逐项更改样式。最好一次性更改style属性,或者将样式列表定义为class并一次性更改class属性

2.避免循环操作DOM。创建一个documentFragment或div,在它上面应用所有DOM操作,最后再把它添加到window.document。

3.避免多次读取offsetLeft等属性。无法避免则将它们缓存到变量。

4.将复杂的元素绝对定位或固定定位,使它脱离文档流。否则回流代价十分高

  • 补充:改变字体大小会引发回流
  • display:none指的是元素完全不陈列出来,不占据空间,涉及到了DOM结构,故产生reflow与repaint
  • visibility:hidden指的是元素不可见但存在,保留空间,不影响结构,故只产生repaint

FOR-IN循环

遍历一个对象中的键值对的,有多少组键值对,我们就遍历多少次

let obj = {name: 'xxx', age: 27, 0: 0, sex: 0, score: 100, 1: 1};
for (let key in obj) {
    // console.log(key);//=>KEY存储的是每一次循环获取的属性名
    // console.log(obj[key]);//=>每一次循环基于KEY获取属性值

    // if(key==='age'){
    //     break;  也支持BREAK和CONTINUE等关键词
    // }
    // console.log(key);
}

//=>FOR-IN遍历的时候有自己的顺序:先遍历数字属性名(按照小->大),再遍历字符串属性名(按照书写顺序)
for (let attr in obj) {
    console.log(attr);//=>0 1 name age sex score
}

obj.__proto__===Object.prototype : obj是Object这个类的一个实例
大括号中的是OBJ的私有属性,Object.prototype上的是OBJ公有属性
Object.prototype.bbbb = 1000;
for (let key in obj) {
    //=>FOR-IN循环只遍历当前对象可枚举(可遍历)的属性
    //1.对象的私有属性(自己写的)是可枚举的
    //2.浏览器内置的属性一般都是不可枚举的
    //3.自己在类的原型上设置的属性也是可枚举的,FOR-IN循环的时候也会被遍历出来(一般情况下我们是不想遍历到原型上的公有属性的)
    if (obj.hasOwnProperty(key)) {//=>一般使用FOR-IN在遍历对象的时候,我们加一个私有属性的验证,只有是私有的属性,我们才做操作
        console.log(key);
    }
}