0427

27
四月
2021

一、重载与Proxy表单验证

1.1、重写与重载的区别

重写:
	重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
重载:
	重载是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
//===重写==========================
	  class Parent {
        a() {}
      }
      class Child extends Parent {
        // 重写
        a() {
          console.log(111);
        }
      }
//===重载1===========================
	  function Person() {}
      Person.prototype.say = function (...args) {
        if (args.length > 3) throw new Error('参数过多,最多3个');
        this[`m${args.length - 1}`]();
      };
      Person.prototype.m0 = function () {
        console.log('m0');
      };
      Person.prototype.m1 = function () {
        console.log('m1');
      };
      Person.prototype.m2 = function () {
        console.log('m2');
      };

      const p = new Person();
      p.say(1, 2, 3);
//===重载2===========================================
	   class Person {
        say(...args) {
          if (args.length > 3) throw new Error('参数过多,最多3个');
          this[`m${args.length}`](...args);
        }
        m0() {}
        m1(...args) {
          console.log('传1个参数时:' + args);
        }
        m2(...args) {
          console.log('传2个参数时:' + args);
        }
        m3(...args) {
          console.log('传3个参数时:' + args);
        }
      }
      const p = new Person();
      p.say(1000, 100);

1.2、表单验证

1、不用代理的表单验证

//===css=========================================================
<style>
      .error {
        border: 1px solid red;
        color: red;
      }
</style>
//===html==========================================================
 <input type="text" validate rule='{"max":3,"required":true}' />
//===js============================================================
	  class Validator {
        static max(value, len = 5) {
          return value.length < len;
        }
        static required(value, require = false) {
          if (!require) return true;
          return value == '' ? false : true;
        }
      }

      document.querySelectorAll('input[type="text"]').forEach((el, index) => {
        el.addEventListener('keyup', function (ev) {
          //console.log(ev.target.value)
          let value = this.value;
          // 把规则转为json对象
          let rule = eval('(' + this.getAttribute('rule') + ')');
          // 判断输入的值是否符合规则条件
          // let state = Object.getOwnPropertyNames(rule)
          let state = Object.keys(rule).every((methodName) => {
            return Validator[methodName](value, rule[methodName]);
          });
          /* if (!state) {
          this.classList.add('error')
        } else {
          this.classList.remove('error')
        } */
          this.classList[!state ? 'add' : 'remove']('error');
        });
      });

2、用代理的 表单验证–proxy

//===css=========================================================
<style>
      .error {
        border: 1px solid red;
        color: red;
      }
</style>
//===html========================================================
<input type="text" validate rule='{"max":3,"required":true}' />
//===js==========================================================
	  class Validator {
        static max(value, len = 5) {
          return value.length < len;
        }
        static required(value, require = false) {
          if (!require) return true;
          return value == '' ? false : true;
        }
      }

      let inputProxy = new Proxy(
        document.querySelectorAll('input[type="text"]'),
        {
          get(target, key) {
            return Reflect.get(target, key);
          },
          set(target, key, dom) {
            // 把规则转为json对象
            let rule = eval('(' + dom.getAttribute('rule') + ')');
            // 判断输入的值是否符合规则条件
            let state = Object.keys(rule).every((methodName) => {
              return Validator[methodName](dom.value, rule[methodName]);
            });
            dom.classList[!state ? 'add' : 'remove']('error');
            return true;
          },
        }
      );

      inputProxy.forEach((el, index) => {
        el.addEventListener('keyup', function () {
          inputProxy[index] = this;
        });
      });

2、用代理(封装性更好)的 表单验证–proxy

//===css=========================================================
<style>
      .error {
        border: 1px solid red;
        color: red;
      }
</style>
//===html========================================================
<input type="text" validate rule='{"max":3,"required":true}' />
//===js===========================================================
	  let inputProxy = (function (NodeListDom) {
        class Validator {
          static max(value, len = 5) {
            return value.length < len;
          }
          static required(value, require = false) {
            if (!require) return true;
            return value == '' ? false : true;
          }
        }

        let inputProxy = new Proxy(NodeListDom, {
          get(target, key) {
            return Reflect.get(target, key);
          },
          set(target, key, dom) {
            // 把规则转为json对象
            let rule = eval('(' + dom.getAttribute('rule') + ')');
            // 判断输入的值是否符合规则条件
            let state = Object.keys(rule).every((methodName) => {
              return Validator[methodName](dom.value, rule[methodName]);
            });
            dom.classList[!state ? 'add' : 'remove']('error');
            return true;
          },
        });
        return inputProxy;
      })(document.querySelectorAll('input[type="text"]'));

      inputProxy.forEach((el, index) => {
        el.addEventListener('keyup', function () {
          inputProxy[index] = this;
        });
      });

二、模块化

随着前端js代码复杂度的提高,JavaScript模块化这个概念便被提出来,前端社区也不断地实现前端模块化,直到es6对其进行了规范。

前端模块化方案:AMD[requirejs],CMD[seajs],CommonJS[nodejs]和ES6

AMD和CMD,
		AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。
	    CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
	    
		AMD:提前执行(异步加载:依赖先执行)+延迟执行
		CMD:延迟执行(运行到需加载,根据顺序执行)			
	    
		CMD 推崇依赖就近,AMD 推崇依赖前置

2.1、AMD

AMD是RequireJS在推广过程中对模块定义的规范化产出。AMD规范则是非同步加载模块,允许指定回调函数。

//===定义模块,没有依赖项========================
define(function () {
  function fn1() {
    return '你好fn1'
  }
  // 导出模块
  return { fn1 };
})

//===定义模块有这依赖项==========================
define(['m1'], function (m1) {
  function fn2() {
    console.log('m2模块', m1.fn1());
  };
  // 暴露模块
  return { fn2 };
})

//===入口文件===================================
(function () {
  requirejs.config({
    // 配置js路径
    paths: {
      m1: './module/m1',
      m2: './module/m2',
      jquery: './module/jquery'
    }
  });

  requirejs(['m2', ' jquery'], function (m2) {
    m2.fn2();
    $('#box').click(function(){
      console.log(1111);
    })
  })
})()

//===页面文件==================================
<div id="box">点击试一下</div>
<script data-main="./main.js" src="./lib/require.js"></script>

2.2、CMD

CMD是SeaJS在推广过程中对模块定义的规范化产出。

//===没有依赖的模块=============================
define(function (require, exports, module) {
  function fn1() {
    console.log("m1模块下面的fn1方法");
  };
  // 导出模块
  module.exports = {
    fn1
  }
})

//===有依赖的模块=================================
define(function (require, exports, module) {
  // 导入依赖模块
  let m1 = require('./m1')
  m1.fn1()
  function fn2() {
    console.log('我是m2模块下面的fn2方法');
  }
  exports.fn2 = fn2
});

//===主入口文件=====================================
define(function (require) {
  let m2 = require('./m2')
  m2.fn2()
  let jquery = require('./jquery')

  console.log(jquery('body'));
})

//===页面============================================
<script src="./lib/sea.js"></script>
<script>
  seajs.use('./module/main.js')
</script>

2.3、CommonJS

// 导出
module.exports = 对象

// 导入
const 变量 = require(路径)

2.4、ES6模块化

在ES6中,我们可以使用 import 关键字引入模块,通过 exprot 关键字导出模块,功能较之于前几个方案更为强大,也是我们所推崇的,但是由于ES6模块化目前还无法在所有的浏览器中支持,所以在浏览器中使用需要进行编译处理。目前chrome是支持的。

export [default] 对象

import * as obj form ‘路径’
import xxx form ‘路径’
import {xx as 别名} from ‘路径’

三、ts

3.1、ts的基本类型

3.1.1、布尔值

let a:boolean;
a = true;
console.log(a);

3.1.2、数字

let decLiteral: number = 6;           // 十进制
let hexLiteral: number = 0xf00d;     // 十六进制
let binaryLiteral: number = 0b1010;  // 二进制
let octalLiteral: number = 0o744;    // 八进制

3.1.3、字符串

let name: string = "bob"
let username:string = `aaabbbccc`

3.1.4、any和unknown

let app:any = 66
let app:unknown = 66

3.1.5、void

它表示没有任何类型, 声明一个void类型的变量没有什么大用,因为你只能为它赋予undefined和null,一般多用于函数返回值指定

let unusable: void = undefined;
function warnUser(): void {
    console.log("This is my warning message");
};

3.1.6、null和undefined

undefined和null两者各自有自己的类型分别叫做undefined和null。 和 void相似,它们的本身的类型用处不是很大

let u: undefined = undefined;
let n: null = null;

3.1.7、never

never类型表示的是那些永不存在的值的类型

function error(message: string): never {
  throw new Error(message);
};

3.1.8、字面量

可以使用字面量去指定变量的类型,通过字面量可以确定变量的取值范围

// 声明
let name2: 1 | 2 | '先生' | '女士' | true;
// 赋值 值只能在字面量中,选一个
name2 = true;

3.1.9、枚举(enum)

使用枚举类型可以为一组数值赋予友好的名字

enum Color {
  Red,
  Green,
  Blue,
}enum Color {
  Red = 1,
  Green = 2,
  Blue = 3,
}
let c: Color = Color.Green;

3.1.10、object

let obj: object = {}
let obj:{id:number,name?:string}  // ?可选
// id是必须要有的,后面可以任意key,key为字符串,值为任意类型
let obj:{id:number,[props:string]:any}
// 给函数参数定义类型和返回值定义类型
type fnType = (a:number,b:number)=>number
const fn:fnType = (a:number,b:number):number=>a+b
TAG

网友评论

共有访客发表了评论
请登录后再发布评论,和谐社会,请文明发言,谢谢合作! 立即登录 注册会员