云顶集团400800044

当前位置:云顶集团400800044 > 云顶集团400800044 > 深远了然Javascript面向对象编制程序,实现数据压

深远了然Javascript面向对象编制程序,实现数据压

来源:http://www.ofertasanjuan.com 作者:云顶集团400800044 时间:2019-10-27 02:43

使用 canvas 达成数据压缩

2016/03/15 · HTML5 · 1 评论 · Canvas

初藳出处: EtherDream   

使用 SVG 输出 Octicon

2016/03/18 · HTML5 · SVG

原版的书文出处: aaronshekey   译文出处:[百度EFE

  • Justineo]()   

GitHub.com 今后不再选择字体来输出Logo了。大家把代码库中颇负的 Octicon 替换到了 SVG 版本。就算这几个退换并不那么明显,但您马上就能够体味到 SVG Logo的亮点。

图片 1

Octicon 上的比较

切换成 SVG 今后,Logo会作为图片渲染而非文字,那使其在别的分辨率下都能很好地在各类像素值下显得。能够相比较一下左方放大后的书体版本和左臂清晰的 SVG 版本。

JSONProxy – 获取跨域json数据工具

2015/07/10 · JavaScript · JSON, JSONProxy

深远了然Javascript面向对象编制程序,实现数据压缩。原稿出处: 韩子迟   

JSONProxy是风流倜傥款很好的得到json多少的代理网址,“Enables cross-domain requests to any JSON API”。当你苦于不也许跨域获取json数据时,不妨少年老成试,说不定能渔人之利。

举个例子说那位朋友,想透过ajax获取必应的每日意气风发图的url(是或不是能够透过ajax获取“Bing天天风流罗曼蒂克图”?)很显著,那么些ajax是跨域的,直接拿走会因为跨域报错;服务端也迟早不会有对你本地localhost的“Access-Control-Allow-Origin”的装置,所以CO奇骏S战略也是非常的;因为是个json数据,未有章程名包裹,所以jsonp也是万分。楼主目前还没有接触过其它的跨域方法,假设要小编去取得url,只好通过服务端的代码,服务端去赢得json数据,然后index页面去ajax央求服务端获取的json数据(那时候index页面和服务端同源),代码量增添,而要做的仅仅只是获取叁个json数据啊!那个时候JSONProxy就帮您做好了服务端的行事,是还是不是很爽!

Web Components 是个什么的东西

2016/09/04 · HTML5, JavaScript · Web Components

原稿出处: teabyii   

前者组件化这么些宗旨相关的剧情已经火了相当久非常久,angular 刚出去时的 Directive 到 angular2 的 components,还有 React 的components 等等,无一不是前端组件化的风流洒脱种完结和搜求,不过提上议程的 Web Components 标准是个如何的事物,相关的后生可畏对框架大概类库,如 React,Angular2,以至是 x-tag,polymer 现在落到实处的组件化的事物和 Web Components 标准差异在什么地方?小编花时间努力地把现存的 W3C Web Components 文书档案看了下,然后坚强地写下这一个记录。

率先我们须求通晓,Web Components 包蕴了多个部分:

  • Custom Elements
  • HTML Imports
  • HTML Templates
  • Shadow DOM

那四部分有机地结合在联合,才是 Web Components。

能够用自定义的竹签来引进组件是前面八个组件化的根底,在页面引用 HTML 文件和 HTML 模板是用来辅助理编辑写组件视图和零部件财富管理,而 Shadow DOM 则是割裂组件间代码的冲突和潜移暗化。

上面分别是每大器晚成局地的笔记内容。

深远通晓Javascript面向对象编制程序

2015/12/23 · JavaScript · 1 评论 · 面向对象

原稿出处: 涂根华   

风度翩翩:通晓构造函数原型(prototype)机制

prototype是javascript完结与处理持续的风华正茂种体制,也是面向对象的统筹观念.构造函数的原型存储着援引对象的四个指针,该指针指向与一个原型对象,对象内部存款和储蓄着函数的原始属性和艺术;我们能够依赖prototype属性,能够访谈原型内部的本性和格局。

当构造函数被实列化后,全部的实例对象都得以访问构造函数的原型成员,借使在原型中注脚一(Beingmate)(Dumex)个成员,全体的实列方法都得以共享它,举举个例子下代码:

JavaScript

// 构造函数A 它的原型有八个getName方法 function A(name){ this.name = name; } A.prototype.getName = function(){ return this.name; } // 实列化2次后 该2个实列皆有原型getName方法;如下代码 var instance1 = new A("longen1"); var instance2 = new A("longen2"); console.log(instance1.getName()); //longen1 console.log(instance2.getName()); // longen2

1
2
3
4
5
6
7
8
9
10
11
12
// 构造函数A 它的原型有一个getName方法
function A(name){
    this.name = name;
}
A.prototype.getName = function(){
    return this.name;
}
// 实列化2次后 该2个实列都有原型getName方法;如下代码
var instance1 = new A("longen1");
var instance2 = new A("longen2");
console.log(instance1.getName()); //longen1
console.log(instance2.getName()); // longen2

原型具有普通对象协会,可以将别的日常对象设置为原型对象; 平日景色下,对象都持续与Object,也足以掌握Object是怀有目的的超类,Object是不曾原型的,而构造函数具有原型,由此实列化的靶子也是Object的实列,如下代码:

JavaScript

// 实列化对象是构造函数的实列 console.log(instance1 instanceof A); //true console.log(instance2 instanceof A); // true // 实列化对象也是Object的实列 console.log(instance1 instanceof Object); //true console.log(instance2 instanceof Object); //true //Object 对象是具备目的的超类,由此构造函数也是Object的实列 console.log(A instanceof Object); // true // 不过实列化对象 不是Function对象的实列 如下代码 console.log(instance1 instanceof Function); // false console.log(instance2 instanceof Function); // false // 但是Object与Function有关联 如下代码表明 console.log(Function instanceof Object); // true console.log(Object instanceof Function); // true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 实列化对象是构造函数的实列
console.log(instance1 instanceof A); //true
console.log(instance2 instanceof A); // true
 
// 实列化对象也是Object的实列
console.log(instance1 instanceof Object); //true
console.log(instance2 instanceof Object); //true
 
//Object 对象是所有对象的超类,因此构造函数也是Object的实列
console.log(A instanceof Object); // true
 
// 但是实列化对象 不是Function对象的实列 如下代码
console.log(instance1 instanceof Function); // false
console.log(instance2 instanceof Function); // false
 
// 但是Object与Function有关系 如下代码说明
console.log(Function instanceof Object);  // true
console.log(Object instanceof Function);  // true

如上代码,Function是Object的实列,也足以是Object也是Function的实列;他们是2个分化的构造器,我们继承看如下代码:

JavaScript

var f = new Function(); var o = new Object(); console.log("------------"); console.log(f instanceof Function); //true console.log(o instanceof Function); // false console.log(f instanceof Object); // true console.log(o instanceof Object); // true

1
2
3
4
5
6
7
var f = new Function();
var o = new Object();
console.log("------------");
console.log(f instanceof Function);  //true
console.log(o instanceof Function);  // false
console.log(f instanceof Object);    // true
console.log(o instanceof Object);   // true

咱俩掌握,在原型上加码成员属性只怕措施的话,它被抱有的实列化对象所分享属性和方法,不过大器晚成旦实列化对象有和原型相像的分子成员名字的话,那么它取到的积极分子是本实列化对象,假若本实列对象中从不的话,那么它会到原型中去寻找该成员,假如原型找到就赶回,不然的会重返undefined,如下代码测量试验

JavaScript

function B(){ this.name = "longen2"; } B.prototype.name = "AA"; B.prototype.getName = function(){ return this.name; }; var b1 = new B(); // 在本实列查找,找到就回到,不然到原型查找 console.log(b1.name); // longen2 // 在本实列未有找到该方法,就到原型去摸索console.log(b1.getName());//longen2 // 倘若在本实列未有找到的话,到原型上查找也从不找到的话,就重返undefined console.log(b1.a); // undefined // 今后自身利用delete运算符删除本地实列属性,那么取到的是便是原型属性了,如下代码: delete b1.name; console.log(b1.name); // AA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function B(){
    this.name = "longen2";
}
B.prototype.name = "AA";
B.prototype.getName = function(){
    return this.name;
};
 
var b1 = new B();
// 在本实列查找,找到就返回,否则到原型查找
console.log(b1.name); // longen2
 
// 在本实列没有找到该方法,就到原型去查找
console.log(b1.getName());//longen2
 
// 如果在本实列没有找到的话,到原型上查找也没有找到的话,就返回undefined
console.log(b1.a); // undefined
 
// 现在我使用delete运算符删除本地实列属性,那么取到的是就是原型属性了,如下代码:
delete b1.name;
console.log(b1.name); // AA

二:明白原型域链的定义

原型的优点是能够以目的组织为载体,成立大气的实列,这个实列能分享原型中的成员(属性和艺术);同不经常候也足以行使原型达成面向对象中的承继机制~ 如下代码:上边大家来看那么些布局函数AA和布局函数BB,当BB.prototype = new AA(11);实践这些的时候,那么B就连续与A,B中的原型就有x的属性值为11

JavaScript

function AA(x){ this.x = x; } function BB(x) { this.x = x; } BB.prototype = new AA(11); console.log(BB.prototype.x); //11 // 大家再来精晓原型承接和原型链的定义,代码如下,都有注释 function A(x) { this.x = x; } // 在A的原型上定义两性情质x = 0 A.prototype.x = 0; function B(x) { this.x = x; } B.prototype = new A(1);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function AA(x){
    this.x = x;
}
function BB(x) {
    this.x = x;
}
BB.prototype = new AA(11);
console.log(BB.prototype.x); //11
 
// 我们再来理解原型继承和原型链的概念,代码如下,都有注释
function A(x) {
    this.x = x;
}
// 在A的原型上定义一个属性x = 0
A.prototype.x = 0;
function B(x) {
    this.x = x;
}
B.prototype = new A(1);

实列化A new A(1)的时候 在A函数内this.x =1, B.prototype = new A(1);B.prototype 是A的实列 也便是B承袭于A, 即B.prototype.x = 1;  如下代码:

JavaScript

console.log(B.prototype.x); // 1 // 定义C的构造函数 function C(x) { this.x = x; } C.prototype = new B(2);

1
2
3
4
5
6
console.log(B.prototype.x); // 1
// 定义C的构造函数
function C(x) {
    this.x = x;
}
C.prototype = new B(2);

C.prototype = new B(2); 相当于C.prototype 是B的实列,C承袭于B;那么new B(2)的时候 在B的构造函数内 this.x = 2;那么 C的原型上会有壹天品质x =2 即C.prototype.x = 2; 如下代码:

JavaScript

console.log(C.prototype.x); // 2

1
console.log(C.prototype.x); // 2

上边是实列化 var d = new C(3); 实列化C的构造函数时候,那么在C的构造函数内this.x = 3; 由此如下打字与印刷实列化后的d.x = 3;如下代码:

JavaScript

var d = new C(3); console.log(d.x); // 3

1
2
var d = new C(3);
console.log(d.x); // 3

剔除d.x 再拜会d.x的时候 本实列对象被删掉,只可以从原型上去搜索;由于C.prototype = new B(2); 也正是C承接于B,由此C的原型也是有x = 2;即C.prototype.x = 2; 如下代码:

JavaScript

delete d.x; console.log(d.x); //2

1
2
delete d.x;
console.log(d.x);  //2

除去C.prototype.x后,大家从下边代码知道,C是三番四次于B的,本身的原型被删掉后,会去追寻父成分的原型链,由此在B的原型上找到x =1; 如下代码:

JavaScript

delete C.prototype.x; console.log(d.x); // 1

1
2
delete C.prototype.x;
console.log(d.x);  // 1

当删除B的原型属性x后,由于B是承接于A的,因而会从父成分的原型链上查找A原型上是还是不是有x的质量,如若有的话,就再次回到,不然看A是或不是有继续,未有继续的话,继续往Object上去寻觅,若无找到就再次回到undefined 因而当删除B的原型x后,delete B.prototype.x; 打字与印刷出A上的原型x=0; 如下代码:

JavaScript

delete B.prototype.x; console.log(d.x); // 0 // 继续删除A的原型x后 结果未有找到,就再次回到undefined了; delete A.prototype.x; console.log(d.x); // undefined

1
2
3
4
5
6
delete B.prototype.x;
console.log(d.x);  // 0
 
// 继续删除A的原型x后 结果没有找到,就返回undefined了;
delete A.prototype.x;
console.log(d.x);  // undefined

在javascript中,一切都以对象,Function和Object都是函数的实列;构造函数的父原型指向于Function原型,Function.prototype的父原型指向与Object的原型,Object的父原型也本着与Function原型,Object.prototype是具有原型的顶层;

如下代码:

JavaScript

Function.prototype.a = function(){ console.log("小编是父原型Function"); } Object.prototype.a = function(){ console.log("小编是 父原型Object"); } function A(){ this.a = "a"; } A.prototype = { B: function(){ console.log("b"); } } // Function 和 Object都是函数的实列 如下: console.log(A instanceof Function); // true console.log(A instanceof Object); // true // A.prototype是三个指标,它是Object的实列,但不是Function的实列 console.log(A.prototype instanceof Function); // false console.log(A.prototype instanceof Object); // true // Function是Object的实列 同是Object也是Function的实列 console.log(Function instanceof Object); // true console.log(Object instanceof Function); // true /* * Function.prototype是Object的实列 但是Object.prototype不是Function的实列 * 表达Object.prototype是有着父原型的顶层 */ console.log(Function.prototype instanceof Object); //true console.log(Object.prototype instanceof Function); // false

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Function.prototype.a = function(){
    console.log("我是父原型Function");
}
Object.prototype.a = function(){
    console.log("我是 父原型Object");
}
function A(){
    this.a = "a";
}
A.prototype = {
    B: function(){
        console.log("b");
    }
}
// Function 和 Object都是函数的实列 如下:
console.log(A instanceof Function);  // true
console.log(A instanceof Object); // true
 
// A.prototype是一个对象,它是Object的实列,但不是Function的实列
console.log(A.prototype instanceof Function); // false
console.log(A.prototype instanceof Object); // true
 
// Function是Object的实列 同是Object也是Function的实列
console.log(Function instanceof Object);   // true
console.log(Object instanceof Function); // true
 
/*
* Function.prototype是Object的实列 但是Object.prototype不是Function的实列
* 说明Object.prototype是所有父原型的顶层
*/
console.log(Function.prototype instanceof Object);  //true
console.log(Object.prototype instanceof Function);  // false

三:明白原型承继机制

构造函数都有三个指针指向原型,Object.prototype是具备原型对象的顶层,比方如下代码:

JavaScript

var obj = {}; Object.prototype.name = "tugenhua"; console.log(obj.name); // tugenhua

1
2
3
var obj = {};
Object.prototype.name = "tugenhua";
console.log(obj.name); // tugenhua

给Object.prototype 定义一个属性,通过字面量创设的指标的话,都会从父类那边拿到Object.prototype的习性;

从地点代码大家精晓,原型承接的点子是:假设A须求持续于B,那么A.prototype(A的原型) = new B()(作为B的实列) 就能够实现A承接于B; 因而大家下边能够发轫化三个空的构造函数;然后把目的赋值给构造函数的原型,然后回到该构造函数的实列; 就可以完毕接二连三; 如下代码:

JavaScript

if(typeof Object.create !== 'function') { Object.create = function(o) { var F = new Function(); F.prototype = o; return new F(); } } var a = { name: 'longen', getName: function(){ return this.name; } }; var b = {}; b = Object.create(a); console.log(typeof b); //object console.log(b.name); // longen console.log(b.getName()); // longen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if(typeof Object.create !== 'function') {
    Object.create = function(o) {
        var F = new Function();
        F.prototype = o;
        return new F();
    }
}
var a = {
    name: 'longen',
    getName: function(){
        return this.name;
    }
};
var b = {};
b = Object.create(a);
console.log(typeof b); //object
console.log(b.name);   // longen
console.log(b.getName()); // longen

如上代码:大家先检查评定Object是不是曾经有Object.create该办法;若无的话就创办多少个; 该措施内创立一个空的构造器,把参数对象传递给构造函数的原型,最终回来该构造函数的实列,就兑现了承袭形式;如上测量检验代码:先定义八个a目的,有成员属性name=’longen’,还应该有三个getName()方法;最终回到该name属性; 然后定义多个b空对象,使用Object.create(a);把a对象承袭给b对象,由此b对象也会有总体性name和成员方法getName();

 精晓原型查找原理:指标查找先在该构造函数内搜索对应的质量,假设该对象未有该属性的话,

那么javascript会试着从该原型上去寻找,假使原型对象中也从未该属性的话,那么它们会从原型中的原型去搜索,直到查找的Object.prototype也并未有该属性的话,那么就能够重返undefined;由此大家想要仅在该对象内找寻的话,为了增长品质,大家得以选择hasOwnProperty()来推断该对象内有未有该属性,倘若有的话,就推行代码(使用for-in循环查找):如下:

JavaScript

var obj = { "name":'tugenhua', "age":'28' }; // 使用for-in循环 for(var i in obj) { if(obj.hasOwnProperty(i)) { console.log(obj[i]); //tugenhua 28 } }

1
2
3
4
5
6
7
8
9
10
var obj = {
    "name":'tugenhua',
    "age":'28'
};
// 使用for-in循环
for(var i in obj) {
    if(obj.hasOwnProperty(i)) {
        console.log(obj[i]); //tugenhua 28
    }
}

如上接收for-in循环查找对象里面包车型地铁天性,可是我们必要精通的是:for-in循环查找对象的品质,它是不保障顺序的,for-in循环和for循环;最实质的区分是:for循环是有种种的,for-in循环遍历对象是冬日的,因而大家假设须求对象保险顺序的话,可以把指标调换为数组来,然后再利用for循环遍历就能够;

上面我们来切磋原型承接的可取和劣势

JavaScript

// 先看上边包车型客车代码: // 定义构造函数A,定义特权属性和特权方法 function A(x) { this.x1 = x; this.getX1 = function(){ return this.x1; } } // 定义构造函数B,定义特权属性和特权方法 function B(x) { this.x2 = x; this.getX2 = function(){ return this.x1 + this.x2; } } B.prototype = new A(1);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 先看下面的代码:
// 定义构造函数A,定义特权属性和特权方法
function A(x) {
    this.x1 = x;
    this.getX1 = function(){
        return this.x1;
    }
}
// 定义构造函数B,定义特权属性和特权方法
function B(x) {
    this.x2 = x;
    this.getX2 = function(){
        return this.x1 + this.x2;
    }
}
B.prototype = new A(1);

B.prototype = new A(1);那句代码施行的时候,B的原型承袭于A,由此B.prototype也会有A的性子和措施,即:B.prototype.x1 = 1; B.prototype.getX1 方法;不过B也许有和好的特权属性x2和特权方法getX2; 如下代码:

JavaScript

function C(x) { this.x3 = x; this.getX3 = function(){ return this.x3 + this.x2; } } C.prototype = new B(2); C.prototype = new B(2);那句代码试行的时候,C的原型承继于B,因而C.prototype.x2 = 2; C.prototype.getX2方法且C也是有友好的特权属性x3和特权方法getX3, var b = new B(2); var c = new C(3); console.log(b.x1); // 1 console.log(c.x1); // 1 console.log(c.getX3()); // 5 console.log(c.getX2()); // 3 var b = new B(2);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function C(x) {
    this.x3 = x;
    this.getX3 = function(){
        return this.x3 + this.x2;
    }
}
C.prototype = new B(2);
C.prototype = new B(2);这句代码执行的时候,C的原型继承于B,因此C.prototype.x2 = 2; C.prototype.getX2方法且C也有自己的特权属性x3和特权方法getX3,
var b = new B(2);
var c = new C(3);
console.log(b.x1);  // 1
console.log(c.x1);  // 1
console.log(c.getX3()); // 5
console.log(c.getX2()); // 3
var b = new B(2);

实列化B的时候 b.x1 首先会在构造函数内查找x1属性,未有找到,由于B的原型承袭于A,因而A有x1属性,由此B.prototype.x1 = 1找到了;var c = new C(3); 实列化C的时候,从下边包车型客车代码能够看来C承继于B,B继承于A,由此在C函数中一直不找到x1属性,会往原型继续查找,直到找到父成分A有x1属性,因而c.x1 = 1;c.getX3()方法; 再次回到this.x3+this.x2 this.x3 = 3;this.x2 是B的习性,由此this.x2 = 2;c.getX2(); 查找的办法也生机勃勃律,不再解释

prototype的短处与亮点如下:

可取是:可以允好多个对象实列共享原型对象的积极分子及办法,

症结是:1. 各种构造函数只有三个原型,由此不直接支持多重承继;

2. 不可能很好地支撑多参数或动态参数的父类。在原型承继阶段,客户还不可能调整以

什么参数来实列化构造函数。

四:精通使用类承袭(承袭的更加好的方案)

类承袭也称之为构造函数承继,在子类中实行父类的构造函数;实现原理是:能够将三个构造函数A的方法赋值给另贰个构造函数B,然后调用该措施,使组织函数A在布局函数B内部被试行,此时构造函数B就具有了结构函数A中的属性和办法,这就是利用类承继达成B承接与A的基本原理;

正如代码实现demo:

JavaScript

function A(x) { this.x = x; this.say = function(){ return this.x; } } function B(x,y) { this.m = A; // 把结构函数A作为二个常常函数引用给不经常措施m this.m(x); // 实行组织函数A; delete this.m; // 消亡一时措施this.m this.y = y; this.method = function(){ return this.y; } } var a = new A(1); var b = new B(2,3); console.log(a.say()); //输出1, 试行组织函数A中的say方法 console.log(b.say()); //输出2, 能试行该办法求证被三番五次了A中的方法 console.log(b.method()); // 输出3, 构造函数也不无自个儿的主意

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function A(x) {
    this.x = x;
    this.say = function(){
        return this.x;
    }
}
function B(x,y) {
    this.m = A; // 把构造函数A作为一个普通函数引用给临时方法m
    this.m(x);  // 执行构造函数A;
    delete this.m; // 清除临时方法this.m
    this.y = y;
    this.method = function(){
        return this.y;
    }
}
var a = new A(1);
var b = new B(2,3);
console.log(a.say()); //输出1, 执行构造函数A中的say方法
console.log(b.say()); //输出2, 能执行该方法说明被继承了A中的方法
console.log(b.method()); // 输出3, 构造函数也拥有自己的方法

上面包车型地铁代码达成了简单的类承继的底子,可是在目眩神摇的编制程序中是不会动用方面包车型客车办法的,因为地方的代码远远不足严格;代码的耦合性高;我们能够利用越来越好的秘诀如下:

JavaScript

function A(x) { this.x = x; } A.prototype.getX = function(){ return this.x; } // 实例化A var a = new A(1); console.log(a.x); // 1 console.log(a.getX()); // 输出1 // 现行反革命我们来成立构造函数B,让其B承继与A,如下代码: function B(x,y) { this.y = y; A.call(this,x); } B.prototype = new A(); // 原型继承console.log(B.prototype.constructor); // 输出构造函数A,指针指向与构造函数A B.prototype.constructor = B; // 重新安装构造函数,使之指向B console.log(B.prototype.constructor); // 指向构造函数B B.prototype.getY = function(){ return this.y; } var b = new B(1,2); console.log(b.x); // 1 console.log(b.getX()); // 1 console.log(b.getY()); // 2 // 下边是躬体力行对构造函数getX进行重写的艺术如下: B.prototype.getX = function(){ return this.x; } var b2 = new B(10,20); console.log(b2.getX()); // 输出10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function A(x) {
    this.x = x;
}
A.prototype.getX = function(){
    return this.x;
}
// 实例化A
var a = new A(1);
console.log(a.x); // 1
console.log(a.getX()); // 输出1
// 现在我们来创建构造函数B,让其B继承与A,如下代码:
function B(x,y) {
    this.y = y;
    A.call(this,x);
}
B.prototype = new A();  // 原型继承
console.log(B.prototype.constructor); // 输出构造函数A,指针指向与构造函数A
B.prototype.constructor = B;          // 重新设置构造函数,使之指向B
console.log(B.prototype.constructor); // 指向构造函数B
B.prototype.getY = function(){
    return this.y;
}
var b = new B(1,2);
console.log(b.x); // 1
console.log(b.getX()); // 1
console.log(b.getY()); // 2
 
// 下面是演示对构造函数getX进行重写的方法如下:
B.prototype.getX = function(){
    return this.x;
}
var b2 = new B(10,20);
console.log(b2.getX());  // 输出10

上边我们来剖析上边的代码:

在构造函数B内,使用A.call(this,x);那句代码的意义是:大家都知晓使用call或然apply方法能够退换this指针指向,进而能够兑现类的继续,因此在B构造函数内,把x的参数传递给A构造函数,并且再而三于结构函数A中的属性和方式;

动用那句代码:B.prototype = new A();  能够兑现原型继承,约等于B能够承继A中的原型全数的主意;console.log(B.prototype.constructor); 打印出输出构造函数A,指针指向与组织函数A;大家通晓的是,当定义构造函数时候,其原型对象私下认可是四个Object类型的二个实例,其布局器暗中认可会被安装为构造函数自己,倘诺校正构造函数prototype属性值,使其针对性于另二个对象的话,那么新指标就不会有着原本的constructor的值,举个例子第一遍打字与印刷console.log(B.prototype.constructor); 指向于被实例化后的构造函数A,重写设置B的constructor的属性值的时候,第二回打印就本着于本身B;由此B承接与构造A及其原型的具备属性和艺术,当然我们也得以对构造函数B重写构造函数A中的方法,如上边最终几句代码是对结构函数A中的getX方法举办重写,来促成本人的政工~;

五:提议利用封装类达成持续

封装类达成一而再接二连三的基本原理:先定义一个封装函数extend;该函数有2个参数,Sub代表子类,Sup代表超类;在函数内,先定义一个空函数F, 用来落时效果与利益中间转播,先设置F的原型为超类的原型,然后把空函数的实例传递给子类的原型,使用贰个空函数的受益是:制止直接实例化超类恐怕会带来系统质量难点,比如超类的实例非常大的话,实例化会占用超级多内部存款和储蓄器;

如下代码:

JavaScript

function extend(Sub,Sup) { //Sub表示子类,Sup代表超类 // 首先定义叁个空函数 var F = function(){}; // 设置空函数的原型为超类的原型 F.prototype = Sup.prototype; // 实例化空函数,并把超类原型援用传递给子类 Sub.prototype = new F(); // 重新初始化子类原型的构造器为子类本身Sub.prototype.constructor = Sub; // 在子类中保留超类的原型,制止子类与超类耦合 Sub.sup = Sup.prototype; if(Sup.prototype.constructor === Object.prototype.constructor) { // 检验超类原型的构造器是或不是为原型本人 Sup.prototype.constructor = Sup; } } 测量试验代码如下: // 上面我们定义2个类A和类B,大家指标是达成B承接于A function A(x) { this.x = x; this.getX = function(){ return this.x; } } A.prototype.add = function(){ return this.x + this.x; } A.prototype.mul = function(){ return this.x * this.x; } // 构造函数B function B(x){ A.call(this,x); // 承接构造函数A中的全部属性及办法 } extend(B,A); // B承接于A var b = new B(11); console.log(b.getX()); // 11 console.log(b.add()); // 22 console.log(b.mul()); // 121

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function extend(Sub,Sup) {
    //Sub表示子类,Sup表示超类
    // 首先定义一个空函数
    var F = function(){};
 
    // 设置空函数的原型为超类的原型
    F.prototype = Sup.prototype;
 
// 实例化空函数,并把超类原型引用传递给子类
    Sub.prototype = new F();
 
    // 重置子类原型的构造器为子类自身
    Sub.prototype.constructor = Sub;
 
    // 在子类中保存超类的原型,避免子类与超类耦合
    Sub.sup = Sup.prototype;
 
    if(Sup.prototype.constructor === Object.prototype.constructor) {
        // 检测超类原型的构造器是否为原型自身
        Sup.prototype.constructor = Sup;
    }
 
}
测试代码如下:
// 下面我们定义2个类A和类B,我们目的是实现B继承于A
function A(x) {
    this.x = x;
    this.getX = function(){
        return this.x;
    }
}
A.prototype.add = function(){
    return this.x + this.x;
}
A.prototype.mul = function(){
    return this.x * this.x;
}
// 构造函数B
function B(x){
    A.call(this,x); // 继承构造函数A中的所有属性及方法
}
extend(B,A);  // B继承于A
var b = new B(11);
console.log(b.getX()); // 11
console.log(b.add());  // 22
console.log(b.mul());  // 121

注意:在封装函数中,犹如此一句代码:Sub.sup = Sup.prototype; 我们未来得以来掌握下它的意思:

举个例子说在B传承与A后,笔者给B函数的原型再定义八个与A雷同的原型相符的章程add();

如下代码

JavaScript

extend(B,A); // B继承于A var b = new B(11); B.prototype.add = function(){ return this.x + "" + this.x; } console.log(b.add()); // 1111

1
2
3
4
5
6
extend(B,A);  // B继承于A
var b = new B(11);
B.prototype.add = function(){
    return this.x + "" + this.x;
}
console.log(b.add()); // 1111

那么B函数中的add方法会覆盖A函数中的add方法;因而为了不掩瞒A类中的add()方法,且调用A函数中的add方法;能够如下编写代码:

JavaScript

B.prototype.add = function(){ //return this.x + "" + this.x; return B.sup.add.call(this); } console.log(b.add()); // 22

1
2
3
4
5
B.prototype.add = function(){
    //return this.x + "" + this.x;
    return B.sup.add.call(this);
}
console.log(b.add()); // 22

B.sup.add.call(this); 中的B.sup就含有了协会函数A函数的指针,由此富含A函数的全体属性和章程;因而得以调用A函数中的add方法;

如上是落到实处持续的三种方法,类承袭和原型承袭,不过那几个后续不可能持续DOM对象,也不援救承继系统静态对象,静态方法等;譬如Date对象如下:

JavaScript

// 使用类承袭Date对象 function D(){ Date.apply(this,arguments); // 调用Date对象,对其引述,达成承接 } var d = new D(); console.log(d.toLocaleString()); // [object object]

1
2
3
4
5
6
// 使用类继承Date对象
function D(){
    Date.apply(this,arguments); // 调用Date对象,对其引用,实现继承
}
var d = new D();
console.log(d.toLocaleString()); // [object object]

如上代码运营打字与印刷出object,我们能够观看使用类承接不能贯彻系统静态方法date对象的接续,因为她不是简单的函数结构,对注明,赋值和起初化都进展了包装,由此无法继续;

上边大家再来看看使用原型承继date对象;

JavaScript

function D(){} D.prototype = new D(); var d = new D(); console.log(d.toLocaleString());//[object object]

1
2
3
4
function D(){}
D.prototype = new D();
var d = new D();
console.log(d.toLocaleString());//[object object]

我们从代码中看出,使用原型承接也不可能继续Date静态方法;可是大家得以如下封装代码承袭:

JavaScript

function D(){ var d = new Date(); // 实例化Date对象 d.get = function(){ // 定义本地点法,直接调用Date对象的法门 console.log(d.toLocaleString()); } return d; } var d = new D(); d.get(); // 二〇一四/12/21 清晨12:08:38

1
2
3
4
5
6
7
8
9
function D(){
    var d = new Date();  // 实例化Date对象
    d.get = function(){ // 定义本地方法,间接调用Date对象的方法
        console.log(d.toLocaleString());
    }
    return d;
}
var d = new D();
d.get(); // 2015/12/21 上午12:08:38

六:精晓使用复制承继

复制承接的基本原理是:先规划三个空对象,然后利用for-in循环来遍历对象的积极分子,将该目的的积极分子八个三个复制给新的空对象里面;那样就落到实处了复制承继了;如下代码:

JavaScript

function A(x,y) { this.x = x; this.y = y; this.add = function(){ return this.x + this.y; } } A.prototype.mul = function(){ return this.x * this.y; } var a = new A(2,3); var obj = {}; for(var i in a) { obj[i] = a[i]; } console.log(obj); // object console.log(obj.x); // 2 console.log(obj.y); // 3 console.log(obj.add()); // 5 console.log(obj.mul()); // 6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function A(x,y) {
    this.x = x;
    this.y = y;
    this.add = function(){
        return this.x + this.y;
    }
}
A.prototype.mul = function(){
    return this.x * this.y;
}
var a = new A(2,3);
var obj = {};
for(var i in a) {
    obj[i] = a[i];
}
console.log(obj); // object
console.log(obj.x); // 2
console.log(obj.y); // 3
console.log(obj.add()); // 5
console.log(obj.mul()); // 6

如上代码:先定义三个构造函数A,函数里面有2个属性x,y,还会有三个add方法,该构造函数原型有贰个mul方法,首先实列化下A后,再创设叁个空对象obj,遍历对象贰个个复制给空对象obj,从地点的打字与印刷效果来看,大家可以看出已经达成了复制承接了;对于复制承袭,我们得以封装成如下方法来调用:

JavaScript

// 为Function扩充复制传承方法 Function.prototype.extend = function(o) { for(var i in o) { //把参数对象的积极分子复制给当下目的的构造函数原型对象 this.constructor.prototype[i] = o[i]; } } // 测量试验代码如下: var o = function(){}; o.extend(new A(1,2)); console.log(o.x); // 1 console.log(o.y); // 2 console.log(o.add()); // 3 console.log(o.mul()); // 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 为Function扩展复制继承方法
Function.prototype.extend = function(o) {
    for(var i in o) {
        //把参数对象的成员复制给当前对象的构造函数原型对象
        this.constructor.prototype[i] = o[i];
    }
}
// 测试代码如下:
var o = function(){};
o.extend(new A(1,2));
console.log(o.x);  // 1
console.log(o.y);  // 2
console.log(o.add()); // 3
console.log(o.mul()); // 2

下边封装的扩展承继方法中的this对象指向于方今实列化后的指标,并非指向于构造函数本人,由此要接受原型扩充成员来讲,就须要使用constructor属性来指向它的构造器,然后经过prototype属性指向构造函数的原型;

复制承继好似下优点:

1. 它不可能承接系统主旨对象的只读方法和总体性

2. 假诺目的数据相当的多以来,那样四个个复制的话,品质是超低的;

3. 只有对象被实列化后,技巧给遍历对象的分子和属性,相对来说远远不够利索;

4. 复制承接只是简短的赋值,所以只要赋值的指标是引用类型的指标的话,或者会设有一点副功用;如上我们见到好似上有的劣势,上边大家得以选拔clone(克隆的办法)来优化下:

基本思路是:为Function扩充贰个办法,该办法能够把参数对象赋值赋值二个空构造函数的原型对象,然后实列化构造函数并重回实列对象,那样该目的就具有了该对象的享有成员;代码如下:

JavaScript

Function.prototype.clone = function(o){ function Temp(){}; Temp.prototype = o; return Temp(); } // 测量检验代码如下: Function.clone(new A(1,2)); console.log(o.x); // 1 console.log(o.y); // 2 console.log(o.add()); // 3 console.log(o.mul()); // 2

1
2
3
4
5
6
7
8
9
10
11
Function.prototype.clone = function(o){
    function Temp(){};
    Temp.prototype = o;
    return Temp();
}
// 测试代码如下:
Function.clone(new A(1,2));
console.log(o.x);  // 1
console.log(o.y);  // 2
console.log(o.add()); // 3
console.log(o.mul()); // 2

2 赞 19 收藏 1 评论

图片 2

前言

HTTP 补助 GZip 压缩,可节省不计其数传输财富。但可惜的是,唯有下载才有,上传并不补助。

倘诺上传也能减弱,那就康健了。特别切合一大波文书提交的场合,比方和讯,正是很好的例证。

虽说正式不援助「上传压缩」,但还能团结来兑现。

为什么选择 SVG?

Easy: JSONP

原生的JavaScript:

XHTML

<script> function myCallback(data){ console.log(data); } </script> <script src=";

1
2
3
4
5
6
<script>
  function myCallback(data){
    console.log(data);
  }
</script>
<script src="https://jsonp.afeld.me/?callback=myCallback&url=http://jsonview.com/example.json"></script>

myCallback函数里的data正是回来的json数据了。很分明,服务器会帮你去央浼你需求的json数据,然后装进在你设置的回调函数名中,这时候要介怀的代码中的樱桃红两处要保持风流倜傥致,url后跟的便是急需的json数据地址。

自然JQuery封装好的艺术特别简明:

XHTML

<script> $.getJSON('', function(data){ console.log(data); }); </script>

1
2
3
4
5
<script>
  $.getJSON('https://jsonp.afeld.me/?callback=?&url=http://jsonview.com/example.json', function(data){
    console.log(data);
  });
</script>

Custom Elements

Flash

首要推荐方案当然是 Flash,终归它提供了压缩 API。除了 zip 格式,还协理 lzma 这种一流压缩。

因为是原生接口,所以品质超级高。而且对应的 swf 文件,也相当小。

Logo字体渲染难点

Logo字体平素只是风流倜傥种 hack。我们后边运用多少个自定义字体,并将Logo作为 Unicode 符号。那样Logo字体就能够经过包装后的 CSS 来引进。只要轻便地在自便成分上增多一个class,Logo就能够展现出来。然后大家只利用 CSS 就能够即时改换Logo的尺码和颜料了。

噩运的是,纵然那个Logo是矢量图形,但在 1x 荧屏下的渲染效果并不美貌。在依照 Web基特的浏览器下,图标只怕会在一些窗口宽度下变得模糊。因为那个时候Logo是作为文本输出的,本来用于抓牢文书可读性的次像素渲染手艺反而使图标看起来倒霉大多。

Easier: Cross-domain AJAX (CORS)

比jsonp更简约的点子是COTucsonS(好呢,也没轻巧到哪去啊…)

XHTML

<script> $.get('', function(data){ console.log(data); }); </script>

1
2
3
4
5
<script>
  $.get('https://jsonp.afeld.me/?url=http://jsonview.com/example.json', function(data){
    console.log(data);
  });
</script>

那回是真的地发送了ajax央求了,为何跨域了仍然是能够央求?因为服务端设置好了。

图片 3

而伏乞的json数据也是服务端帮您获得的。也便是说,客商端发送须要,服务端分析呼吁的url,然后服务器作为代理发送http央求去央求json数据(那时候空中楼阁客商端跨域),再回到给顾客端作为回调的参数。

概述

Custom Elements 看名就能够猜到其意义,是提供生机勃勃种方法让开垦者能够自定义 HTML 成分,包含特定的整合,样式和行事。帮忙 Web Components 标准的浏览器会提供一花样好些个 API 给开荒者用于创立自定义的成分,或许扩表现成成分。

这意气风发项标准的草案还地处不平稳的情况,时有更新,API 还或者有所变化,上边的笔记以 Cutsom Elements 2016.02.26 那些版本为准,因为在新式的 chrome 浏览器已然是能够干活的了,这样能够行使 demo 来做尝试,末了小编会再轻便写一下风行文书档案和那个的分别。

JavaScript

Flash 渐渐淘汰,但代表的 HTML5,却不曾提供压缩 API。只好自身用 JS 达成。

那尽管平价,但运营速度就慢多了,况兼相应的 JS 也非常的大。

大器晚成旦代码有 50kb,而数据压缩后只小 10kb,那就不足了。除非量大,才有意义。

对页面渲染的精耕细作

因为大家从来将 SVG 注入 HTML(那也是我们筛选这种方法更大的来由),所以不再汇合世Logo字体下载、缓存、渲染过程中现身的体制闪动。

图片 4页面闪动

Easiest: jQuery Plugin

最轻巧易行的,作者怎么感觉越是复杂了…

略…

小结,因为要用第三方的服务器,所以既耗费时间又有不鲜明因素(举例服务器挂了),不合适用在真正项目中,自个儿玩玩能够选取。

1 赞 收藏 评论

图片 5

registerElement

率先,大家得以尝试在 chrome 调控台输入 HTMLInputElement,能够看来是有这么二个事物的,这些精通为 input DOM 成分实例化时的构造函数,基础的是 HTMLElement

Web Components 标准建议提供那样三个接口:

JavaScript

document.registerElement('x-foo', { prototype: Object.create(HTMLElement.prototype, { createdCallback: { value: function() { ... } }, ... }) })

1
2
3
4
5
6
7
8
document.registerElement('x-foo', {
  prototype: Object.create(HTMLElement.prototype, {
    createdCallback: {      
      value: function() { ... }
    },
    ...
  })
})

你能够使用 document.registerElement 来注册五个标签,标准中为了提供 namesapce 的支持,幸免矛盾,规定标签类型(也可知为名字)须要动用 - 连接。同期,不能够是以下那有个别:

  • annotation-xml
  • color-profile
  • font-face
  • font-face-src
  • font-face-uri
  • font-face-format
  • font-face-name
  • missing-glyph

第贰个参数是标签相关的配备,首假若提供一个 prototype,那几个原型对象是以 HTMLElement 等的原型为根基创立的目的。然后您便足以在 HTML 中去行使自定义的标签。如:

XHTML

<div> <x-foo></x-foo> </div>

1
2
3
<div>
  <x-foo></x-foo>
</div>

是还是不是嗅到了 React 的含意?行吗,React 说它和煦首要不是做那些事情的。

其他

可不可以不要 JS,而是使用一些接口,直接达成降低?

其实,在 HTML5 刚面世时,就留神到了贰个职能:canvas 导出图片。能够改造jpg、png 等格式。

设若在妄想的话,相信你也想开了。没有错,正是 png —— 它是无损压缩的。

作者们把常常数据当成像素点,画到 canvas 上,然后导出成 png,便是叁个卓绝的收缩包了~


上面带头商讨。。。

可访谈性

就像在《Logo字体已死》一文中所述,有个别客商会覆盖掉 GitHub 的书体。对于患有读写障碍的客户,有些特定字体是进一步轻松阅读的。对于改进字体的客商来说,大家依据字体的Logo就被渲染成了空白方框。那搞乱了 GitHub 页面布局,並且也不提供任何音讯。而不管字体覆盖与否,SVG 都能够健康突显。对于读屏器客商来讲,SVG 能让我们接纳是读出 alt 属性依然直接完全跳过。

生命周期和回调

在这里个 API 的基础上,Web Components 标准提供了一应有尽有决定自定义成分的方法。大家来挨门逐户看下:

一个自定义元素会经历以下这个生命周期:

  • 登记前创办
  • 挂号自定义元素定义
  • 在登记后创设成分实例
  • 要素插入到 document 中
  • 元素从 document 中移除
  • 要素的性格变化时

这几个是很主要的内容,开拓者能够在注册新的自定义元素时钦定相应的生命周期回调来为自定义成分增加各样自定义的表现,这么些生命周期回调富含了:

  • createdCallback
    自定义成分注册后,在实例化之后会调用,通常多用于做成分的初始化,如插入子成分,绑定事件等。
  • attachedCallback
    要素插入到 document 时接触。
  • detachedCallback
    要素从 document 中移除时接触,或者会用来做肖似 destroy 之类的政工。
  • attributeChangedCallback
    要素属性别变化化时接触,能够用来从外到内的通信。外界通过改正成分的习性来让个中获得有关的数据相同的时间施行相应的操作。

其三遍调在分裂景况下有对应不一样的参数:

  • 设置属性时,参数列表是:属性名称,null,值,命名空间
  • 修正属性时,参数列表是:属性名称,旧值,新值,命名空间
  • 剔除属性时,参数列表是:属性名称,旧值,null,命名空间

好了,就上边理解到的底子上,假如大家要创立三个自定义的 button-hello 按键,点击时会 alert('hello world'),代码如下:

JavaScript

document.registerElement('button-hello', { prototype: Object.create(HTMLButtonElement.prototype, { createdCallback: { value: function createdCallback() { this.innerHTML = '<button>hello world</button>' this.addEventListener('click', () => { alert('hello world') }) } } }) })

1
2
3
4
5
6
7
8
9
10
11
12
document.registerElement('button-hello', {
  prototype: Object.create(HTMLButtonElement.prototype, {
    createdCallback: {
      value: function createdCallback() {
        this.innerHTML = '<button>hello world</button>'
        this.addEventListener('click', () => {
          alert('hello world')
        })
      }
    }
  })
})

要小心上述代码施行之后技巧运用 <button-hello></button-hello>

本文由云顶集团400800044发布于云顶集团400800044,转载请注明出处:深远了然Javascript面向对象编制程序,实现数据压

关键词: