Javascript也是面向对象的语言,但它是一种基于原型Prototype的语言,而不是基于类的语言。在Javascript中,类和对象看起来没有太多的区别。

什么是prototype:

function定义的对象有一个prototype属性,prototype属性又指向了一个prototype对象,注意prototype属性与prototype对象是两个不同的东西,要注意区别。在prototype对象中又有一个constructor属性,这个constructor属性同样指向一个constructor对象,而这个constructor对象恰恰就是这个function函数本身。 是不是很绕?用伪代码表示如下:

1
2
3
4
5
var function{
prototype:prototype{
constructor:constructor == function
}
}

还不明白?看图吧:

prototype的作用:

这个prototype到底有什么作用呢?看下面的例子:

1
2
3
4
5
function jb51(){
}
jb51.prototype.name = "a";
var test = new jb51();
alert(test.name)//"a";

奇怪吧,明明没有为test设置name属性,可是为什么会有值?

这就是prototype的功劳了,uw3c中prototype属性中的name对象,在uw3c被new构造函数之后,被继承到了对象test的属性中。接着看:

1
2
3
4
5
6
7
var name = "js";
function jb51(name){
alert(this.name);//"css"
}
jb51.prototype.name = "css";
var test = new jb51();
test()

为什么alert的值不是“js”?这个过程大致如下:

1
2
var test={};
uw3c.call(test);

第一步是建立一个新对象(test)。

第二步将该对象(test)内置的原型对象设置为构造函数(就是uw3c)prototype 属性引用的那个原型对象。

第三步就是将该对象(test)作为this 参数调用构造函数(就是uw3c),完成成员设置等初始化工作。

其中第二步中出现了一个新名词就是内置的原型对象,注意这个新名词跟prototype对象不是一回事,
为了区别我叫它inobj,inobj就指向了函数uw3c的prototype对象。在uw3c的prototype对象中出现的任何属性或者函数都可以在test对象中直接使用,这个就是JS中的原型继承了。

通常,这样创建一个对象:

1
2
3
4
5
6
7
8
function person(name){
this.sayHi = function(){
alert('hi ' + this.name);
}
this.name = name;
}
var p = new person("dan");
p.sayHi();

以上,使用new关键字,通过对象(函数也是特殊对象)创建一个对象实例。

在基于类的语言中,属性或字段通常都是在类中事先定义好了,但在Javascript中,在创建对象之后还可以为类添加字段。

1
2
3
function animal(){}
var cat = new animal();
cat.color = "green";

以上,color这个字段只属于当前的cat实例。
对于后加的字段,如果想让animal的所有实例都拥有呢?

1
2
3
4
5
6
7
--使用Prototype
function animal(){}
animal.prototype.color= "green";
var cat = new animal();
var dog = new animal();
console.log(cat.color);//green
console.log(dog.color);//green

通过Prototype不仅可以添加字段,还可以添加方法。

1
2
3
4
5
6
7
8
9
10
function animal(){}
animal.prototype.color= "green";
var cat = new animal();
var dog = new animal();
console.log(cat.color);//green
console.log(dog.color);//green
animal.prototype.run = funciton(){
console.log("run");
}
dog.run();

原来通过prototype属性,在创建对象之后还可以改变对象的行为。
比如,可以为数组这个特殊对象添加一个方法。

1
2
3
4
5
6
7
8
Array.prototype.remove = function(elem){
var index = this.indexof(elem);
if(index >= 0){
this.splice(index, 1);
}
}
var arr = [1, 2, 3] ;
arr.remove(2);

除了通过prototype为对象定义属性或方法,还可以通过对象的构造函数来定义类的属性或方法。

1
2
3
4
5
6
7
8
function animal(){
this.color = "green";
this.run = function(){
console.log("run");
}
}
var mouse = new animal();
mouse.run();

以上做法的也可以让所有的animal实例共享所有的字段和方法。并且还有一个好处是可以在构造函数中使用类的局部变量。

1
2
3
4
5
6
7
8
9
10
11
function animal(){
var runAlready = false;
this.color = "green";
this.run = funciton(){
if(!runAlreadh){
console.log("start running");
} else {
console.log("already running")
}
}
}

其实,一个更加实际的做法是把通过构造函数结合通过prototype定义一个类的字段和行为。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function animal(){
var runAlready = false;
this.run = function(){
if(!runAlready){
console.log('i am running');
} else {
console.log("i am already running");
}
}
}
animal.prototype.color = '';
animal.prototype.hide = funciton(){
console.log("");
}
var horse = new animal();
horse.run();
horse.hide();

Prototype允许我们在创建对象之后来改变对象或类的行为,并且这些通过prototype属性添加的字段或方法所有对象实例是共享的。

来自:http://www.jb51.net/article/79549.htm

最新文章

  1. Ubuntu 15.1 unity在顶部面板显示系统CPU/内存/网络速度
  2. BUG级别定义标准
  3. PHPCMS修改管理栏目下的模版设置的注意
  4. 一致性hash算法简介与代码实现
  5. MVVM(Model-View-View-Model)简单分析(及代码示例)
  6. 转学步园:jquery offset
  7. HTML5的本地存储 LocalStorage
  8. DTD - XML Building Blocks
  9. HashMap,TreeMap,LinkedHashMap学习
  10. java学习之即时通信项目实战
  11. mysql语句在node.js中的写法
  12. Linux netstat订购具体解释
  13. socket通信的json数据传输与获取
  14. Java之JMX 详解
  15. 运行Chromium浏览器缺少google api密钥无法登录谷歌账号的解决办法
  16. 客户端 未登录页面 (clearfix 分割线)
  17. easyui datagrid 后台返回所有数据,前台分页
  18. 使用Git Subtree在多个项目中共用同一个子项目
  19. sanchi
  20. learning makefile 定义命令包

热门文章

  1. C++_异常7-exception类
  2. 最小生成树----prim算法的堆优化
  3. js去掉浏览器右键点击默认事件(+vue项目开启右键行为)
  4. [转] 利用shell创建文本菜单与窗口部件的方法
  5. 建立ionic3的环境
  6. 一种简单快速的模板解析方法,活用with javascript版
  7. Q686 重复叠加字符串匹配
  8. CentOS-pam认证机制简介
  9. 2.5 Go错误处理
  10. Linux——文件和文件夹的操作