zoukankan      html  css  js  c++  java
  • 前端0:js,css基础

    1.js是按顺序执行的,故把 <script> 内容放到 <head> 里,或放到 <body> 内容之前,与<script> 内容放到 <body> 内容之后 执行的效果会有所不同。经常会遇到:

      ①<head><script> 里修改图片路径 obj.src 失败,由于未加载 window.onload。

    2.节点处理

      由于浏览器兼容性差异,各标签之间的空白也算为节点,index 随之变化。

    3.查询字符串:JS与服务器的通信,避免URL等数据格式不正确即未经编码,导致通信错误。

    1 function addQueryStringArg(url,name,value){
    2 if(url.index("?")==-1){
    3 url+="?";
    4 }else{
    5 url+="&";
    6 }
    7 url+=encodeURLComponent(name)+"="+encodeURLComponent(value);
    8 return url;
    9 }

    4.数组处理:数组其实和对象一样,也是有属性的,即 0,1,2,3...,所以才能用下标查找,同时可以用原型链查找属性的方法 key in array。

      arr=null 数组删除

      arr.pop 去尾,返回尾巴

      arr.join('.')   数组转字符串,以 . 分开,一般配合 split

      arr.reduce(fn)  接收一个函数进行两两迭代,数组中的每个值(从左到右)开始合并,最终计算为一个值。

      arr.map(fn,cb)   参数为函数表达式及回调,fn(a,b,c) 参数默认为当前数组值,当前数组值索引,etc  

      arr.shift() 删除头,返回头

      arr.unshift('a') 加头,返回length

      arr.push 加尾,返回length

      arr.splice(index,howmany,...itemn) 添加删除,返回原arr,index表示操作位置,index初始为0;howmany表示删除个数,howmany=0为不删除,改插入,插入index-1位置;...itemn为加入的参数若干,非纯函数,输出改变

      

    var xs = [1,2,3,4,5];
    
    // 不纯的
    xs.splice(0,3);
    //=> [1,2,3]
    
    xs.splice(0,3);
    //=> [4,5]
    
    xs.splice(0,3);
    //=> []

      纯函数:arr.slice(start,end) 提取,返回子arr,内容是从 start 处到 end-1,参数可负,原arr不变,纯函数输出不变

      Array.prototype.slice.apply(arguments) 类数组转数组 e.g.call

      arr.indexOf

      arr.find(callback) 查找满足条件的第一个值

      arr.findIndex(callback)

    字符串处理:

      str.substring(start,end) 提取,返回子str,内容是从 start 处到 end-1,if (start<0) start=0,原str不变

      str.split() 分割,返回数组arr,若需要进一步split,注意:分割后为数组,故用for循环split

      str.parse() 转成json,注意:字符串中的属性要严格加上引号

      str.substr(start,length) 返回子str,注意:不建议使用

      字符串的部分修改可以使用replace 或者拼接

      str.slice

      str.indexOf

      str.replace 正则替换

    5.underscore对象处理:

      underscore 待整理

      if ( 'a' in obj ) 判断对象 (json)obj 中是否有 a,注意 'a' 的 '',同样 obj 可以替换为 arr,但此时只能寻找下标 0,1,2...

    json处理:

      json.stringify() 转成str

      json 转 url string:for in 遍历,push( = ) 存入数组,join('&') 转成 str,补套接字

      json.parse() 将字符串转换成 json

      遍历用 for in 后存入 push 数组

    7.switch(true){case 80<n:document.write('优秀');break;}//当表达式为比较时,参数为布尔值。

    8.Math.floor/Math.ceil/Math.round//要上下兼顾建议floor,使用Math.floor(Math.random()*(max-min+1)+min)

    9.页面所获取的内容都是字符串,eg:typeof getElementById(ID).value

    10.URL-encode处理避免读取错误请求 url:    encodeURLComponent()     

    e.g.     encodeURLComponent("MTAuMTA4LjUyLjM2O2FkbWluO2ExMjM0NTY3OzgwMDA=")   //MTAuMTA4LjUyLjM2O2FkbWluO2ExMjM0NTY3OzgwMDA%3D

    11.<button onclick='func(event)'></button>//event必须通过实际参数形式传递给函数func(e),考虑是否需要全局window

    {alert(e.target.value);}

    12.javascript 是单线程的,但浏览器内部不是单线程的。你的一些 I/O 操作,定时器的计时和事件监听(click,keydown...)等都是由浏览器提供的其他线程来完成的。

    改变 this 指向:将 this 添加到指定环境中,若环境为 null,则指向 window。

      .call(环境,参数1,参数2)

      .apply(环境,[参数1,参数2])

      .bind(环境,参数1,参数2...)

      总结:call和apply都是改变上下文中的this并立即执行这个函数,bind方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加。

      e.g.

    var a = {
        user:"追梦子",
        fn:function(e,d,f){
            console.log(this.user); //追梦子
            console.log(e,d,f); //10 1 2
        }
    }
    var b = a.fn;
    var c = b.bind(a,10); //或者 var d = b.bind(a,10,1,2);  或者 var e = b.bind(a)   
    c(1,2);

    13.动态创建的dom元素

      在此基础上添加监听事件,需要全局方法 <dom onclick='window.fn()' /> 或查询相关资料。

    14.禁止使用 遍历节点添加事件绑定

      解决方法:父级监听事件委托/代理 addEventListener('events', fn, false);

    15.try catch 异步编程中

      try 代码块中避免使用赋值逻辑,并结合类型检查 typeof

      朴灵曾提到:异步编程的难点之一是异常处理,书中描述 "尝试对异步方法进行try/catch操作只能捕获当次事件循环内的异常,对call back执行时抛出的异常将无能为力"。

     16.闭包的属性方法

    var arr = [];
    for(var i = 0; i < 2; i++){
        (arr[i] = function self(){
            console.log(self.x);
        }).x = i;
    };
    arr[1](); // 1

     17.判断变量的类型

    Object.prototype.toString.call(1) //"[object Number]"

     18.apply, call  不过是改变函数上下文

    let obj = {}
    fn(a, b)
    fn.apply(obj, arr)
    // 解析:
    // obj 为加入的对象,该参数表示需要变更的执行大小文,说白了,就是改变原本fn的指向,即this。
    // arr:Array 即传递给fn的参数,['A', 'B'] 对应 fn的arguments
    
    
    fn.call(obj, 'A','B')

    所以当你需要某个函数中的属性和方法,只需要在:目标函数里 { 需要的函数.call(this) } 即可。

    fn.call() // or apply 会使函数立即执行

    bind 与 call 有点类似,不同点在于

    var func1 = fn.bind(obj);
    func1();
    
    // 解析:绑定obj后不会立即执行函数,而是返回一个改变了上下文 this 后的新函数。原函数fn的this依旧为window
    // call 是把第二个及以后的参数作为 func 方法的实参传进去,而 func1 方法的实参实则是在 bind 中参数的基础上再往后排

    自己实现bind

    if (!Function.prototype.bind) {
            Function.prototype.bind = function () {
                var self = this,                        // 保存原函数
                    context = [].shift.call(arguments), // 保存需要绑定的this上下文
                    args = [].slice.call(arguments);    // 剩余的参数转为数组
                return function () {                    // 返回一个新函数
                    self.apply(context,[].concat.call(args, [].slice.call(arguments)));
                }
            }
        }

    apply, call, bind 请参考 https://github.com/lin-xin/blog/issues/7

    apply, call, bind 涉及的闭包与 js 执行上下文相关,遇到 执行 函数 (...实参) ,即创建一个新的执行上下文。同时 js 引擎将该上下文添加到调用堆栈。当调用结束后从调用堆栈中删除。

    19.元素置换[乱起的名]

    let arr = [1, 3, 2];
    let val = arr[0];
    arr[0] = arr [1];
    arr[1] = val
    console.log(arr); // [3, 1, 2]
    
    // 引申快捷操作:
    // 外面数组表示对应位置互相置换
    // 同时改变里面成员的值
    [arr[0], arr[1]] = [arr[1], arr[0]]

     20.深拷贝:完全拷贝一个新对象,修改时原对象不再受到任何影响。 JSON.parse(JSON.stringify(obj))

    21.fs.readFile 读文件结果为buffer,buffer.toString()

    22.让代码继续下去

    try{ 
        // 捕获错误
    }catch(e){
        // 不放内容,直接运行下去
    }
    
    
    // 或者reject catch
    await Promise.reject('出错内容').catch(err => {
       console.log(err) 
    })

     实例:确保每个异步都能正常进行下去

    async function fn() {
      try{
            let f1 = await readFile('data/a.txt')  
            let f2 = await readFile('data/b.txt')  
      }catch(e){}  
      
      console.log(f1.toString())
      console.log(f2.toString())
    }    

     23.类静态属性

    class Test {
        static fn () {}          
    }
    
    Test.fn()

     24.import * as name语法导入所有导出接口,即导入模块整体

     25.text-align: justify; // 文字两端对齐

     26.for of 解决 forEach 无法 return 结束的问题

    for (let [idx, val] of delayList.entries()) {
    }

     27.异步生成数组,同步直接在for循环里处理逻辑即可

    (function next(i, len, callback) {
        if (i < len) {
            async(arr[i], function (value) {
                arr[i] = value
                next(i+1, len, callback)
            })
        } else {
            callback()
        }
    } (0, arr.length, function () {
        // all array items have processed
    }))

     28.同步执行,并根据最终数组进行后续处理

    (function next2(i, len, count, callback) {
        for (; i < len; i++) {
            (function (i) {
                async(arr[i], function (value) {
                    arr[i] = value
                    if (++count === len) {
                        callback()
                    }
                })
            }(i))
        }
    } (0, arr.length, 0 ,function () {}))

     29.事件委托(兼容)

    let oUl = document.querySelector('ul-class')
    oUl.onmouseover = function (e) {
        var e = e || window.event;
        var oLi  = e.srcElement || e.target;
        if (oLi.nodeName.toLowerCase() === 'li') {
            oLi.style.background = 'red';
        }
    }   

     30.async 与 promise.all

    async function A1() {
    let res = await Promise.all([cPromise, cPromise]);   // 简单但灵活性降低了,只有都成功或者都失败两种情况。
    console.log(res)
    }
    
    // 推荐
    async function A2() {
    let res = [];
    let reqs = [cPromise(), cPromise()]; // 注意这里其实已经开始执行异步;
    for (let i=0; i<reqs; i++) {  // 基本没有消耗
       res[i] = await reqs[i]
    }
    console.log(res)
    }

    async 的错误处理

    function createPromise (needCatch:boolean) {
        let p = new Promise((resolve, reject) => {
             reject(10);
        });
        return needCatch ? p.catch(err => err) : p;  // 提前包装捕获错误或者在 async 函数中使用 try.catch
    }

     31.使用 Boolean 构造函数过滤数组中的所有假值

    const compact = arr => arr.filter(Boolean);
    
    compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]);
    
    // [1, 2, 3, 'a', 's', 34]

    32.取整 | 0

    33.判断奇偶 !!(num & 1);  奇数为true, 偶数为 false

    34.强制参数

    mandatory = () => {
        throw new Error('Missing parameter !');
    }
    
    foo = (bar = mandatory()) => {
        return bar;
    }

    35.惰性载入函数,首次判断后覆写原函数,之后结果统一用复写的

    function foo() {
        a !==b ? console.log('aaa') : console.log('bbb')
    }
    
    // 覆写后,当判断分支足够多时,节约的资源还是很客观的
    function newFoo () {
        if (a !== b) {
            foo = () => console.log('aaa')
        } else {
            foo = () => console.log('bbb')
        }
        return foo();  
    }

    36.一次性函数

    var sca = function () {
        console.log('msg')  // 只执行一次,之后重新覆写
        sca = function () {
            console.log('foo')
        }  
    }

    37.字符串比较时间先后:字符串是从左到右比较每个字符的charCode的,注意:时间形式需要补0;

    console.log('2014-08-08' < '2014-09-09'); // true
    console.log('21:00' < '09:10') // false
    // 数字补0
    const addZero = (num, len = 2) => (`0${num}`).slice(-len)

    38.精确到指定位数的小数(四舍五入)

    const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`)
    
    round(1.235, 2) // 1.35
    round(1.345, 1) // 1.3

    39.统计数组中相同项的个数

    var cars = ['BMW', 'Benz', 'Benz', 'Tesla'];
    var carsObj = cars.reduce(function (obj, name) {
       obj[name] = obj[name] ? ++ obj[name] : 1;
       return obj  
    }, {});
    carsObj;

    40.将数组平铺到指定深度

    const flatten = (arr, depth = 1) {
        depth !==1 
        ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flatten(v, depth -1) : v), [])  
        : arr.reduce((a, v) => a.concat(v), [])  
    }
    
    flatten([1, [2], 3, 4]);    // [1, 2, 3, 4]
    flatten([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]

    41.数组的对象解构,可以方便地获取数组的第 n 个值

    const csvFileLine = '1997,John Doe,US,john@doc.com,New York';
    const {2:country, 4:state} = csvFileLine.split(',');
    
    // country      US
    // state          New York

    42.采用解构删除不必要的属性

    let {_internal, tooBig, ...cleanObject} = {el1: '1', _internal: 'secret', tooBig: {}, el2: '2', el3: '3'};
    
    console.log(cleanObject);  // {el1: '1', el2: '2', el3: '3'}

     43.在函数参数中解构嵌套对象

    var car = {
        model: 'bmw 2018',
        engine: {
            v6: true,
            vin: 12345
        }
    }
    const modelAndVin = ({model, engine: {vin}}) => {
        console.log(`model: ${model} vin: ${vin}`)
    }
    modelAndVin(car)

    44.通用表单验证

    const schema = {
        first: {required: true},
        last: {required: true}
    }
    
    const validate = (schema, values) => {
        for (field in schema) {
            if (schema[field].required) {
                if (!values[field]) return false
            }
        }
        return true
    }
    console.log(validate(schema, {firstL 'Bruce'}));  // false
    console.log(validate, {first: 'Bruce', last: 'Wayne'});   // true

     45.两端对齐,数字字母不分割

    .text {
      text-align: justify;
      word-break: normal;
    }

     46.sort((a, b) => a-b) 为什么是升序,可以简单将 a,b 理解为 unicode,b 比 a 大,a - b 为升序

     47.animation 不按预期停止动画,使用 forwards 解决,意为动画到 100 % 就停止,而不恢复到初始

    .fr { animation: name 2s ease-in forwards }

     48. 静态导入导出

    export const a = 1
    export const b = 2
    const c = 3
    export default c
    
    import c, {a, b} from __dirname
    
    import * as cur from __dirname // { a:1, b: 2, default: 3 }

     49.web worker 只能加载网络同源 url 或者字符串 js

    class webWorker {
      /**
       * @description: webworker的简单封装
       * @param {String} data js的url/script的id或class
       * @param {Object} type 默认值给出,同页面的web worker传个’worker‘即可
       * @return: WebWorker 对象
       */
      constructor(data, type = "url") {
        this.worker = null;
        this.workerInit(data, type);
      }
      workerInit(data, type) {
        if (type === "url") {
          // 默认是以url脚本形式的worker线程
          // 此时的data应该是一个url链接
          this.worker = new Worker(data);
        } else {
          // 以字符串形式创建worker线程,把代码字符串,转成二进制对象,生成 URL,加载URL
          const blob = new Blob([data]);
          const url = window.URL.createObjectURL(blob);
          this.worker = new Worker(url); // 加载
        }
      }
      /**
       * @description: 给worker线程发送消息
       * @param {*} data 要发送的数据
       */
      postMessage(data) {
        return this.worker.postMessage(data);
      }
      /**
       * @description: worker线程发送给主进程的数据
       * @param {Function} fn 把数据通过回调的形式传出去
       */
      onmessage(fn) {
        this.worker.onmessage = msg => {
          return fn(msg.data);
        };
      }
      // 主线程关闭worker线程
      closeWorker() {
        return this.worker.terminate();
      }
      /**
       * @description: 主线程监听worker线程的错误信息
       * @param {Function} fn 错误信息回调
       */
      errMsg(fn) {
        this.worker.onerror = e => {
          return fn(e);
        };
      }
    }
    
    const data = `
          // worker线程加载脚本 TODO: Worker 线程无法读取本地文件,加载的脚本必须来自网络
          // importScripts('hello1.js', 'http~.js');
          
          // 监听主线程传过来的信息
          self.onmessage = e => {
            console.log('主线程传来的信息:', e.data);
            // do something
          };
          
          // 发送信息给主线程
          self.postMessage('来自worker线程');
          
          // 关闭worker线程
          function closeSon() {
            return self.close();
          }`;
    
    const worker = new webWorker(data, "script");
    worker.onmessage(data => {
      console.log("父进程接收的数据:", data);
    });
    worker.postMessage("主进程传给worker线程");
    worker.errMsg(msg => {
      console.log("worker线程报错:", msg);
    });
  • 相关阅读:
    image/pjpeg和image/jpeg问题
    windows server 2003 服务器中 HTTP 错误401.1 未经授权:访问由于凭据无效被拒绝
    解决了界面上菜单项跑到其它AE控件后面的问题(java)
    清除地图中的所有图层和FileFilter的使用
    设置pagelayoutControl控件显示滚动条
    pagelayoutControl中添加图元(VB)
    添加和删除字段(vb)
    用代码实现toolbar弹出ButtonMenus(VB)
    pageLayoutControl与Mapcontrol同步(VB)
    C++ Builder XE2随意学习 (1)
  • 原文地址:https://www.cnblogs.com/yuqlblog/p/11179989.html
Copyright © 2011-2022 走看看