这里有新鲜出炉的 Javascript 教程,程序狗速度看过来!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
文章介绍了代码复用的概念及其原则,已经代码复用的集中类型,非常的详尽,语言简单易懂,有需要的朋友可以参考下
代码复用及其原则
,顾名思义就是对曾经编写过的代码的一部分甚至全部重新加以利用,从而构建新的程序。在谈及代码复用的时候,我们首先可以想到的是
- 代码复用
。代码复用的原则是:
- 继承性
- 优先使用对象组合,而不是类继承
在 js 中,由于没有类的概念,因此实例的概念也就没多大意义,js 中的对象是简单的键 - 值对,可以动态的创建和修改它们。
但在
中,我们可以使用构造函数和
- js
操作符来实例化一个对象,这与其他使用类的编程语言在语法上有其相似之处。
- new
例如:
- var trigkit4 = new Person();
在调用构造函数
- js
时似乎看起来是一个类,但其实际上仍然是一个函数,这让我们产生了一些假定在类的基础上的开发思路和继承模式,我们可以称之为 "类式继承模式"。
- Person
传统的继承模式是需要
关键字的,我们假定以上的类式继承模式为
- class
,这是一种不需要以类的方式考虑的模式。
- 现代继承模式
类式继承模式
看下面两个构造函数
和
- Parent()
的例子:
- Child()
- function Parent(name) { this.name = name || 'Allen';
- } Parent.prototype.say = function() {
- return this.name;
- }
- function Child(name) {} //用Parent构造函数创建一个对象,并将该对象赋值给Child原型以实现继承 function inherit(C,P){ C.prototype = new P();//原型属性应该指向一个对象,而不是函数 } //调用声明的继承函数 inherit(Child,Parent);
当使用
语句创建一个对象时,它会通过原型从
- new Child()
实例获取它的功能,比如:
- Parent()
- var kid = new Child();
- kid.say();
- //Allen
原型链
讨论一下类式继承模式下原型链的工作原理,我们将对象看做是内存中某处的块,该内存块包含数据以及指向其他块的引用。当用
语句创建一个对象时,就会创建如下图左边的这样一个块,这个块保存了
- new Parent()
属性,如果想访问
- name
方法,我们可以通过指向构造函数
- say()
的
- Parent()
(原型)属性的隐式链接
- prototype
,便可访问右边区块
- __proto__
。
- Parent.prototype
那么,当使用
创建新对象时会发生什么?如下图:
- var kid = new Child()
使用
语句所创建的对象除了隐式链接
- new Child()
外,它几乎是空的。这种情况下,
- __proto__
指向了在
- __proto__
函数中使用
- inherit()
语句所创建的对象
- new Parent()
当执行
时,由于最左下角的区块对象并没有
- kid.say()
方法,因此他将通过原型链查询中间的区块对象,然而,中间的区块对象也没有
- say()
方法,因此他又顺着原型链查询到最右边的区块对象,而该对象正好有
- say()
方法。完了吗?
- say()
执行到这里的时候并没有完,在
方法中引用了
- say()
,this 指向构造函数所创建的对象,在这里,它指向了
- this.name
这个区块,然而,
- new Child()
中并没有
- new Child()
属性,为此,将查询中间区块,而中间区块正好有
- name
属性,至此,原型链的查询完毕。
- name
更详细的讨论请查看我这篇文章:javascript 学习笔记(五)原型和原型链详解
共享原型
本模式的法则在于:可复用的成员应该转移到原型中而不是放置在 this 中。因此,处于继承的目的,任何值得继承的东西都应该放在原型中实现。所以,可以将子对象的原型与父对象的原型设置为相同即可,如下示例所示:
- function inherit(C, P) { C.prototype = P.prototype;
- }
子对象和父对象共享同一个原型,并且可以同等的访问
方法。然而,子对象并没有继承
- say()
属性
- name
原型继承
原型继承是一种 "现代" 无类继承模式。看如下实例:
- //要继承的对象 var parent = { name : "Jack" //这里不能有分号哦 };
- //新对象 var child = Object(parent);
- alert(child.name); //Jack
在原型模式中,并不需要使用对象字面量来创建父对象。如下代码所示,可以使用构造函数来创建父对象,这样做的话,自身的属性和构造函数的原型的属性都将被继承。
- //父构造函数 function Person(){ this.name = "trigkit4"; } //添加到原型的属性 Person.prototype.getName = function(){ return this.name; }; //创建一个新的Person类对象 var obj = new Person(); //继承 var kid = Object(obj); alert(kid.getName());//trigkit4
本模式中,可以选择仅继承现有构造函数的原型对象。对象继承自对象,而不论父对象是如何创建的,如下实例:
- //父构造函数 function Person(){ this.name = "trigkit4"; } //添加到原型的属性 Person.prototype.getName = function(){ return this.name; }; //创建一个新的Person类对象 var obj = new Person(); //继承 var kid = Object(Person.prototype); console.log(typeof kid.getName);//function,因为它在原型中 console.log(typeof kid.name);//undefined,因为只有该原型是继承的
来源: http://www.phperz.com/article/17/0418/274394.html