js原型链+继承 浅析

名称:    prototype--原型对象    __proto__--属性

原型链与继承网上搜索定义,看起来挺绕的 。先说继承: 所有的对象实例都可以共享原型对象包含的属性和方法  例如一个实例A被XX所创建那么这个实例A就会继承XX.prototype 。继承到哪里了那?继承到A.__proto__  属性里面了 。

js原型链+继承 浅析

这是一个最简单的原型链继承。然后我想b为什么没有prototype.然后有***找了一番理解一番得出:

每个对象都有 __proto__属性(并且指向该对象的构造函数的prototype)prototype是一个对象所以所有的prototype都有__proto__属性, 对象才有prototype属性(但不是所有的对象都有prototype);每个函数对象都有prototype。

有够绕。。。 总结一下  prototype原型对象      这个属性只有函数对象才有,并且prototype原型对象是个对象,所以他有__proto__这个属性。然后是所有对象的__proto__的值都是 自己所继承的原型对象(就像上图 a继承了b的原型对象prototype)。

然而不可能无限这样继承下去 继承的顶端是Object.prototype  (这里面就包含了js自己封装的一些方法,其实挺常用的一些方法)比如数组 的排序,删除增加什么的。都是从顶端继承来的。(不然还是从石头缝里蹦出来的。。。)

以上是定义。然后b为什么没有prototype   是因为 b是 构造函数a 所创建出来的一个实例对象。不是函数对象。所以没有prototype;  (我试了 数组,字符串,时间等常用的都没有此属性)(所以现在不是很明白除了函数对象还有什么有prototype)。

然后就是原型链:a.__proto__=b.prototype=c.prototype=...=Object.prototype(原型链的终点)。

当我们取a中的一个属性或者方法的时候。JS会先在a自己的里面找找不到再去继承的b.prototype里面找,找不到再去c.prototype,然后直到找到为止,或者找到尽头没找到返回undefined;

所以原型链的优点我们项目开始的一些方法封装尽量都封装在原型对象里面.

以下是常用方法

例如 简单的 字符串中的替换 replace()方法只是匹配并替换匹配到的第一个,我们自定义一个replaceAll;

String.prototype.replaceAll= function(s1,s2){
  return this.replace(new RegExp(s1,"gm"),s2);
}

关于数组去重 :

对于比较简单的数组去重使用indexOf判断就很方便,但是对于对象数组根据某个Key去重就比较麻烦。所以综合就是

Array.prototype.unique = function(key) {
  var arr = this;
  var n = [arr[0]];
  for (var i = 1; i < arr.length; i++) {
    if (key === undefined) {
    if (n.indexOf(arr[i]) == -1) n.push(arr[i]);
} else {
inner: {
  var has = false;
  for (var j = 0; j < n.length; j++) {
    if (arr[i][key] == n[j][key]) {
        has = true;
        break inner;
      }
    }
  }
      if (!has) {
        n.push(arr[i]);
      }
    }
  }
  return n;
}

这个去重只针对普通的及去重对象的KEY是当前的对象的第一级的key。

调用方法: [{a:1,b:2},{a:3,b:2},{a:1,b:2},{a:1,b:2}].unique();

时间:js Date()方法所得到的结果是ue May 08 2018 16:12:58 GMT+0800 (中国标准时间)     而不是我们日常见到的 20187/5/8等 。

Date.prototype.Format = function(formatStr)
{
var str = formatStr;
var Week = ['日','一','二','三','四','五','六'];
var month=this.getMonth()+1;
str=str.replace(/yyyy|YYYY/,this.getFullYear());
str=str.replace(/yy|YY/,(this.getYear() % 100)>9?(this.getYear() % 100).toString():'0' + (this.getYear() % 100));
str=str.replace(/MM/,month>9?month.toString():'0' + month);
str=str.replace(/M/g,month);
str=str.replace(/w|W/g,Week[this.getDay()]);
str=str.replace(/dd|DD/,this.getDate()>9?this.getDate().toString():'0' + this.getDate());
str=str.replace(/d|D/g,this.getDate());
str=str.replace(/hh|HH/,this.getHours()>9?this.getHours().toString():'0' + this.getHours());
str=str.replace(/h|H/g,this.getHours());
str=str.replace(/mm/,this.getMinutes()>9?this.getMinutes().toString():'0' + this.getMinutes());
str=str.replace(/m/g,this.getMinutes());
str=str.replace(/ss|SS/,this.getSeconds()>9?this.getSeconds().toString():'0' + this.getSeconds());
str=str.replace(/s|S/g,this.getSeconds());
return str;
}
可以根据自己的需求改 replace 所对应的字符串
调用方法   new Date().Format('yyyy-MM-dd')
new Date().Format('YYYY/MM/dd')
怎样拼接都是自己定义的。
 
JS计算精度问题(这个问题涉及的是很基础的繁杂的知识。搜索学习吧。比较多 ,抽时间会做一个整理)
 
 相信大家在前端做计算的时候都会遇到浮点数字计算不准确。一开始我也是吐槽js然后搜索后才发现是自己的无知。
首先追溯到大学学的知识。计算机都是二进制运算的。所有的程序 在计算机最终执行都是二进制。  
有些浮点数转换二进制是无限小数的。这样超出的超出被截断了。最后计算机把二进制
计算的结果转换成十进制或者几进制的时候肯定会有误差。所以这个现象应该是只要不是二进制计算。其他的计算都会有这种结果。不分语言。
 所以我们的加减乘除在实际运用中对于浮点的不友好只能手动解决了(把浮点部分单拿出来做计算)。
 
加法
Number.prototype.add =function(arg1, arg2) {

var r1, r2, m, c;
try {
r1 = arg1.toString().split(".")[1].length;
}
catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
}
catch (e) {
r2 = 0;
}
c = Math.abs(r1 - r2);
m = Math.pow(10, Math.max(r1, r2));
if (c > 0) {
var cm = Math.pow(10, c);
if (r1 > r2) {
arg1 = Number(arg1.toString().replace(".", ""));
arg2 = Number(arg2.toString().replace(".", "")) * cm;
} else {
arg1 = Number(arg1.toString().replace(".", "")) * cm;
arg2 = Number(arg2.toString().replace(".", ""));
}
} else {
arg1 = Number(arg1.toString().replace(".", ""));
arg2 = Number(arg2.toString().replace(".", ""));
}
return (arg1 + arg2) / m;
}

 减法
Number.prototype.sub=function(arg1, arg2) {

var r1, r2, m, n;
try {
r1 = arg1.toString().split(".")[1].length;
}
catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
}
catch (e) {
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //动态控制精度长度
n = (r1 >= r2) ? r1 : r2;
return ((arg1 * m - arg2 * m) / m).toFixed(n);
}

乘法

Number.prototype.mul=

function accMul(arg1, arg2) {

var m = 0, s1 = arg1.toString(), s2 = arg2.toString();

try {

m += s1.split(".")[1].length;

}

catch (e) {

}

try {

m += s2.split(".")[1].length;

}

catch (e) {

}

return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);

}

除法

Number.prototype.division=function(arg1, arg2) {

var t1 = 0, t2 = 0, r1, r2;

try {

t1 = arg1.toString().split(".")[1].length;

}

catch (e) {

}

try {

t2 = arg2.toString().split(".")[1].length;

}

catch (e) {

}

with (Math) {

r1 = Number(arg1.toString().replace(".", ""));

r2 = Number(arg2.toString().replace(".", ""));

return (r1 / r2) * pow(10, t2 - t1);

}

}

上一篇:js原型链、继承、this指向等老生常谈却依然不熟的知识点——记录解析


下一篇:iOS- UITextView与键盘回收与键盘遮挡输入框