zoukankan      html  css  js  c++  java
  • 2018面试总结第一轮

    头条面试题卷一


    JS里的New干了什么

      let obj = new Base();  

    这样代码的结果是什么,我们在Javascript引擎中看到的对象模型是:

    new操作符具体干了什么呢?其实很简单,就干了三件事情。

    let obj  = {}; 
    obj.__proto__ = Base.prototype;
    Base.call(obj);

    第一行,我们创建了一个空对象obj
    第二行,我们将这个空对象的__proto__成员指向了Base函数对象prototype成员对象
    第三行,我们将Base函数对象的this指针替换成obj,然后再调用Base函数,于是我们就给obj对象赋值了一个id成员变量,这个成员变量的值是”base”。 


    如果我们给Base.prototype的对象添加一些函数会有什么效果呢?
    例如代码如下:

      Base.prototype.toString = function() {     
        return this.id;
    }

    那么当我们使用new创建一个新对象的时候,根据__proto__的特性,toString这个方法也可以做新对象的方法被访问到。于是我们看到了:
    构造子中,我们来设置‘类’的成员变量(例如:例子中的id),构造子对象prototype中我们来设置‘类’的公共方法。于是通过函数对象和Javascript特有的__proto__与prototype成员及new操作符,模拟出类和类实例化的效果。

    Position定位属性

    static默认定位

    relative相对定位

    absolute绝对定位

    fixed固定定位

    sticky粘性定位

    HTML中meta标签的作用

    <meta> 元素可提供有关某个 HTML 元素的元信息 (meta-information),比如描述、针对搜索引擎的关键词以及刷新频率。

    参考链接

    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
    <meta name="format-detection"content="telephone=no, email=no" />
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" /><!-- 删除苹果默认的工具栏和菜单栏 -->
    <meta name="apple-mobile-web-app-status-bar-style" content="black" /><!-- 设置苹果工具栏颜色 -->
    <meta name="format-detection" content="telphone=no, email=no" /><!-- 忽略页面中的数字识别为电话,忽略email识别 -->
    <!-- 启用360浏览器的极速模式(webkit) -->
    <meta name="renderer" content="webkit">
    <!-- 避免IE使用兼容模式 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 -->
    <meta name="HandheldFriendly" content="true">
    <!-- 微软的老式浏览器 -->
    <meta name="MobileOptimized" content="320">
    <!-- uc强制竖屏 -->
    <meta name="screen-orientation" content="portrait">
    <!-- QQ强制竖屏 -->
    <meta name="x5-orientation" content="portrait">
    <!-- UC强制全屏 -->
    <meta name="full-screen" content="yes">
    <!-- QQ强制全屏 -->
    <meta name="x5-fullscreen" content="true">
    <!-- UC应用模式 -->
    <meta name="browsermode" content="application">
    <!-- QQ应用模式 -->
    <meta name="x5-page-mode" content="app">
    <!-- windows phone 点击无高光 -->
    <meta name="msapplication-tap-highlight" content="no">
    <!-- 适应移动端end -->

    web中实现长连接的方式

    ajax 参考链接

    websocket 参考链接

    iframe

    DOM的删除,移除,复制,插入,查询方法

    //查找节点
    document.getElementById("id");//通过id查找,返回唯一的节点,如果有多个将会返回第一个,在IE6、7中有个bug,会返回name值相同的元素,所有要做一个兼容
    document.getElementsByClassName("class");//通过class查找,返回节点数组
    document.getElementsByTagName("div");
    document.querySelector(); //方法返回文档中匹配指定 CSS 选择器的一个元素
    document.querySelectorAll();
    //创建节点
    document.createDocumentFragment();//创建内存文档碎片
    document.createElement();//创建元素
    document.createTextNode();//创建文本节点
     
    //添加节点
    var ele = document.getElementById("my_div");
    var oldEle = document.createElement("p");
    var newEle=document.createElement("div");
    ele.appendChild(oldEle);
    //移除
    ele.removeChild(oldEle);
    //替换
    ele.replaceChild(newEle,oldEle);
    //插入
    ele.insertBefore(oldEle,newEle);//在newEle之前插入 oldEle节点
     
    //复制节点
    var cEle = oldEle.cloneNode(true);//深度复制,复制节点下面所有的子节点
    cEle = oldEle.cloneNode(false);//只复制当前节点,不复制子节点
     
    //移动节点
    var cloneEle = oldEle.cloneNode(true);//被移动的节点
    document.removeChild(oldEle);//删除原节点

     参考链接

    浏览器缓存机制有哪几种

    正解答案

    http缓存详解参考链接

    exports 和 module.exports 的区别

    正解答案

    “原理很简单,即 module.exports 指向新的对象时,exports 断开了与 module.exports 的引用,那么通过 exports = module.exports 让 exports 重新指向 module.exports 即可。” 这一段有点画蛇添足。引用官网的一句 “如果一个新的值被赋值给 exports,它就不再绑定到 module.exports”。

    当你搞不明白export和module.export的关系的时候,就一直使用module.export好了。export是module.export的引用,然后export是个局部变量,module是个全局变量。

    原生实现Jsonp

    科普文章

    解决方法

     1 function ajax(params) {   
     2 
     3   params = params || {};   
     4 
     5   params.data = params.data || {};   
     6 
     7   var json = params.jsonp ? jsonp(params) : json(params);      
     8 
     9 
    10 
    11   // jsonp请求   
    12 
    13   function jsonp(params) {   
    14 
    15     //创建script标签并加入到页面中   
    16 
    17     var callbackName = params.jsonp;   
    18 
    19     var head = document.getElementsByTagName('head')[0];   
    20 
    21     // 设置传递给后台的回调参数名   
    22 
    23     params.data['callback'] = callbackName;   
    24 
    25     var data = formatParams(params.data);   
    26 
    27     var script = document.createElement('script');   
    28 
    29     head.appendChild(script);    
    30 
    31  
    32 
    33     //创建jsonp回调函数   
    34 
    35     window[callbackName] = function(json) {   
    36 
    37       head.removeChild(script);   
    38 
    39       clearTimeout(script.timer);   
    40 
    41       window[callbackName] = null;   
    42 
    43       params.success && params.success(json);   
    44 
    45     };    
    46 
    47 
    48 
    49     //发送请求   
    50 
    51     script.src = params.url + '?' + data;    
    52 
    53 
    54 
    55     //为了得知此次请求是否成功,设置超时处理   
    56 
    57     if(params.time) {   
    58 
    59      script.timer = setTimeout(function() {   
    60 
    61        window[callbackName] = null;   
    62 
    63        head.removeChild(script);   
    64 
    65        params.error && params.error({   
    66 
    67          message: '超时'   
    68 
    69        });   
    70 
    71      }, time);   
    72 
    73     }   
    74 
    75   };
    <script type="text/javascript">
        //定义一个发送Jsonp请求的函数
        function jsonp(obj) {
            //定义一个处理Jsonp返回数据的回调函数
            window["callback"] = function(object) {
                obj.success(JSON.parse(object));
            }
            var script = document.createElement("script");
            //组合请求URL
            script.src = obj.url + "?fn=callback";
            for(key in obj.data){
                script.src +="&" + key + "=" + obj.data[key];
            }
            //将创建的新节点添加到BOM树上
            document.getElementsByTagName("body")[0].appendChild(script);  
        }
    </script>
     
    <script type="text/javascript">
        //调用Jsonp函数发送jsonp请求
        jsonp({
            url:"http://localhost/index.php",
            data:{
                name:"小明",
            },
            success:function(obj) {
                alert("性别" + obj.sex);
            }
        });
    </script>

    Html5新增input类型

    • email
    • url
    • number
    • range
    • Date pickers (date, month, week, time, datetime, datetime-local)
    • search
    • color

    BFC是什么,怎么生成

      BFC 定义

      BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。

      BFC布局规则:

    1. 内部的Box会在垂直方向,一个接一个地放置。
    2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
    3. 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
    4. BFC的区域不会与float box重叠。
    5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
    6. 计算BFC的高度时,浮动元素也参与计算

    参考链接

    JS继承

    参考链接

    Vue原理

    文字参考链接

    双向绑定

     1 <body>
     2     <div id="app">
     3         <input type="text" id="txt">
     4         <p id="show-txt"></p>
     5     </div>
     6     <script>
     7         var obj = {}
     8         Object.defineProperty(obj, 'txt', {
     9             get: function () {
    10                 return obj
    11             },
    12             set: function (newValue) {
    13                 document.getElementById('txt').value = newValue
    14                 document.getElementById('show-txt').innerHTML = newValue
    15             }
    16         })
    17         document.addEventListener('keyup', function (e) {
    18             obj.txt = e.target.value
    19         })
    20     </script>
    21 </body>

    Object.defineProperty()

    方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。如果不指定configurable, writable, enumerable ,则这些属性默认值为false,如果不指定value, get, set,则这些属性默认值为undefined

     1 语法: Object.defineProperty(obj, prop, descriptor)
     2 obj: 需要被操作的目标对象
     3 prop: 目标对象需要定义或修改的属性的名称
     4 descriptor: 将被定义或修改的属性的描述符
     5 
     6 var obj = new Object();
     7 
     8 Object.defineProperty(obj, 'name', {
     9     configurable: false,
    10     writable: true,
    11     enumerable: true,
    12     value: '张三'
    13 })
    14 
    15 console.log(obj.name)  //张三

    学习链接

    头条面试题卷二


    new webSocket背后的原理。长链接方案。长轮询原理。
     
    节流函数。
     
    实现原生es6 bind函数。
     1 if (!Function.prototype.binds) {
     2   Function.prototype.binds = function (ctx) {
     3     if (typeof this !== 'function') {
     4       throw new TypeError("NOT_A_FUNCTION -- this is not callable")
     5     }
     6     var _this = this
     7     var slice = Array.prototype.slice
     8     var formerArgs = slice.call(arguments, 1)
     9     // 定义一个中间函数,用于作为继承的中间值
    10     var fun = function () {}
    11     var fBound = function (){
    12       let laterArgs = slice.call(arguments, 0)
    13       return _this.apply(ctx, formerArgs.concat(laterArgs))
    14     }
    15     // 先让 fun 的原型方法指向 _this 即原函数的原型方法,继承 _this 的属性
    16     fun.prototype = _this.prototype
    17     // 再将 fBound 即要返回的新函数的原型方法指向 fun 的实例化对象
    18     // 这样,既能让 fBound 继承 _this 的属性,在修改其原型链时,又不会影响到 _this 的原型链
    19     fBound.prototype = new fun()
    20     return fBound
    21   }
    22 }
     
    cookie是否有跨域问题,cookie从http迁移到https域名。
    cookie存在跨域问题。
     
    一个url的访问历程。ip如何映射到物理机。如何配置服务器代理映射。网关相关知识。
     
    es7的proxy拦截代理和defineProperty的区别。
     
    迭代器函数的原理。
     
    继承的方式。
     
    对restAPI的理解。get,post,put的区别
     
    vue和react的区别,实现双向绑定,两次改变数据哪一次生效。
     
    new Promise两次回调会生效几次。
     
    如何判断是否是数组。
     
    函数式编程和面向对象编程。
     
    两个算法题。
     
    补充

     1px边框解决方案

     1 .div::after {
     2     content: '';
     3     width: 200%;
     4     height: 200%;
     5     position: absolute;
     6     top: 0;
     7     left: 0;
     8     border: 1px solid #bfbfbf;
     9     border-radius: 4px;
    10     -webkit-transform: scale(0.5,0.5);
    11     transform: scale(0.5,0.5);
    12     -webkit-transform-origin: top left;
    13 }

     flex知识

    事件冒泡和事件捕获的机制和顺序

    Map数据结构

    它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。

    map()方法

    map()是数组的一个方法,它创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。map()里面的处理函数接受三个参数,分别指代当前元素、当前元素的索引、数组本身。

     1 /**** 原生map() ****/
     2 var arrTmp = [1,2,3];
     3 var arrDouble = arrTmp.map(function(num){
     4     return num*2;
     5 })
     6 // arrDouble -> [2,4,6]
     7  
     8 //注意,使用map()时实际传递了3个参数:
     9 arr.map(function(currentValue, index, array){
    10   // currentValue -> 数组中正在处理的当前元素
    11   // index -> 数组中正在处理的当前元素的索引
    12   // array -> 指向map方法被调用的数组
    13 })
    14  
    15 ["1", "2", "3.5"].map(parseInt); // 结果不是[1, 2, 3],而是[1, NaN, NaN]
    16 ["1", "2", "3.5"].map(function(num){ return parseInt(num)}); //得到正确结果[1, 2, 3]
    17  
    18 //使用map()重组数组
    19 var kvArray = [{key: 1, value: 10}, {key: 2, value: 20}, {key: 3, value: 30}];
    20 var reformattedArray = kvArray.map(function(obj) { var rObj = {}; rObj[obj.key] = obj.value; return rObj; });
    21 // kvArray不变,reformattedArray -> [{1: 10}, {2: 20}, {3: 30}],

    扩展运算符

    自定义事件(MDN)

    张鑫旭博客

    你了解前端路由吗?

     1 class Routers {
     2   constructor() {
     3     this.routes = {};
     4     this.currentUrl = '';
     5     this.refresh = this.refresh.bind(this);
     6     window.addEventListener('load', this.refresh, false);
     7     window.addEventListener('hashchange', this.refresh, false);
     8   }
     9 
    10   route(path, callback) {
    11     this.routes[path] = callback || function() {};
    12   }
    13 
    14   refresh() {
    15     this.currentUrl = location.hash.slice(1) || '/';
    16     this.routes[this.currentUrl]();
    17   }
    18 }
    19 
    20 window.Router = new Routers();
    21 var content = document.querySelector('body');
    22 // change Page anything
    23 function changeBgColor(color) {
    24   content.style.backgroundColor = color;
    25 }
    26 Router.route('/', function() {
    27   changeBgColor('yellow');
    28 });
    29 Router.route('/blue', function() {
    30   changeBgColor('blue');
    31 });
    32 Router.route('/green', function() {
    33   changeBgColor('green');
    34 });
     1 class Routers {
     2   constructor() {
     3     this.routes = {};
     4     // 在初始化时监听popstate事件
     5     this._bindPopState();
     6   }
     7   // 初始化路由
     8   init(path) {
     9     history.replaceState({path: path}, null, path);
    10     this.routes[path] && this.routes[path]();
    11   }
    12   // 将路径和对应回调函数加入hashMap储存
    13   route(path, callback) {
    14     this.routes[path] = callback || function() {};
    15   }
    16 
    17   // 触发路由对应回调
    18   go(path) {
    19     history.pushState({path: path}, null, path);
    20     this.routes[path] && this.routes[path]();
    21   }
    22   // 监听popstate事件
    23   _bindPopState() {
    24     window.addEventListener('popstate', e => {
    25       const path = e.state && e.state.path;
    26       this.routes[path] && this.routes[path]();
    27     });
    28   }
    29 }

    请你实现一个深克隆

    阮一峰版的快速排序完全是错的

    XSS 中文名为跨站脚本, 是发生在目标用户的浏览器层面上的,当渲染DOM树的过程成发生了不在预期内执行的JS代码时,就发生了XSS攻击。

     
     
     
    vue相关

    既然React/Vue可以用Event Bus进行组件通信,你可以实现下吗?

    class EventEmeitter {
      constructor() {
        this._events = this._events || new Map(); // 储存事件/回调键值对
        this._maxListeners = this._maxListeners || 10; // 设立监听上限
      }
    }
    // 触发名为type的事件
    EventEmeitter.prototype.emit = function(type, ...args) {
      let handler;
      // 从储存事件键值对的this._events中获取对应事件回调函数
      handler = this._events.get(type);
      if (args.length > 0) {
        handler.apply(this, args);
      } else {
        handler.call(this);
      }
      return true;
    };
    
    // 监听名为type的事件
    EventEmeitter.prototype.addListener = function(type, fn) {
      // 将type事件以及对应的fn函数放入this._events中储存
      if (!this._events.get(type)) {
        this._events.set(type, fn);
      }
    };

  • 相关阅读:
    Merge Sorted Array
    Remove Duplicates from Sorted List
    Climbing Stairs
    Plus One
    微信开发 (四) 微信网页授权
    基于注解的实现获取微信openId1
    利用TortoiseGit(小乌龟)将项目上传至GitHub网站
    微信网页授权多次回调code请求
    安装git之后,桌面出现蓝色问号的解决方法
    两个日期之间的日历
  • 原文地址:https://www.cnblogs.com/paxster/p/9348034.html
Copyright © 2011-2022 走看看