简单粗暴地理解 JS 原型链

2016/05/07 · JavaScript
· 1 评论 ·
原型链

原文出处:
茄果   

原型链理解起来有点绕了,网上资料也是很多,每次晚上睡不着的时候总喜欢在网上找点原型链和闭包的文章看,效果极好。

不要纠结于那一堆术语了,那除了让你脑筋拧成麻花,真的不能帮你什么。简单粗暴点看原型链吧,想点与代码无关的事,比如人、妖以及人妖。

1)人是人他妈生的,妖是妖他妈生的。人和妖都是对象实例,而人他妈和妖他妈就是原型。原型也是对象,叫原型对象。

图片 1

2)人他妈和人他爸啪啪啪能生出一堆人宝宝、妖他妈和妖他爸啪啪啪能生出一堆妖宝宝,啪啪啪就是构造函数,俗称造人。

图片 2

3)人他妈会记录啪啪啪的信息,所以可以通过人他妈找到啪啪啪的信息,也就是说能通过原型对象找到构造函数。

4)人他妈可以生很多宝宝,但这些宝宝只有一个妈妈,这就是原型的唯一性。

5)人他妈也是由人他妈他妈生的,通过人他妈找到人他妈他妈,再通过人他妈他妈找到人他妈他妈……,这个关系叫做原型链。

图片 3

6)原型链并不是无限的,当你通过人他妈一直往上找,最后发现你会发现人他妈他妈他妈……的他妈都不是人,也就是原型链最终指向null。

7)人他妈生的人会有人的样子,妖他妈生的妖会有妖的丑陋,这叫继承。

图片 4

8)你继承了你妈的肤色,你妈继承了你妈他妈的肤色,你妈他妈……,这就是原型链的继承。

9)你谈对象了,她妈让你带上房产证去提货,你若没有,那她妈会问你妈有没有,你妈没有那她妈会问你妈她妈有没有……这就是原型链的向上搜索。

10)你会继承你妈的样子,但是你也可以去染发洗剪吹,就是说对象的属性可以自定义,会覆盖继承得到的属性。

图片 5

11)虽然你洗剪吹了染成黄毛了,但你不能改变你妈的样子,你妈生的弟弟妹妹跟你的黄毛洗剪吹没一点关系,就是说对象实例不能改动原型的属性。

12)但是你家被你玩火烧了的话,那就是说你家你妈家你弟们家都被烧了,这就是原型属性的共享。

13)你妈外号阿珍,邻居大娘都叫你阿珍儿,但你妈头发从飘柔做成了金毛狮王后,隔壁大婶都改口叫你包租仔,这叫原型的动态性。

图片 6

14)你妈爱美,又跑到韩国整形,整到你妈他妈都认不出来,即使你妈头发换回飘柔了,但隔壁邻居还是叫你金毛狮王子。因为没人认出你妈,整形后的你妈已经回炉再造了,这就是原型的整体重写。

图片 7

尼玛!你特么也是够了! Don’t BB! Show me the code!

function Person (name) { this.name = name; } function Mother () { }
Mother.prototype = { //Mother的原型 age: 18, home: [‘Beijing’,
‘Shanghai’] }; Person.prototype = new Mother(); //Person的原型为Mother
//用chrome调试工具查看,提供了__proto__接口查看原型,这里有两层原型,各位还是直接看chrome好一点。
var p1 = new Person(‘Jack’); //p1:’Jack’;
__proto__:{__proto__:18,[‘Beijing’,’Shanghai’]} var p2 = new
Person(‘Mark’); //p2:’Mark’;
__proto__:{__proto__:18,[‘Beijing’,’Shanghai’]} p1.age = 20;
/* 实例不能改变原型的基本值属性,正如你洗剪吹染黄毛跟你妈无关 *
在p1实例下增加一个age属性的普通操作,与原型无关。跟var o={};
o.age=20一样。 * p1:下面多了个属性age,而__proto__跟
Mother.prototype一样,age=18。 * p2:只有属性name,__proto__跟
Mother.prototype一样 */ p1.home[0] = ‘Shenzhen’; /*
原型中引用类型属性的共享,正如你烧了你家,就是烧了你全家的家 *
这个先过,下文再仔细唠叨一下可好? * p1:’Jack’,20;
__proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]} *
p2:’Mark’; __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
*/ p1.home = [‘Hangzhou’, ‘Guangzhou’]; /*
其实跟p1.age=20一样的操作。换成这个理解: var o={};
o.home=[‘big’,’house’] * p1:’Jack’,20,[‘Hangzhou’,’Guangzhou’];
__proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]} *
p2:’Mark’; __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
*/ delete p1.age; /*
删除实例的属性之后,原本被覆盖的原型值就重见天日了。正如你剃了光头,遗传的迷人小卷发就长出来了。
*
这就是向上搜索机制,先搜你,然后你妈,再你妈他妈,所以你妈的改动会动态影响你。
* p1:’Jack’,[‘Hangzhou’,’Guangzhou’];
__proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]} *
p2:’Mark’; __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
*/ Person.prototype.lastName = ‘Jin’; /*
改写原型,动态反应到实例中。正如你妈变新潮了,邻居提起你都说你妈真潮。
*
注意,这里我们改写的是Person的原型,就是往Mother里加一个lastName属性,等同于Mother.lastName=’Jin’
*
这里并不是改Mother.prototype,改动不同的层次,效果往往会有很大的差异。
* p1:’Jack’,[‘Hangzhou’,’Guangzhou’];
__proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]} *
p2:’Mark’;
__proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]} */
Person.prototype = { age: 28, address: { country: ‘USA’, city:
‘Washington’ } }; var p3 = new Person(‘Obama’); /*
重写原型!这个时候Person的原型已经完全变成一个新的对象了,也就是说Person换了个妈,叫后妈。
* 换成这样理解:var a=10; b=a; a=20;
c=a。所以b不变,变得是c,所以p3跟着后妈变化,与亲妈无关。 *
p1:’Jack’,[‘Hangzhou’,’Guangzhou’];
__proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]} *
p2:’Mark’;
__proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]} *
p3:’Obama’;__proto__: 28 {country: ‘USA’, city: ‘Washington’} */
Mother.prototype.no = 9527; /*
改写原型的原型,动态反应到实例中。正如你妈他妈变新潮了,邻居提起你都说你丫外婆真潮。
*
注意,这里我们改写的是Mother.prototype,p1p2会变,但上面p3跟亲妈已经了无瓜葛了,不影响他。
* p1:’Jack’,[‘Hangzhou’,’Guangzhou’];
__proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’],9527} *
p2:’Mark’;
__proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’],9527} *
p3:’Obama’;__proto__: 28 {country: ‘USA’, city: ‘Washington’} */
Mother.prototype = { car: 2, hobby: [‘run’,’walk’] }; var p4 = new
Person(‘Tony’); /*
重写原型的原型!这个时候Mother的原型已经完全变成一个新的对象了!人他妈换了个后妈!
*
由于上面Person与Mother已经断开联系了,这时候Mother怎么变已经不影响Person了。
* p4:’Tony’;__proto__: 28 {country: ‘USA’, city: ‘Washington’} */
Person.prototype = new Mother(); //再次绑定 var p5 = new
Person(‘Luffy’); //
这个时候如果需要应用这些改动的话,那就要重新将Person的原型绑到mother上了
// p5:’Luffy’;__proto__:{__proto__: 2, [‘run’,’walk’]}
p1.__proto__.__proto__.__proto__.__proto__
//null,你说原型链的终点不是null?
Mother.__proto__.__proto__.__proto__
//null,你说原型链的终点不是null?

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
function Person (name) { this.name = name; }
function Mother () { }
Mother.prototype = {    //Mother的原型
    age: 18,
    home: [‘Beijing’, ‘Shanghai’]
};
Person.prototype = new Mother(); //Person的原型为Mother
 
//用chrome调试工具查看,提供了__proto__接口查看原型,这里有两层原型,各位还是直接看chrome好一点。
var p1 = new Person(‘Jack’); //p1:’Jack’; __proto__:{__proto__:18,[‘Beijing’,’Shanghai’]}
var p2 = new Person(‘Mark’); //p2:’Mark’; __proto__:{__proto__:18,[‘Beijing’,’Shanghai’]}
 
p1.age = 20;  
/* 实例不能改变原型的基本值属性,正如你洗剪吹染黄毛跟你妈无关
* 在p1实例下增加一个age属性的普通操作,与原型无关。跟var o={}; o.age=20一样。
* p1:下面多了个属性age,而__proto__跟 Mother.prototype一样,age=18。
* p2:只有属性name,__proto__跟 Mother.prototype一样
*/
 
p1.home[0] = ‘Shenzhen’;
/* 原型中引用类型属性的共享,正如你烧了你家,就是烧了你全家的家
* 这个先过,下文再仔细唠叨一下可好?
* p1:’Jack’,20; __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
* p2:’Mark’;    __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
*/
 
p1.home = [‘Hangzhou’, ‘Guangzhou’];
/* 其实跟p1.age=20一样的操作。换成这个理解: var o={}; o.home=[‘big’,’house’]
* p1:’Jack’,20,[‘Hangzhou’,’Guangzhou’]; __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
* p2:’Mark’;                             __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
*/
 
delete p1.age;    
/* 删除实例的属性之后,原本被覆盖的原型值就重见天日了。正如你剃了光头,遗传的迷人小卷发就长出来了。
* 这就是向上搜索机制,先搜你,然后你妈,再你妈他妈,所以你妈的改动会动态影响你。
* p1:’Jack’,[‘Hangzhou’,’Guangzhou’]; __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
* p2:’Mark’;                          __proto__:{__proto__:18,[‘Shenzhen’,’Shanghai’]}
*/
 
 
Person.prototype.lastName = ‘Jin’;
/* 改写原型,动态反应到实例中。正如你妈变新潮了,邻居提起你都说你妈真潮。
* 注意,这里我们改写的是Person的原型,就是往Mother里加一个lastName属性,等同于Mother.lastName=’Jin’
* 这里并不是改Mother.prototype,改动不同的层次,效果往往会有很大的差异。
* p1:’Jack’,[‘Hangzhou’,’Guangzhou’]; __proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]}
* p2:’Mark’;                          __proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]}
*/
 
Person.prototype = {
    age: 28,
    address: { country: ‘USA’, city: ‘Washington’ }
};
var p3 = new Person(‘Obama’);
/* 重写原型!这个时候Person的原型已经完全变成一个新的对象了,也就是说Person换了个妈,叫后妈。
* 换成这样理解:var a=10; b=a; a=20; c=a。所以b不变,变得是c,所以p3跟着后妈变化,与亲妈无关。
* p1:’Jack’,[‘Hangzhou’,’Guangzhou’]; __proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]}
* p2:’Mark’;                          __proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’]}
* p3:’Obama’;__proto__: 28 {country: ‘USA’, city: ‘Washington’}
*/
 
 
Mother.prototype.no = 9527;
/* 改写原型的原型,动态反应到实例中。正如你妈他妈变新潮了,邻居提起你都说你丫外婆真潮。
* 注意,这里我们改写的是Mother.prototype,p1p2会变,但上面p3跟亲妈已经了无瓜葛了,不影响他。
* p1:’Jack’,[‘Hangzhou’,’Guangzhou’]; __proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’],9527}
* p2:’Mark’;                          __proto__:{‘jin’,__proto__:18,[‘Shenzhen’,’Shanghai’],9527}
* p3:’Obama’;__proto__: 28 {country: ‘USA’, city: ‘Washington’}
*/
 
Mother.prototype = {
    car: 2,
    hobby: [‘run’,’walk’]
};
var p4 = new Person(‘Tony’);
/* 重写原型的原型!这个时候Mother的原型已经完全变成一个新的对象了!人他妈换了个后妈!
* 由于上面Person与Mother已经断开联系了,这时候Mother怎么变已经不影响Person了。
* p4:’Tony’;__proto__: 28 {country: ‘USA’, city: ‘Washington’}
*/
Person.prototype = new Mother(); //再次绑定
var p5 = new Person(‘Luffy’);
// 这个时候如果需要应用这些改动的话,那就要重新将Person的原型绑到mother上了
// p5:’Luffy’;__proto__:{__proto__: 2, [‘run’,’walk’]}
 
p1.__proto__.__proto__.__proto__.__proto__ //null,你说原型链的终点不是null?
Mother.__proto__.__proto__.__proto__    //null,你说原型链的终点不是null?

看完基本能理解了吧?

现在再来说说 p1.age = 20、p1.home = [‘Hangzhou’, ‘Guangzhou’]
和  p1.home[0] = ‘Shenzhen’ 的区别。 p1.home[0] = ‘Shenzhen’;
 总结一下是 p1.object.method,p1.object.property 这样的形式。

p1.age = 20;  p1.home = [‘Hangzhou’,
‘Guangzhou’];这两句还是比较好理解的,先忘掉原型吧,想想我们是怎么为一个普通对象增加属性的:

var obj = new Object(); obj.name=’xxx’; obj.num = [100, 200];

1
2
3
var obj = new Object();
obj.name=’xxx’;
obj.num = [100, 200];

这样是不是就理解了呢?一样一样的呀。

那为什么 p1.home[0] = ‘Shenzhen’ 不会在 p1 下创建一个 home
数组属性,然后将其首位设为 ‘Shenzhen’呢?
我们还是先忘了这个,想想上面的obj对象,如果写成这样: var obj.name =
‘xxx’, obj.num = [100, 200],能得到你要的结果吗?
显然,除了报错你什么都得不到。因为obj还未定义,又怎么能往里面加入东西呢?同理,p1.home[0]中的
home 在 p1 下并未被定义,所以也不能直接一步定义 home[0]
了。如果要在p1下创建一个 home 数组,当然是这么写了:

p1.home = []; p1.home[0] = ‘Shenzhen’;

1
2
p1.home = [];
p1.home[0] = ‘Shenzhen’;

这不就是我们最常用的办法吗?

而之所以 p1.home[0] =
‘Shenzhen’ 不直接报错,是因为在原型链中有一个搜索机制。当我们输入
p1.object
的时候,原型链的搜索机制是先在实例中搜索相应的值,找不到就在原型中找,还找不到就再往上一级原型中搜索……一直到了原型链的终点,就是到null还没找到的话,就返回一个
undefined。当我们输入 p1.home[0] 的时候,也是同样的搜索机制,先搜索 p1
看有没有名为 home
的属性和方法,然后逐级向上查找。最后我们在Mother的原型里面找到了,所以修改他就相当于修改了
Mother 的原型啊。

一句话概括:p1.home[0] = ‘Shenzhen’  等同于
 Mother.prototype.home[0] = ‘Shenzhen’。

由上面的分析可以知道,原型链继承的主要问题在于属性的共享,很多时候我们只想共享方法而并不想要共享属性,理想中每个实例应该有独立的属性。因此,原型继承就有了下面的两种改良方式:

时间流互联网之未来(上)

2013/04/15 · HTML5 · 1
评论 ·
HTML5

来源:pingwest

从空间模式转向时间模式

图片 8

两个月前,耶鲁大学计算机科学教授David
Gelernter 在连线杂志上发表了一篇文章,称未来的互联网将从空间模式转向时间模式。当时很多科技媒体都开始翻译,但对于大多数人来说,David
Gelernter提出的这种概念太超前,顶多也就是明白有这么一个新闻而已。甚至对大部分媒体来说,他们脑海中也根本无法想象Gelernter
提出的这种概念是什么样子。

David Gelernter
的这个理论确实有一些超前因素(更何况他16年前就提出了类似的观点),但实际上这里面的很多说法,已经开始进入我们的生活了。下面,本文就大致根据David
Gelernter
的理论,结合当下的互联网发展来简单介绍一下。由于此理论与互联网的联系非常庞杂,后面我们还会分五章(共六章)来从各个层面介绍,以便提供一个深入的认识。

David Gelernter
的观点,总的来说,就是现在的互联网还是以一个个网站、一款款App、一项项服务这种独立的形式存在的,你需要分别去登陆各个网站,每个服务都有一个独立的ID,他们在空间上是分开的,就像你去街上逛的一家家店铺一样。而随着网络的发展、信息世界的开放、智能终端的普及,这些独立的内容会聚合在一起,并以时间流的形式呈现给我们每个人。你只要刷信息流,就可以看到这个世界在发生什么、看到朋友们在干什么,去获取信息、购物、发布内容、检索、与人沟通等。

最简单的例子,就是Twitter 和Facebook
的时间流信息的形式。Twitter前天刚刚在Twitter
Card上新增了一个App超级链接,用户可以在Twitter信息流中去看好友分享的内容并直接跳转过去。这样,当大家都把内容分享到Twitter时,你就能看到所有动态包括新闻、朋友分享的文章、上传到Flickr的图片、上传到Vine的视频等
Facebook
也是,现在每个网站上都有Facebook的大拇指按钮,你在FB上可以看到各种从其他网站上分享过来的东西。(哈哈,或许你已经想到了Facebook今天推出的
Home for Android,我们在第五章中会详细介绍这种形式。)

互联网时间流的概念,意味着未来的信息会高度整合,这些信息包括博客、RSS订阅、Twitter等社交网络信息、Instagram图片、朋友分享的电影图书音乐、Foursquare
签到等等。
David Gelernter
称之为魔法日记(他把空间模式称为杂志摊),信息流像日记一样不断地滚动,记录着你的世界上发生的每一条信息,当你触碰她时,她便停止,你可以不断地翻阅、搜索、在里面和朋友互动等。而这个日记最基本的特征就是根据时间排序,你生活中的所有行为,都会以时间这一最基本的标签保存起来。

图片 9

这种时间流的形态,将直接影响着我们的信息获取方式、介质展现形式(包括硬件和软件)、搜索的形式、信息生产的方式、电商的形式等。当这种时间流形态最终成型之后,互联网的概念便会慢慢的从人们的认知中消失,像杂志摊的网站类型也会从人们的生活中消失(虽然它们仍然存在),每个人看到的就是一个“流”,这个流包括万象,如果哪家网站或服务拒绝进入这个流,那就意味着拒绝进入互联网。

当然,每个人看到的都只是整个“世界流”的一部分,是自己有意无意订制的一个个人世界。当你把微博、豆瓣、邮箱、微信、色影无忌、V2EX这些你常用的网站整合在一条信息流之后,你想要的所有信息都尽收眼底。有人问那微博信息流那么多,被刷屏怎么办?首先这些信息流肯定会有优先级,其次碎片化的时间可以帮你解决部分问题,再次一个人本来需要的信息就有限,这样也会让你更好的利用时间,获取最有价值的信息。当然,像Evernote、Instapaper、Doit.im、Mindjet
Maps这些工具也会帮你管理、筛选知识和信息,更好的规划你的生活。

的时间流互联网基本上就是这样,后面我们会从各个方面阐述一下这种理论目前已有的一些趋势性的论证依据,以及在这种理论下未来的互联网、移动互联网发展的具体形式。

 

10款最佳JavaScript 和 HTML5演示(幻灯片)框架

2014/12/26 · HTML5,
JavaScript ·
HTML5,
Javascript,
幻灯片

本文由 伯乐在线 –
cucr
翻译,黄利民
校稿。未经许可,禁止转载!
英文出处:devzum.com。欢迎加入翻译组。

JavaScript 和
HTML5 框架在现代浏览器中为创建演示文稿扮演着重要的角色。他们在web页面中嵌入特性,提供了一种有效的方式来展示信息。一般来说,手动编写需要大量的时间和精力。而且手动真的很复杂,初学者如果没有应用有效的技术无法获得足够的成果。另一方面,演示框架具有在不发生任何问题和复杂性就产生很好的工作成果的特性。他们以最大的速度和准确性交付最好的web开发成果。

HTML5在现代设计师和web开发人员中变得非常受欢迎。其丰富的功能和无滞后的表现在很大程度上提高一个网站的功能和效率。你可以很容易地通过选择一款出色的框架来修改你的网站的界面外观,。毫无疑问,这是微软power
point和keynote的一个完美的web替代品。

因此,看看这些顶级JavaScript和HTML5演示框架,并选择最好的一款,通过这些幻灯片演示框架的帮助来展示你的任务。

1)组合继承

function Mother (age) { this.age = age; this.hobby =
[‘running’,’football’] } Mother.prototype.showAge = function () {
console.log(this.age); }; function Person (name, age) {
Mother.call(this, age);  //第二次执行 this.name = name; }
Person.prototype = new Mother();  //第一次执行
Person.prototype.constructor = Person; Person.prototype.showName =
function () { console.log(this.name); } var p1 = new Person(‘Jack’, 20);
p1.hobby.push(‘basketball’); //p1:’Jack’;
__proto__:20,[‘running’,’football’] var p2 = new Person(‘Mark’,
18); //p2:’Mark’; __proto__:18,[‘running’,’football’]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function Mother (age) {
    this.age = age;
    this.hobby = [‘running’,’football’]
}
Mother.prototype.showAge = function () {
    console.log(this.age);
};
 
function Person (name, age) {
    Mother.call(this, age);  //第二次执行
    this.name = name;
}
Person.prototype = new Mother();  //第一次执行
Person.prototype.constructor = Person;
Person.prototype.showName = function () {
    console.log(this.name);
}
 
var p1 = new Person(‘Jack’, 20);
p1.hobby.push(‘basketball’);  //p1:’Jack’; __proto__:20,[‘running’,’football’]
var p2 = new Person(‘Mark’, 18);  //p2:’Mark’; __proto__:18,[‘running’,’football’]

结果是酱紫的:

图片 10  图片 11

这里第一次执行的时候,得到 Person.prototype.age =
undefined, Person.prototype.hobby =
[‘running’,’football’],第二次执行也就是 var p1 = new Person(‘Jack’,
20) 的时候,得到 p1.age =20, p1.hobby =
[‘running’,’football’],push后就变成了 p1.hobby =
[‘running’,’football’, ‘basketball’]。其实分辨好 this
的变化,理解起来也是比较简单的,把 this 简单替换一下就能得到这个结果了。
如果感觉理解起来比较绕的话,试着把脑子里面的概念扔掉吧,把自己当浏览器从上到下执行一遍代码,结果是不是就出来了呢?

通过第二次执行原型的构造函数
Mother(),我们在对象实例中复制了一份原型的属性,这样就做到了与原型属性的分离独立。细心的你会发现,我们第一次调用
Mother(),好像什么用都没有呢,能不调用他吗?可以,就有了下面的寄生组合式继承。

桌面将成为一级菜单和第一入口

图片 12

实际上在David Gelernter
再次提出互联网时间流这个理论之前,移动互联网在高速发展过程中就已经开始有了类似的趋势。只不过由于其形势并不明显,很多人并没有注意到。本文便是针对移动互联网的这一趋势,来详细聊聊。

在功能机时代,手机上的每个功能是以九宫格的形式存在的,苹果推出iPhone之后,延续了这一特性。同时独立App的形式还能保证其单任务、安全、流畅的特性,所以现在大部分的手机都是打开屏幕,点击一个应用图标,然后进入使用一些功能。

但到了后来,Android后期(4.x之后),移动OS厂商开始将一些功能从应用层提到桌面层,比如iOS的下拉通知、Android
后期的下拉菜单和Widgets。而之后的Windows 8、Windows
Phone以及BlackBerry
10,则开始将更多地信息展示提到桌面层。用户打开手机便可以看到想要的信息,一些天气、IM、图片等信息开始被整合到桌面上。

以微软Win8 之后的Live
Title(动态磁贴)为例,这种形式让我第一次看到了OS厂商将桌面作为以及菜单的决心。虽然很多人认为这样很丑,而且微软也并没有大力宣传他们的这一功能,但以后一旦桌面信息入口成主流,微软便拥有了先发优势。

微软的动态磁贴实际上就是一个个的App
icon的演进,除了显示应用图标和名称,还可以动态展示应用内的数据信息。比如天气软件显示天气数据、日历显示日期或活动、微博显示微博信息、图片应用显示最近上传的图片,以及新闻、股票、视频、邮件、信息等。
由于动态磁贴有1/4、1/2的形式(以后还有更大的),展示的内容最小有1/16(比如人脉app),所以桌面就成了一个很好的信息流平台。虽然目前还不是时间流,只是一个一个的App的独立展示。

BlackBerry 10上的BlackBerry
Hub也是一种信息流形式。从某种意义上讲,它也属于手机桌面的一级菜单中(桌面左滑进入Hub)。BlackBerry
Hub里集成了几乎用户用到的所有信息,包括邮件、BBM、通话、短消息、Twitter、LinkedIn等,而且确实是按照时间流的形式排序的。你左滑手机,便可以查看、回复所有信息,不用再点进入一个一个App查看了

在桌面成为一级菜单和第一入口的同时,Android甚至做出了更大胆的举动。Android的下拉通知栏、Widgets
功能和Google Now让部分信息提到了桌面层,而其锁屏Widget
的发明,则直接将信息提得比桌面更靠前。显而易见,锁屏层级要比桌面更高,你点亮屏幕,不用解锁就能看到信息,这对用户来说显然更加方便。但这样可能也会有一些小问题,而且并不能改变Android仍然是以App为操作入口的现状。

图片 13

当桌面成为一级菜单和第一入口的趋势越来越明显,用户便会慢慢接受互联网时间流的形式,大部分操作都在桌面上进行,手机菜单层级进一步扁平化,App特性被逐渐淡化。除了微软、黑莓,新出来的Firefox、Ubuntu系统可能都会在这方面有更大的空间,而iOS和Android,由于其系统架构过于传统,在互联网信息流浪潮中没有太多优势。

而对于那些争着做移动浏览器来抢占移动互联网入口,甚至有的还在App内做了好几层菜单的厂商,简直就是在搞笑。当大部分用户都习惯用手机来获取信息之后,没人再会去浏览器内使用某项服务,更没人点亮手机、解锁、点击App图标、点击某公共账号、输入“天气”俩字,然后让对方弹出了天气信息。当大家都在手机桌面上看天气、搜索东西的时候,谁还愿意再点击四五层菜单去获取信息啊?!

而这种移动互联网趋势的发展,不仅颠覆了以前人们的信息获取方式,同时也为移动OS厂商、App开发者提供了很多挑战和机遇。

 

1) HTML5 Slides

图片 14

Slides是一款有效的web开发演示框架。由谷歌提供,这款框架提供了一个链接,通过它可以极大容易和舒适地获取模板。大家需要做的就是复制样本幻灯片的代码,并为他们填上新的内容。

2)寄生组合式继承

function object(o){ function F(){} F.prototype = o; return new F(); }
function inheritPrototype(Person, Mother){ var prototype =
object(Mother.prototype); prototype.constructor = Person;
Person.prototype = prototype; } function Mother (age) { this.age = age;
this.hobby = [‘running’,’football’] } Mother.prototype.showAge =
function () { console.log(this.age); }; function Person (name, age) {
Mother.call(this, age); this.name = name; } inheritPrototype(Person,
Mother); Person.prototype.showName = function () {
console.log(this.name); } var p1 = new Person(‘Jack’, 20);
p1.hobby.push(‘basketball’);//p1:’Jack’;
__proto__:20,[‘running’,’football’] var p2 = new Person(‘Mark’,
18); //p2:’Mark’; __proto__:18,[‘running’,’football’]

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
function object(o){
    function F(){}
    F.prototype = o;
    return new F();
}
 
function inheritPrototype(Person, Mother){
    var prototype = object(Mother.prototype);
    prototype.constructor = Person;    
    Person.prototype = prototype;    
}
                        
function Mother (age) {
    this.age = age;
    this.hobby = [‘running’,’football’]
}
Mother.prototype.showAge = function () {
    console.log(this.age);
};
 
function Person (name, age) {
    Mother.call(this, age);
    this.name = name;
}
 
inheritPrototype(Person, Mother);
 
Person.prototype.showName = function () {
    console.log(this.name);
}
 
var p1 = new Person(‘Jack’, 20);
p1.hobby.push(‘basketball’);//p1:’Jack’; __proto__:20,[‘running’,’football’]
var p2 = new Person(‘Mark’, 18); //p2:’Mark’; __proto__:18,[‘running’,’football’]

结果是酱紫的:

图片 15 图片 16

原型中不再有 age 和 hobby 属性了,只有两个方法,正是我们想要的结果!

关键点在于 object(o) 里面,这里借用了一个临时对象来巧妙避免了调用new
Mother(),然后将原型为 o
的新对象实例返回,从而完成了原型链的设置。很绕,对吧,那是因为我们不能直接设置
Person.prototype = Mother.prototype 啊。

移动OS、HTML5 和超级App

当智能终端的桌面成为一级菜单以及信息的第一入口之后,互联网时间流效应开始凸显。人们直接在桌面上读取信息,很少进入App中进行操作,App对人的控制权开始减弱,开始沦为信息背后的提供者,HTML5的这种跨平台信息提供形式开始被消费者和开发者青睐。同时,移动OS的平台性和话语权增强当然,虽然用户仍可以把自己喜欢的信息放在桌面上,但OS厂商可能会对第三方信息服务提供商进行更严格的限制。

移动OS

图片 17

当信息不再局限于App这样的信息孤岛中之后,App开发者为了曝光率,会争相提供桌面甚至锁屏界面兼容。而OS提供商,可能会因为各种原因实施各种限制措施,比如iOS会利用Sandbox、单任务等把App都限制在应用层内,Google
会限制Android 第三方搜索(语音和文字)的使用权限,BlackBerry
Hub让要想接入第三方应用信息需接受批准等。这些措施都会对第三方信息提供商造成不利。

另一方面,移动OS厂商还会大力推广自己的服务,并在出厂时预装自己的服务(大家都知道预装的威力)。Google
会在Android上加入搜索、Gmail、Google Now、Google Plus、Google
Drive、传言中的Google
Babble等,微软会预装Bing、Outlook、Skydrive、Skype等,黑莓、三星、Firefox、Ubuntu都会在ROM中加入自己的服务,更别提国内那些第三方Android
ROM定制厂商了。

HTML5

由于在时间流互联网下,信息都集中到桌面上,导致App使用率下降,而相比之下,HTML5
内容提供方有着更多的优势。Web App
开发成本低、实时在线、无需更新、跨平台,同时兼容性和嵌入性都非常高,所以更方便于在桌面上展示。甚至Web
App要比时间流互联网更快到来,所以如果三五年后时间流互联网成为现实,到时候可能大部分服务都采用HTML5开发。

另一方面,由于智能眼镜、智能手表、智能电视的显示屏幕规格各不相同,HTML5网页的内容展示方式也将更适合这些平台。比如Google
Glass那个很小的屏幕,或者Pebble手表的显示屏,小屏幕只能显示非常少的信息,而HTML5,则可以灵活应对各种情况。至于各屏幕之间有何不同,下一章我们会详细阐述。

超级App

我把“超级App”定义为拥有亿级用户的服务,比如Facebook、Twitter、QQ和微信等。由于这些产品用户量巨大,他们能够左右用户的选择。而且这些产品都有着非常强的马太效应,大家都在用,你就不得不用,导致后期其用户会呈现指数型增长。

对于Facebook、Twitter,一旦他们推出一款深度定制的App(比如Facebook
Home for
Android),只要硬件允许,大家都会去安装使用。甚至如果Facebook把其他Facebook应用下架,那用Facebook的人就不得不去装一个Facebook
Home ,这就很可怕了,因为整个桌面的控制权都在它手里。

除了上面的之外,拥有亿级用户的账号系统也很恐怖。比如Google
的Gmail账户、微软的Outlook账户、苹果账户、Amazon、Facebook
等。很多账户还有绑定了信用卡,一旦他们只允许使用他们账号体系的第三方服务接入桌面,这就很对很多创业者造成一定程度的伤害。

 

2) Reveal.js

图片 18

Reveal.js是一款著名的web开发框架。它创造很棒的幻灯片,可以水平和垂直定位。通过使用它,你可以很容易地为你的演示添加各种效果的完美组合和3
d幻灯片过渡。大量的web开发人员正在使用这款有效并且可靠的框架。

小结


说了这么多,其实核心只有一个:属性共享和独立的控制,当你的对象实例需要独立的属性,所有做法的本质都是在对象实例里面创建属性。若不考虑太多,你大可以在Person里面直接定义你所需要独立的属性来覆盖掉原型的属性。总之,使用原型继承的时候,要对于原型中的属性要特别注意,因为他们都是牵一发而动全身的存在。

下面简单罗列下js中创建对象的各种方法,现在最常用的方法是组合模式,熟悉的同学可以跳过到文章末尾点赞了。

《时间流互联网之未来(下)》

 

赞 收藏 1
评论

图片 19

3) Impress.js

图片 20

另一款有效的框架是Impress.js。这是一款神奇的框架,幻灯片排列在3
d空间,同时定义在“div”元素中,并通过足够的数据属性控制x,y,z的位置和旋转。通过使用它,您可以很容易地设计一些流畅的,惊人的,新颖的幻灯片。

发表评论

电子邮件地址不会被公开。 必填项已用*标注