知识点--面试可能用得到

  1. ::before 和 :after中双冒号和单冒号 有什么区别?解释一下这2个伪元素的作用
    经常会遇到的的伪元素有:::before, ::after,伪类包括::focus, :hover, :link
    在css2中,对两者没有特别的区分,单冒号和双冒号都可以;css3中的伪元素需要用双冒号表示。
    CSS3伪类和伪元素的特性和区别
    :before和::before的区别

  2. undefined与null的区别
    js最早只有null,后来设计者认为null是个对象,需要一个非对象的类型,进而引入了undefined,其实两者差别不大。

  • null:

    1. 转为数字为0
    2. 作为函数的参数,表示该函数的参数不是对象
    3. 作为对象原型链的终点
  • undefined:

    1. 变量被声明了,但没有赋值时,就等于undefined。
    2. 调用函数时,应该提供的参数没有提供,该参数等于undefined
    3. 对象没有赋值的属性,该属性的值为undefined
    4. 函数没有返回值时,默认返回undefined

有必要解释下undefined:在IE8以下的浏览器,undefined是可以把覆盖的;在IE8+的浏览器中,undefined是不可以被覆盖的。因此早期的框架需要用函数多一个参数的方式来显示指定undefined,防止其被覆盖:

  (function(a,b,undefined){
  })("arg1","arg2");//最后一个形参不传值,则没传值得形参值为undefined类型

同理,判断一个值是不是undefined的最好办法是typeof,而不是直接对比值:

  typeof(value) === 'undefined'
  value === undefined   // undefined有被覆盖的危险

当然 可以采用通用的判断类型的方式进行判断:

  var o = {};
  o.toString.call(window.aaa).toLowerCase() // [object undefined]

还可以采用下面的方式:(events模块采用的方法)

  return value === void 0; // 

参考: 双面undefined

  1. ['1', '2', '3'].map(parseInt)的结果为什么是1, NaN, NaN?
    parseInt接受两个参数:数字和进制。
    map会给callback函数提供三个参数,分别是值、索引和数组本身。
    因此执行的结果应该是:parseInt(1,0), parseInt(2,1), parseInt(3,2)

  2. use strict的作用

  3. 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为

  4. 消除代码运行的一些不安全之处,保证代码运行的安全

  5. 提高编译器效率,增加运行速度

  6. 为未来新版本的Javascript做好铺垫

禁止以下用法:

  1. 不允许一个变量没有声明就赋值,默认是全局变量

  2. with和eval的使用

  3. 禁止this指向window

  4. 对象重名属性,函数重名参数

  5. 怎么利用js检测浏览器是否支持某个css特性
    判断DOM元素的style属性,如:document.body.style里是否含有这个属性。程序如下:

    var supports = (function() {
        var div = document.createElement('div'),
            vendors = 'Khtml O Moz Webkit'.split(' '),
            len = vendors.length;
        return function(prop) {
            if (prop in div.style) return true;
            if ('-ms-' + prop in div.style) return true;
            prop = prop.replace(/^[a-z]/, function(val) {
                return val.toUpperCase();
            });
            while (len--) {
                if (vendors[len] + prop in div.style) {
                    return true;
                }
            }
            return false;
        };
    })();

    // use
    if (supports('textShadow')) {
        document.documentElement.className += ' textShadow';
    }
  1. 0.1+0.2 为什么不等于0.3 而是0.30000000000000004
    计算机中数字的表示都是通过二进制实现的。0.1到0.9的9个小数中,只有0.5是可以准确表示的,其余的几个都是一种近似的表示;因此数字相加过程中的精度丢失是个很正常的事情。
    JavaScript奇味探索

  2. call和apply的第一个参数是null/undefined是什么意思?
    非严格模式下,是把函数的执行环境指定为全局变量(window或global);严格模式下不进行转换,传入什么是什么:

  function aa(){console.log(this);}
  aa.call(null) // 严格模式 输出null; 非严格模式 输出window
  1. 为什么 parseInt(0.0000008) === 8?
    当小数点后面大于等于7为的时候,会转成科学计数法。因此会有以下的转换:
  parseInt(0.0000008) == parseInt('8e-7') == 8
  parseInt(0.000008)  == 0
Paste_Image.png
  1. 一道题目的思考:
  var a = {n:1};  
  var b = a; // 持有a,以回查  
  a.x = a = {n:2};  
  alert(a.x);// --> undefined  
  alert(b.x);// --> {n:2}

关键是a和a.x赋值的时候,对象的指向:

知识点--面试可能用得到_第1张图片
Paste_Image.png

javascript 连等赋值问题

  1. 浏览器缓存控制
    Last-Modified和if-modified-since
    服务端在Response Header中返回 Last-Modified,下次请求的时候浏览器带上 if-modified-since字段,服务器依据此判断是不是有更新。
    expires
    过期时间,如果没有过期
    etag和if-none-match
    根据etag是不是一致决定要不要走缓存,但是由于etag在分布式服务器中不一致,不推荐使用。
    cache-control:max-age=秒
    通过max-age,去更新expires时间:Expires =max-age + “每次下载时的当前的request时间”
    浏览器缓存详解:expires,cache-control,last-modified,etag详细说明

  2. script中的async defer:


  3. 没有 defer或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。


  4. 有 async,加载和渲染后续文档元素的过程将和 script.js 的加载并行进行(异步),加载完成后立即执行。


  5. 有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。

知识点--面试可能用得到_第2张图片
Paste_Image.png

采用了defer机制时,需要在 DOMContentLoaded 事件中进行DOM操作,如Angular1.x的手动bootstrap。
defer和async的区别

  1. observable数据监听的实现
    数据observable的实现方法包括以下几种:
  • 脏检测(Angular)
  • Object.defineProperty(vue avalon)
  • 低版本浏览器借助VbScript(avalon)
  • 属性转成函数:(knockout)
      function observable(val){
        return function(newVal){
          if (arguments.length > 0){
              val = newVal;
              notifyChanges();
          }else{
              return val;
          }
        }
    }
    var data = {};
    var data.a = observable(1);
    var value = data.a() //取值
    data.a(2); //赋值
    
  • Es6 Proxy:proxy

上述是是现在比较流行的方法。数组的话,需要对其方法进行监听, 如push/unshift/splice 这三种添加方法会对新加对象进行监听,而其他函数则直接触发依赖更新。如: [1,2,3] 这种数组,由于元素是简单对象,当其改变的时候不会触发模块更新。

谈谈数据监听observable的实现

前端面试常见问答
前端面试题

你可能感兴趣的:(知识点--面试可能用得到)