整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Web前端JavaScript面向对象闭包实现封装小

Web前端JavaScript面向对象闭包实现封装小实例

络图片

闭包,是几乎所有前端工程师必须要掌握的一个技术,这里简单说一下闭包的概念,闭包就是指在函数中调用函数以外作用域的行为。常见的闭包就是在函数内部再定义一个函数时,触发内部函数,使用外部函数的行为。

之前的对象创建分为原生部分和原型部分,基于闭包方式,可以把私有的基本类型打包起来,基于函数返回值方式建立引用。

但是原型部分的定义,感觉和闭包定义本身没有什么联系,所有再重新定义一个闭包。尝试把原型的定义也打包起来。

以下案例主要是理解关于JavaScript中封装思想,以及如何使用闭包技术来封装对象。

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title></title>

</head>

<body>

<!--

果果爸爸青少年编程

2019-8-2

-->

<script type="text/javascript">

var Product=(function(){

var num=10;

function _product(id,name,costPrice){

// 公有属性

this.name=name;//产品名称

// 公有方法

this.show=function(){

console.log("2019新品:"+this.name+",价格公道,只要:"+calculatorSalePrice());

}

// 私有方法

function calculatorSalePrice(){

return costPrice*4.5; // 一般手机利润是400%左右

}

// 私有属性

var _id=id;//产品编号

var _costPrice=costPrice;//产品成本价

// 特权方法(getter&setter)

this.setId=function(id){

_id=id;

}

this.getId=function(){

return _id;

}

this.setCostPrice=function(costPrice){

_costPrice=costPrice;

}

// 构造器

//this.setName(name);

this.setCostPrice(costPrice);

}

// 类原型公有定义

_product.prototype={

// 公有属性

isCellphone: true,

// 公有方法

toString : function(){

console.log("果果爸爸青少年编程推荐,"+this.name+"好")

}

}

// 返回上面所有定义

return _product;

})();

var huawei=new Product("1","华为p30",1500);

console.log("产品名称:"+huawei.name)

huawei.show()

console.log(huawei.isCellphone);

huawei.toString();

</script>

</body>

</html>

执行效果如下:

程序执行效果

天给大家分享几个好的功能封装,在你的项目开发中,一定会用的到,肯定实用。这样写,能提高的编码能力,编写出高效且可维护的JavaScript代码。

功能一,动态加载JS文件

有过一定项目开发经验的同学一定知道,在实际项目开发过程中,会经常碰到需要动态加载一些JS的时候,比如依赖的第三方SDK。那如何封装一个可以动态加载JS的功能函数呢?代码如下

此代码两个核心点:

1. 使用Promise处理异步

2. 使用脚本标签加载和执行JS

// 封装
function loadJS(files, done) {
  const head=document.getElementsByTagName('head')[0];
  Promise.all(files.map(file=> {
    return new Promise(resolve=> {
      const s=document.createElement('script');
      s.type="text/javascript";
      s.async=true;
      s.src=file;
      s.addEventListener('load', (e)=> resolve(), false);
      head.appendChild(s);
    });
  })).then(done);
}

// 使用
loadJS(["test1.js", "test2.js"], ()=> {

});

功能二,递归检索对象属性

当一个对象的属性也是一个对象的时候,如何遍历出这个对象上的所有属性,包括子属性对象上的对象。

使用递归循环遍历

function getAllObjectProperties(obj) {
  for (const prop in obj) {
    if (typeof obj[prop]==="object") {
      getAllObjectProperties(obj[prop]);
    } else {
      console.log(prop, obj[prop]);
    }
  }
}

const sampleObject={
  name: "John",
  age: 30,
  address: {
    city: "Example City",
    country: "Example Country"
  }
};

getAllObjectProperties(sampleObject);

功能三,柯里化(Currying)

将一个采用多个参数的函数转换为一系列函数,每个函数只采用一个参数,这增强了函数使用的灵活性,最大限度地减少了代码冗余,并提高了代码的可读性。

function curryAdd(x) {
  return function (y) {
    return function (z) {
      return x + y + z;
    };
  };
}

const result=curryAdd(1)(2)(3);

功能四,函数仅执行一次

在某些情况下,特定函数只允许执行一次。这种情况还是挺多的。

once函数包装了另一个函数,确保它只能执行一次

// 封装
function once(fn) {
  let executed=false;
  return function (...args) {
    if (!executed) {
      executed=true;
      return fn.apply(this, args);
    }
  };
}

// 执行
const runOnce=once(()=> {

});

runOnce();
runOnce();

功能五,添加默认值

如果用户省略参数,则分配一个预定的默认值。

function greetUser(name="Guest") {
  console.log(`Hello, ${name}!`);
}
greetUser(); // 输出: Hello, Guest!
greetUser("John"); // 输出:Hello, John!

功能六,利用Reduce进行数据结构转换

下面这个实例,我需要将数据按指定字段分类出来,只需要将使用reduce封装一个可执行的函数就行。

在之前的一篇文章《如何打造属于自己的Javascript武器库,来封装这些经典的方法吧》中,有封装过一些简单的方法。

今天这篇文章我们继续看看关于字符串处理的常用方法,并将其封装,完善自己的Javascript武器库。

文中的代码我已经放到Github上了,有需要的同学可以自取。

https://github.com/zhouxiongking/article-pages/blob/master/articles/jsCapsulation/capsulation2.js

Javascript

去除空格的方法

该方法的主要目的是通过传递不同的参数,选择去除哪里的空格。

  • all - 代表所有空格

  • preBehind - 前后空格

  • previous - 前面空格

  • behind - 后面空格

主要思想是:通过正则表达式\s匹配空白字符,然后用''去替换空白字符。

得到的代码如下所示。

去除空格方法

字母大小写切换

该方法的主要目的是:将字符串的首字母或者全部字母,进行大小写转换。根据传入的参数进行处理。

  • FirstUpper - 首字母大写

  • FirstLower - 首字母小写

  • AllToggle - 全部大小写相互转换

  • AllUpper - 全部大写

  • AllLower - 全部小写

主要思想是:根据传入的参数,配合使用字符串自身的toUpperCase和toLowerCase方法。

得到的代码如下所示。

字母大小写转换

其中的ToggleCase方法用于大小写相互转换,其如下所示。

大小写相互转换

检测字符串类型

该方法主要用于检测输入的字符串是否是我们想要的类型,例如email代表邮箱,phone代表手机号,number代表数字,chinese代表中文。

主要思想是:获得想要获取类型的正则表达式,然后返回匹配的结果。

得到的代码如下所示。

检测字符串类型

上述的检测方案完全可以按照需求进行扩充,直接通过case,就可以自行添加。

检测密码强度

该方法主要用于模仿检测设置密码的强度,检测规则如下:

  • 如果密码长度小于6,则强度为0。

  • 如果密码包含数字,则强度加1。

  • 如果密码包含小写字母,则强度加1。

  • 如果密码包含大写字母,则强度加1。

  • 如果包含特殊字符,则强度加1。

上述规则会累加统计,最高强度为4。

得到的代码如下所示。

检测密码强度

随机生成指定长度字符串

该方法主要用于随机生成指定长度的字符串,例如随机验证码我们完全可以通过这个方法去实现。

主要思想是:先通过Math.random()方法生成随机数,然后调用toString(36)方法转化为字符串,再截取掉前面的0和小数点,循环计算直到达到指定长度。

该方法的核心在于toString()方法的使用,Number类型的toString方法已经重写,传入的参数表示转化的进制数,传入的范围是2-36,最小的2表示0-1,最大的36数字0-9和小写字母a-z,如上面的toString(36),表示要用36进制数表示。

根据以上分析,得到的代码如下所示。

随机生成指定长度字符串

统计给定字符串中,目标字符串出现的次数

该方法通过字符串的split方法实现特别简单。通过split方法按照目标字符串分割成数组,目标字符串出现的次数就是数组的长度减去1。

根据以上分析,得到的代码如下所示。

统计指定字符串出现次数

格式化处理字符串

该方法主要用于将字符串通过传入的参数格式化处理,接收的参数如下所示。

  • size - 表示分割的位数,默认为3。

  • delimiter - 处理后字符串的连接符,默认为','

该方法的思想是通过正则表达式,动态获取每次需要捕获的位数,然后将其捕获的位置前后替换为连接符。

得到的代码如下。

格式化字符串处理

结束语

今天这篇文章主要补充了Javascript中与字符串有关的方法的封装,其他需要封装的方法还有很多,大家也可以自行总结。