CmsWing源码分析(3)全局功能函数(二)

2021SC@SDUSC

 接上一次博客继续分析global.js文件中的全局可用的功能函数

剩余部分内容也不短

目录

获取对象内的所有属性名和方法名

判断对象是否相等

取并集

条件替换

获取行为类型

返回函数的第一个参数

获取文档地址

获取图片


获取对象内的所有属性名和方法名

在此之后,并返回一个数组

global.obj_values = function(obj) {
  const objkey = Object.keys(obj);
  const objarr = [];
  objkey.forEach(key => {
    objarr.push(obj[key]);
  });
  return objarr;
};

其中 keys为js库中自带的函数,效果为返回对象的可枚举字符串属性和方法的名称

(method) ObjectConstructor.keys(o: {}): string[] (+1 overload)
//Returns the names of the enumerable string properties and methods of an object.

将keys中的对象分别写入临时创建的数组 objarr中,最后返回数组objarr

判断对象是否相等

很严谨的自己写了一遍对象是否相等的逻辑....

先是看两者的属性数量是否相等

再看两者都拥有的属性的具体内容是否相等

global.isObjectValueEqual = function(a, b) {
  // Of course, we can do it use for in
  // Create arrays of property names
  var aProps = Object.getOwnPropertyNames(a);
  var bProps = Object.getOwnPropertyNames(b);

  // If number of properties is different,
  // objects are not equivalent
  if (aProps.length != bProps.length) {
    return false;
  }

  for (var i = 0; i < aProps.length; i++) {
    var propName = aProps[i];

    // If values of same property are not equal,
    // objects are not equivalent
    if (a[propName] !== b[propName]) {
      return false;
    }
  }

  // If we made it this far, objects
  // are considered equivalent
  return true;
};

其中,getOwnPropertyNames也是js自带的函数,效果为

返回对象自身属性的名称。 对象自身的属性是直接在该对象上定义的属性,而不是从对象的原型继承的。 对象的属性包括字段(对象)和函数。也就是说,一个父类函数制造的对象有可能和其子类函数对象不相等,但相等也是可能的。

(method) ObjectConstructor.getOwnPropertyNames(o: any): string[]
//Returns the names of the own properties of an object. The own properties of an object are those that are defined directly on that object, and are not inherited from the object's prototype. The properties of an object include both fields (objects) and functions.

取并集

很巧妙...? 

global.array_diff = function(arr1, arr2) {
  // var arr1 = ["i", "b", "c", "d", "e", "f","x",""]; //数组A
  // var arr2 = ["a", "b", "c", "d", "e", "f", "g"];//数组B
  var temp = []; // 临时数组1
  var temparray = [];// 临时数组2
  for (var i = 0; i < arr2.length; i++) {
    temp[arr2[i]] = true;// 巧妙地方:把数组B的值当成临时数组1的键并赋值为真
  }
  for (var i = 0; i < arr1.length; i++) {
    if (!temp[arr1[i]]) {
      temparray.push(arr1[i]);// 巧妙地方:同时把数组A的值当成临时数组1的键并判断是否为真,如果不为真说明没重复,就合并到一个新数组里,这样就可以得到一个全新并无重复的数组
    }
  }; 
}
  return temparray;
};

条件替换

search为条件

replace为要替换的内容

subject为要被替换的内容

global.str_replace = function(search, replace, subject, count) {
  var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0,
    f = [].concat(search),
    r = [].concat(replace),
    s = subject,
    ra = r instanceof Array, sa = s instanceof Array;
  s = [].concat(s);
  if (count) {
    this.window[count] = 0;
  }

然后遍历目标找到可被替换的内容并进行替换

 for (i = 0, sl = s.length; i < sl; i++) {
    if (s[i] === '') {
      continue;
    }
    for (j = 0, fl = f.length; j < fl; j++) {
      temp = s[i] + '';
      repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
      s[i] = (temp).split(f[j]).join(repl);
      if (count && s[i] !== temp) {
        this.window[count] += (temp.length - s[i].length) / f[j].length;
      }
    }
  }
  return sa ? s : s[0];

函数concat将多个数组组合起来

上方的实例中将条件和内容分别与空数组组合起来,形成新的数组

(method) Array<any>.concat(...items: any[]): any[] (+1 overload)
//Combines two or more arrays. This method returns a new array without modifying any existing arrays.

获取行为类型

从这个到之后的函数,几乎都是为用户行为服务的大头戏

参数all表示是否返回全部类型

all为false时返回字符串“系统”或字符串“用户”中的一个

global.get_action_type = function(type, all) {
  all = all || false;
  const list = {
    1: '系统',
    2: '用户'
  };
  if (all) {
    return list;
  }
  return list[type];
};

返回函数的第一个参数

cb为函数名,param应当是一个数组

当params不是数组时,将params作为新数组数组的一个元素,并将这个数组赋值给params(现在是个数组了)

global.call_user_func = function(cb, params) {
  const func = eval(cb);
  if (!think.isArray(params)) {
    params = [params];
  }
  return func.apply(cb, params);
};

eval的作用是评估函数的代码并执行它

function eval(x: string): any
//Evaluates JavaScript code and executes it.

函数apply的作用是返回数组中的值且合成为一个 

apply的使用方法:JavaScript 函数 Apply

获取文档地址

name为文档表示

id为文档ID

有名字的就返回name.html否则返回id.html

global.get_url = (name, id) => {
  if (!think.isEmpty(name)) {
    return `/p/${name}.html`;
  } else {
    return `/p/${id}.html`;
  }
};

获取图片

实际上获得的是图片的地址或者对要求图片进行的处理组成的合成地址

如果id为null,使用默认图片

wh分别为对获取到的图片的进行限定的宽和高

global.get_pic = async(id, m = null, w = null, h = null) => {
  if (think.isEmpty(id)) {
    return '/static/noimg.jpg';
  }

 m根据输入的数字不同会有不同的作用,详细情况见注释:

* /0/w/<LongEdge>/h/<ShortEdge> 	限定缩略图的长边最多为<LongEdge>,短边最多为<ShortEdge>,进行等比缩放,不裁剪。如果只指定 w 参数则表示限定长边(短边自适应),只指定 h 参数则表示限定短边(长边自适应)。
 * /1/w/<Width>/h/<Height> 	限定缩略图的宽最少为<Width>,高最少为<Height>,进行等比缩放,居中裁剪。转后的缩略图通常恰好是 <Width>x<Height> 的大小(有一个边缩放的时候会因为超出矩形框而被裁剪掉多余部分)。如果只指定 w 参数或只指定 h 参数,代表限定为长宽相等的正方图。
 * /2/w/<Width>/h/<Height> 	限定缩略图的宽最多为<Width>,高最多为<Height>,进行等比缩放,不裁剪。如果只指定 w 参数则表示限定宽(长自适应),只指定 h 参数则表示限定长(宽自适应)。它和模式0类似,区别只是限定宽和高,不是限定长边和短边。从应用场景来说,模式0适合移动设备上做缩略图,模式2适合PC上做缩略图。
 * /3/w/<Width>/h/<Height> 	限定缩略图的宽最少为<Width>,高最少为<Height>,进行等比缩放,不裁剪。如果只指定 w 参数或只指定 h 参数,代表长宽限定为同样的值。你可以理解为模式1是模式3的结果再做居中裁剪得到的。
 * /4/w/<LongEdge>/h/<ShortEdge> 	限定缩略图的长边最少为<LongEdge>,短边最少为<ShortEdge>,进行等比缩放,不裁剪。如果只指定 w 参数或只指定 h 参数,表示长边短边限定为同样的值。这个模式很适合在手持设备做图片的全屏查看(把这里的长边短边分别设为手机屏幕的分辨率即可),生成的图片尺寸刚好充满整个屏幕(某一个边可能会超出屏幕)。
 * /5/w/<LongEdge>/h/<ShortEdge> 	限定缩略图的长边最少为<LongEdge>,短边最少为<ShortEdge>,进行等比缩放,居中裁剪。如果只指定 w 参数或只指定 h 参数,表示长边短边限定为同样的值。同上模式4,但超出限定的矩形部分会被裁剪。

然后查找此图片的地址 

const map = {};
  map.status = 1;
  if (think.isNumberString(id)) {
    map.id = id;
  } else {
    map.path = id;
  }
  const picture = await think.model('ext_attachment_pic').where(map).cache(1000 * 1000).find();
  if (think.isEmpty(picture)) {
    return '/static/noimg.jpg';
  }

再根据mhw的数值是否存在分情况讨论

不存在的话直接返回图片的原地址

存在的话,在图片的原地址后添上mhw的参数,并等待之后的函数对此返回值进行进一步利用

if (picture.type > 0) {
    if (m != null) {
      m = '/' + m;
    } else {
      m = '';
    }
    if (w != null) {
      w = '/w/' + w;
    } else {
      w = '';
    }
    if (h != null) {
      h = '/h/' + h;
    } else {
      h = '';
    }
    if (m != '' || w != '' || h != '') {
      q = `?imageView2${m}${w}${h}`;
    }

    return `${get_pdq(picture.type)}/${picture.path}${q}`;
  } else {
    return picture.path;
  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值