美文网首页
2019-03-08临时回顾的笔记

2019-03-08临时回顾的笔记

作者: wudimingwo | 来源:发表于2019-03-10 16:11 被阅读0次
    1. 关于 a++ ,++a, a--, --a,
      先运算还是先执行语句的问题.
      当 ++a 时, 只要遇到语句中变量取值情况出现, 就先执行++a ,然后才会进行取值操作.
    1. 关于 a += b * c, a *= b + c;
      相当于 a = a + ( b * c ); a = a * (b + c);
      即, 注意一下运算顺序.
    1. function test () {} 自带一个属性name,
      即, test.name 会返回 字符串类型的 'test',
      需要注意的是,
      var test = function abc () {},
      定义成这样时,
      abc 这个变量会提示是 未定义的变量.
      但test.name 返回的却是 字符串 'abc'
    1. arguments 实参列表, arguments.length 返回实际参数的数量.
      fn.length 返回形参的数量
    1. arguments 和 形参一一映射关系
      实际上, 刚开始的时候是很容易理解的,
      可到了后面学过引用值和原始值的特点之后,反而不太好理解.
    function test (a) {
      arguments[0] = 10;
      console.log(a)/ 输出10
    }
    test(2) 
    
    1. 关于toString 的一个细节认识的修正
      null 和 undefined 因为没有原型链 所以无法调用 toString
      而123.toString 会首先识别成浮点型,所以无法调用toString
    我一直以为 123 即number类型之所以不能直接调用toString 
    是因为 123 不会临时转换成Number类对象的缘故,
    而像下面这样则是可以的
    var num = 123; 
    num.toString() ; /返回'123'
    
    而true 则可以直接调用
    true.toString() ; / 返回'true'
    
    这种不统一当时我还觉得很奇怪, 现在明白了,
    如果直接浮点型数据, 则能正常调用
    
    123.1.toString() / 返回 '123.1'
    
    
    
    1. 关于call 的一个隐式类型转换
    function test () {console.log(this)};
    test() ;/ 返回 window 
    test.call(); / 返回 window 
    test.call(null); / 返回 window 
    test.call(undefined); / 返回 window 
    test.call({}); / 返回 window {}
    test.call([]); / 返回 window []
    到这里没什么问题, 没发生类型转换
    到了原始值就有了
    
    test.call(123); / 返回 Number {123}
    test.call(''); / 返回 String {''}
    test.call(true); / 返回 Boolean {true}
    

      1. document.styleSheet 这个对象不太明白.
        -2.onclick 只能绑定一个函数, addEventListener 能绑定多个, onclick 能 覆盖add吗? -- 不会
        -3. oncontextmenu 和 addEvent , 如果 前者把默认行为取消掉, 后者也会取消吗? -- 会, 表明默认事件的api 两者共同影响一个变量.
        -4. 取消的默认事件, 还能返回嘛? -- 大神的回复 https://segmentfault.com/q/1010000004819075
        -5. 回忆, 是否能用 for + let 解决闭包? 可以, 查看babel 的翻译,能看出就是用 立即执行函数解决的?
        严格来讲, 这不能说是用闭包解决的问题, 因为没有把内部的函数传递给外部.
        -6. 封装兼容的事件绑定函数
    function addEvent (div, type, handle,flag = false) {
                if (window.addEventListener) {
                  div.addEventListener(type,handle,flag)
                } else if (window.attachEvent) {
                  div.attachEvent("on" + type, function (e) {//因为 attachEvent 的 this 默认指向window, 所以这里更改一下.
                    handle.call(div,e);
                  })
                } else {
                  div["on" + type] = handle;
                }
              }
    

    -7. 假设一个ul>li结构, 用ul 进行事件委托, 但在 ul绑定事件时, 用事件捕获模式, 请问,事件发生时, target 是 ul 还是 li?

    • 依然是li, 表明target与 冒泡机制和捕获机制无关.
      -8. 同一个对象的同一个事件类型,上面绑定了两个事件处理函数,一个符合冒泡,一个符合捕获,点击一个元素后,是先捕获,还是先冒泡?

    • 先捕获, 后冒泡, 可以记为, 捕获用的是true, 冒泡用的是false, 设置的应该比默认的优先级高一点. 对target元素, 谁先绑定, 谁先触发.

      1. focus,blur,change,submit,reset,select 等事件不冒泡
    • 9.1 能冒泡的事件 (非常全) - https://www.cnblogs.com/rubylouvre/p/5080464.html

      1. 取消冒泡 e.stopPropagation() e.cancelBubble = true;
      1. 阻止默认事件 return false event.preventDefault(); event.returnValue = false
      1. a标签阻止默认事件 <a href = “avascript:void( )”>
      1. srcelement和target
      1. input.value 和 input 的 e.value 是一个值? -- 废话, 当然不可能是一样的, e.value 的值为 undefined
      1. 练习题, 实现拖拽功能.
      1. 实际上, 通常最消耗时间的地方是, 边界关系,逻辑关系稍微复杂一点.
    • 或者, 有些数学关系, 并不像其他问题一样, 是单纯的, 线性的, 而是涉及稍微多个量, 并且还要注意方向, 即, 需要对多个因素, 需要保持关注时

    • 超出临时记忆范围时, 易出现这种情况.

    • 解决方法是, 用文字, 或者用图片, 进行辅助思考. 大脑负荷会低很多, 效率就会高很多, 时间消耗就少一点.

      1. 鼠标事件, click, up, down的触发顺序, down -> up -> click.. 根据这个顺序, down和up 的时间差, 可以防止和click 的冲突
      1. 键盘事件触发顺序 keydown -> keypress -> keyup
      1. keydown 和 keypress 的区别?
    • keydown 监控所有按键, keypress 监控字符类按键,

    • keypress 能返回ask码

    • keydown 能通过 e.key 获得字符, 也能识别大小写

      1. 再次整理一下js中各种位置和几何尺寸相关的属性, 和api - https://www.jianshu.com/p/fffa7a8efb22
      1. 按需加载js的函数封装, 有懒加载的意思. 跟JSONP也有点类似,(应该能跨域)
    function loadScript (url,callback) {
                var script = document.createElement('script');
                script.type = "text/javascript";
                
                if (script.readyState) {// 兼容ie
                  script.onreadystatechange = function (e) {
                    if (script.readyState == "complete" || script.readyState == "loaded") {
                      tools[callback]();
                      
                    }
                  }
                } else{
                  script.onload = function () {
                    tools[callback]();
                  }
                }
                script.src = url;
                document.body.appendChild(script);
              }
              function loadScript (url,callback) {
                var script = document.createElement('script');
                script.type = "text/javascript";
                
                if (script.readyState) {// 兼容ie
                  script.onreadystatechange = function (e) {
                    if (script.readyState == "complete" || script.readyState == "loaded") {
                      eval(callback);
                      
                    }
                  }
                } else{
                  script.onload = function () {
                    
                    eval(callback);
                  }
                }
                script.src = url;
                document.body.appendChild(script);
              }
              
              
              function loadScript (url,callback) {
                var script = document.createElement('script');
                script.type = "text/javascript";
                if (script.readyState) {// 兼容ie
                  script.onreadystatechange = function (e) {
                    if (script.readyState == "complete" || script.readyState == "loaded") {
                      callback();
                    }
                  }
                } else{
                  script.onload = function () {
                    callback();
                  }
                }
                console.log(script);
                script.src = url;
                document.body.appendChild(script);
              }
    

    -22 js 事件加载线

    • 创建docuemnt对象, 解析文档.

    • document.readyState = "loading"

    • 遇到 link css 异步加载, 解析文档

    • 遇到 script 外部文件, 同步加载, 阻塞解析

    • 遇到 script asyinc , 异步加载, 解析文档, 加载完成时立即执行

    • 遇到 script defer , 异步加载, 解析文档, 解析完成时执行

    • 遇到 img 等资源, 异步加载, 解析文档

    • 当domtree解析完毕, document.readyState = "interactive" (表示可以交互了?) (此时执行defer script)

    • 触发 document.DOMContentLoaded 事件, 标志, 同步脚本执行阶段, 转为事件驱动阶段.

    • 全部加载完毕时, 触发 window.onload事件, document.readyState = "complete"

    • 22.1 jQ中, $(document).ready() 和 window.onload的区别?

    • 一个是解析完执行, 一个是加载完执行, 前者比后者反应快.

    document.ready = function (callback) {
        ///兼容FF,Google
        if (document.addEventListener) {
            document.addEventListener('DOMContentLoaded', function () {
                document.removeEventListener('DOMContentLoaded', arguments.callee, false);
                callback();
            }, false)
        }
         //兼容IE
        else if (document.attachEvent) {
            document.attachEvent('onreadystatechange', function () {
                  if (document.readyState == "complete") {
                            document.detachEvent("onreadystatechange", arguments.callee);
                            callback();
                   }
            })
        }
        else if (document.lastChild == document.body) {
            callback();
        }
    }
    

    -23. 为什么 script 标签通常写在最下面?

    • 同步加载时, 解析完就会执行, 操作dom时, 有可能找不到,而报错.
    • js执行会阻塞页面渲染. 因为js是单线程

    正则表达式

    -24. 创建正则的两种方式

    var reg = /abc/gmi;
    
    var reg = new RegExp(str,"gim");// 优点, 可以传变量进去.
    
    

    -25.1 深入理解正则 https://www.cnblogs.com/lizhenlin/p/6654934.html
    -25.2 深度理解正则: 这个是大神, 从注释部分开始优点看不懂 https://www.cnblogs.com/zuoshaowei/p/6058955.html?utm_source=itdadao&utm_medium=referral
    -25.3 正则表达式30分钟入门教程 http://deerchao.net/tutorials/regex/regex.htm
    -25.4 注意 : /abc/g.test(str) 和 /abc/.test(str) 的表现是不一样的. 有g时, 会向后移动.会返回false
    -25.5 习题 :写一个字符串,检验一个字符串首尾是否都含有数字 /^\d\w*\d$/
    -26.6 习题 : 把 the-first-name 变成小驼峰式写法 theFirstName : 用 replace

    var reg = /-(\w)/g;
    var str = the-first-name;
    str.replace(reg,function ($,$1) {return $1.toUpperCase()})
    

    ES6 简书笔记文集 https://www.jianshu.com/nb/32041352

    -1. let,const : 暂时性死区, 不得重复声明, 无变量提升. ;解决闭包; let x = x 会报错
    -2. 函数 : 参数默认值, 惰性求值.
    -3. 惰性求值延伸 -- 求值策略(赋值策略) : 是个大神 https://www.cnblogs.com/TomXu/archive/2012/02/08/2341439.html
    -4. 箭头函数,没有this,没有 arguments,没有super,没有prototype,不能被 new 操作符运算,call,apply,bind 也失去作用
    -5. 箭头函数中 this指向,离自己最近的非箭头函数作用域中的this ,arguments与此类似,指向离自己最近的非箭头函数的arguments
    -6. 箭头函数+setTimeout 配合, 可以不用处理this
    -7. 几种迭代方式
    -7.1 for i++ ,, 遍历数组

    var arr = [1,2,3];
    var len = arr.length;
    for(var i = 0; i < len; i++) {
      console.log(arr[i]);
    }
    
    

    -7.1.1 forEach , 遍历数组

    var arr = [1,2,3];
    arr.forEach((item,index) => {
      console.log(item);
    })
    
    

    -7.2 for in 遍历对象

    var obj = {name : "mike"};
    for(var key in obj) {
      console.log(obj[key]);
    }
    
    防止遍历原型链上的
      var obj = {name : "mike"};
    for(var key in obj) {
      if(obj.hasOwnProperty(key)){
      console.log(obj[key]);
      }
    }
    
    

    -7.3 for of 用来遍历 迭代器 , 不能用来迭代对象, 用来迭代数组会丢失第一个?

          function* fibs() {
            let a = 0;
            let b = 1;
            while(true) {
              if (a > 100) {
            /如果没有限制条件, 下面的 for of 会死循环.
                return "over"
              }
              yield a;
              [a, b] = [b, a + b];
            }
          }
    
    let i = fibs();
    for(let item of i){
      console.log(item);
    }
    

    -7.4 解构赋值, 可以迭代 对象, 数组, 迭代器(迭代器内部调用的是next);
    -7.4.1 使用解构赋值时, 会遍历原型链上的属性.
    -7.5 对象的遍历
    ES6 一共有 5 种方法可以遍历对象的属性。

    (1)for...in

    for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。

    (2)Object.keys(obj)

    Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。

    (3)Object.getOwnPropertyNames(obj)

    Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。

    (4)Object.getOwnPropertySymbols(obj)

    Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。

    (5)Reflect.ownKeys(obj)

    Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。

    以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。

    首先遍历所有数值键,按照数值升序排列。
    其次遍历所有字符串键,按照加入时间升序排列。
    最后遍历所有 Symbol 键,按照加入时间升序排列。

    -7.5 原型相关的API
    Object.setPrototypeOf(obj, proto);
    Object.getPrototypeOf(this).foo
    Object.createObject(proto)

    let [a,b,c,d,e] = fibs();
    let {name : s } = obj;
    let [a,b] = arr;
    let [...arr] = arr1; // 完成浅克隆 arr == arr1 返回false
    

    -7.5 字符串扩展
    -CharAt(num),
    -charCodeAt(num);// 返回该字符的unicode码,

    • str.slice(start,end); [start,end) 左闭右开
    • str.indexOf(txt,start=0);
    • str.includes(txt,start=0)
    • str.startWith(txt,start=0)
    • str.endWith(txt,end=length)
    • str.repeat(num);
      -7.6 模板字符串 : 跟函数配合时的应用需要加强.
      -7.7 数组的扩展
    • Array.of() 增强版 new Array() 生成数组
    • Array.from() 将类数组转换为数组 arguments Nodelist
    • 类数组转成数组, 也可以用扩展运算符 let realArr = [...oDivList];
    • arr.find((item,index,self) => {})
    • arr.findIndex((item,index,self) => {}) 遇到符合条件的马上停止
    • arr.fill(value, start=0,end=length) 常用于初始化操作.

    生成器, 迭代器

    -1. 可迭代的数据类型 arr,set,map,
    -2. 可返回迭代器的 函数 entry(), keys(), values()
    -3. 内部api : next 返回值 {value,done}
    -4. for of 用于迭代迭代器
    -5. 内部隐式生成迭代器 for(let value of arrSymbol.iterator)
    -6. 无法用for of 遍历两次同一个迭代器, 但可以迭代arr,set,map , 因为每次会生成新的迭代器arrSymbol.iterator
    -6.1 str 没有 entry(),keys(),values() , 但拥有 strSymbol.iterator, 所以可以用 for of 迭代.
    -7. 字符串可用 for of迭代, 双字节字符 , for in 不可
    -8. 生成器为函数, 返回的数据为迭代器.
    -9. return 能够终止 next
    -10 委托迭代器

    function *pro (arr,string) {
                yield * arr;
                yield * string;
              }
              let i = pro([1,2,3,4],'abcdef');
    

    class

    -1. 可以返回一个可迭代的数据!

                  class iteratorArray {
                    constructor (arr = []) {
                      this.arr = arr;
                    }
                    
                    *[Symbol.iterator](){// 通过定义这个属性, 就可以让数据可迭代. 可以调用next, 可以 for of
                      yield *this.arr[Symbol.iterator]()
                    }
                  }
                  
                  let arr = new iteratorArray([1,2,3]);
                  
                  for(let item of arr) {
                    console.log(item);
                  }
    

    Promise

    -模拟封装Promise https://www.jianshu.com/p/029217e15481

    es6 习题 https://www.jianshu.com/p/5db01aa0fa52

    -1. 链表和数组的区别 : 链表 地址是 非连续的, 数组的内存是 连续的.
    -2. 类数组转数组的方法 : 之前最常用的是 [].slice.call(arguments),es6中的数组扩展符, [...arguments],Array.from(arguments);
    -3. 解构赋值的用途 : https://www.cnblogs.com/fireporsche/p/6288796.html

    SCSS 中文教程 - https://www.sass.hk/docs/

    -1. 层级结构
    -2. & 指向父级
    -3. @name 变量
    -4. @extend 继承
    -5. 控制语句 @if @else-if ,@each ,@ for from through @while
    -6. 混合指令 @mixin --- @include

    vue 生命周期- 钩子

    -1. beforeCreate created beforeMount mounted beforeUpdate updated beforeDestroy destroyed


    一些增加理解的模拟封装

    1. 模拟数组的迭代器

    let arr = [1,2,3,4,5];
              
              function createIterater (arr = []) {
                let nextIndex = 0;
                return {
                  next(){
                    if (arr.length - 1 < nextIndex ) {
                        return {
                          value : undefined,
                          done : true
                        }
                    }else{
                      return {
                         value : arr[nextIndex++],
                         done : false
                      }
                    }
                  }
                  
                }
              }
              
              let nod = createIterater(arr);
    

    2. 生成器 + 模板字符串的应用, 非常的秀

              function first () {
                console.log('first ing');
                setTimeout(function () {
                    console.log("first");
                },1000)
              }
              function second () {
                console.log('second ing');
                setTimeout(function () {
                    console.log("second");
                },2000)
              }
              function third () {
                console.log('third ing');
                setTimeout(function () {
                  console.log("third");
                },1000)
              }
              
               function *createIterator () {
                let result = `${yield first()}${yield second()}${yield third()}`;
                console.log(result);
              }
              
              let process = createIterator();
    

    3. class + 迭代器

                  class iteratorArray {
                    constructor (arr = []) {
                      this.arr = arr;
                    }
                    
                    *[Symbol.iterator](){// 通过定义这个属性, 就可以让数据可迭代. 可以调用next, 可以 for of
                      yield *this.arr[Symbol.iterator]()
                    }
                  }
                  
                  let arr = new iteratorArray([1,2,3]);
                  
                  for(let item of arr) {
                    console.log(item);
                  }
    

    4. 模拟封装Promise

    class myPromise {
                constructor (fn) {
                  if (typeof fn !== "function") {
                    throw TypeError(`myPromise resolver ${fn} is not a function`)
                  }
                  this.state = "pending";
                  this.data = undefined;
                  
                  this.resolveCB = [];
                  this.rejectCB = [];
                  
                  let resolve = (data) => {
                    if (this.state == "pending") {
                      setTimeout(() => {
                        
                      this.state = "resolved"
                      this.data = data;
                      this.resolveCB.forEach(fn => fn());
                      },0)
                    }
                  }
                  let reject = (data) => {
                    if (this.state == "pending") {
                      setTimeout(() => {
                        
                      this.state = "rejected"
                      this.data = data;
                      this.rejectCB.forEach(fn => fn());
                      },0)
                    }
                  }
                  
                  fn(resolve,reject);
                }
                then (resolveFn, rejectFn) {
                  if (this.state == "resolved") {
                    let rus = resolveFn(this.data);
                    if (rus instanceof myPromise) {
                      return rus
                    }else{
                      return myPromise.resolve(rus);
                    }
                  }
                  if (this.state == "rejected") {
                    let rus = rejectFn(this.data);
                    if (rus instanceof myPromise) {
                    return rus
                  }else{
                    return myPromise.resolve(rus);
                  }
                  }
                  
                  if (this.state == "pending") {
                    return new myPromise((resolve, reject) => {
                      console.log(this.resolveCB);
                      this.resolveCB.push(((resolveFn)=>{
                        return () => {
                          var res = resolveFn(this.data);
                          if (res instanceof myPromise) {
                            res.then(resolve,reject);
                          } else{
                            resolve(res)
                          }
                        }
                      })(resolveFn));
                      
                      this.rejectCB.push(((rejectFn)=>{
                        return () => {
                          var res = rejectFn(this.data);
                          if (res instanceof myPromise) {
                            res.then(resolve,reject);
                          } else{
                            resolve(res)
                          }
                        }
                      })(rejectFn));
                    })
                  }
                } 
                static resolve (data) {
                  return new myPromise((suc) => {
                    suc(data);
                  })
                }
                static reject (data) {
                 return new myPromise((suc,err) => {
                  err(data);
                })
                }
            }
    

    webpack 基础配置

    // node 自带路径模块.
    var path = require("path");
    // 插件必须 在这里引入
    var HtmlWebpackPlugin = require("html-webpack-plugin");
    
    var uglify = require("uglifyjs-webpack-plugin");
    
    var MiniCss = require("mini-css-extract-plugin");
    // 模块化导出格式
    module.exports = {
      // 配置入口文件
      entry: {
        main: "./src/index.js"
      },
      // 配置出口文件
      output: {
        // 出口文件名
        filename: "[name].js",
        path: path.resolve(__dirname, "dist") //__dirname 指的是根目录.dist 设置出口文件夹.
      },
      // 配置 环境变量, 设置为开发环境
      // 导出的文件不是压缩的
      mode: "development",
      // 设置为生产环境,导出的文件是压缩的.
      //mode : "production"
    
      // 开启服务器时,默认打开dist文件下的index.html
      // 自动刷新页面
      devServer: {
        contentBase: "dist",
        // 更改 端口
        port: 9879
      },
    
      // 应用loader
    
      module: {
        rules: [
          // css loader
          {
            // 正则匹配需要转换的文件类型
            test: /\.css$/,
            // 使用的加载器, 顺序是从右向左,css-loader 用来解析 css style-loader 用来注入style标签?
            use: [MiniCss.loader, 'css-loader']
          },
    //            {
    //              test : /\.html$/,
    //              use : [
    //                {// 单独抽离的文件,进行处理生成文件
    //                  loader : 'file-loader',
    //                  options : {
    //                    name : "index.html"
    //                  }
    //                },
    //                {// 单独抽离html文件
    //                  loader : 'extract-loader'
    //                },
    //                {//找到 html文件
    //                  loader : 'html-loader'
    //                }
    //              ]
    //            },
    //       es6 js loader
    //            {
    //              test : /\.js$/,
    //              use : ["babel-loader"]
    //            },
    //       图片 loader 字体loader
          {
            test: /\.(jpg|png)$/,
            use: [{
              loader: "url-loader",
              options: {
                //小于该大小时,生成url码,大于时,生成独立文件.
                limit: 8912,
                // 独立文件的文件夹,以及名称和格式.
                name: "/img/[name].[ext]"
              }
            }]
          }
        ]
      },
      plugins: [
        new HtmlWebpackPlugin({
          // 设置title
          title : "title",
          template : "./src/index.html"
        }),
    
        new uglify(),
        new MiniCss({
          // contenthash:8 根据内容生成八位数哈希值.
          filename : "[name]_[contenthash:8].css"
        })
      ]
    
    }
    

    常用vue 用例

    <div id="app">
        <p>{{ number }}</p>
        <input type="button" name="btnGetNumber" value="增加" v-on:click="getNumber()">
      </div>
      <script>
        var app = new Vue({         
          el: '#app',               
          data: {                   
            number: 1
          },
          methods: {
            // 事件响应方法的逻辑代码
            getNumber: function (e) {
              this.number += 1;   // 不管是内联方法调用,还是绑定事件处理器两种方式执行事件响应方法的时候 this都是指向 app
            }
          },
          watch: {
            // 监控number的变化,并自动执行下面的函数
            number: function (val, oldVal) {
              console.log('val:' + val + ' - oldVal: ' + oldVal);
            }
          }
        });
    

    相关文章

      网友评论

          本文标题:2019-03-08临时回顾的笔记

          本文链接:https://www.haomeiwen.com/subject/obxjpqtx.html