@hotjp
2016-11-25T14:46:02.000000Z
字数 2114
阅读 1293
培训
Javascript诞生于面向对象编程的火爆时期(1994年),Javascript的开发者也受C++和java的影响。所以Javascript成为一种一切皆对象的语言。
但是,作者认为不需要把一个浏览器端的小型脚本语言写的很复杂,不想写一个带“继承”的语言,但是需要有一个方式把各种对象联系起来。于是,Brendan Eich定义了Javascript的“继承”模式。
接着就是“类”的抉择,有了“继承”和“类”就是一个标准的面向对象的语言,会增加初学者的学习门槛,并且过于正式,所以,Javascript没有“类”的概念。
没有类,如何定义对象?
C++和Java语言都使用new命令,生成实例。
因此,把new命令引入了Javascript,用来从原型对象生成一个实例对象。但是,Javascript没有"类",如何表示原型对象呢?
C++和Java使用new命令时,都会调用"类"的构造函数(constructor)。于是便做了一个简化的设计,在Javascript语言中,new命令后面跟的不是类,而是构造函数。
所以声明一个对象时我们可这样写:
//内置构造函数声明数组对象
var arr = new Array();
//自定义构造函数声明忍者对象
function Ninjia(name,sex){
this.name = name;
this.weapon = 'knife';
this.sex = sex;
}
var ninjia0 = new Ninjia("mike",'boy');
var ninjia1 = new Ninjia("lily",'girl');
通过关键字new
的构造函数中的this
指向实例化之后的对象本身。
但是new
出来的对象无法共享属性和方法。
比如我们的忍者村批量更换了一种制式武器
//我们给mike装备
ninjia0.weapon='sword';
//检查装备
ninjia0.weapon;
ninjia1.weapon;
修改某个实例对象的通用属性不会影响其他实例对象。
批量的修改相同的属性会浪费很多资源对吧?
于是,我们的Javascript作者添加了另一个玩意'prototype'
实例对象一旦创建,将自动引用prototype对象的属性和方法。也就是说,实例对象的属性和方法,分成两种,一种是本地的,另一种是引用的。
//重新定义构造函数
function Ninjia(name,sex){
this.name = name;
this.sex = sex;
}
//定义原型
Ninjia.prototype.weapon = 'knife';
//实例对象
var ninjia0 = new Ninjia("mike",'boy');
var ninjia1 = new Ninjia("lily",'girl');
Ninjia.prototype.weapon = 'sword';
//检查装备
ninjia0.weapon;
ninjia1.weapon;
由于所有的实例对象共享同一个prototype对象,那么看起来,prototype对象就好像是实例对象的原型,而实例对象则好像"继承"了prototype对象一样。
Jacascript支持的链式写法‘原型链’是怎么实现的呢?
我们扩展一下刚才那个Ninjia。
//定义一个主函数
function Ninjia(name,sex){
this.name = name;
this.sex = sex;
}
Ninjia.prototype.hello = function(){
return '你好,我是' + this.name
}
//实例化,让ninjia0继承Ninjia函数的原型
var ninjia0 = new Ninjia("mike",'boy');
//调用原型函数
ninjia0.hello();
现在我们的小忍者会说话打招呼了,那么如何继续把链式结构延续下去?
Ninjia.prototype.weapon = 'knife';
Ninjia.prototype.attack = function(){
return this.name + '向在座的各位发射了一把' + this.weapon
}
//会出错
ninjia0.hello().attack();
//正常
ninjia0.attack();
上面的代码并不能形成链式调用,肿么办
//定义一个主函数
function Ninjia(name,sex){
this.name = name;
this.sex = sex;
}
Ninjia.prototype.hello = function(){
return '你好,我是' + this.name
}
Ninjia.prototype.getWeapon = function(){
this.weapon = 'knife';
return this;
}
Ninjia.prototype.attack = function(){
console.log(this.name + '向在座的各位发射了一把' + this.weapon)
return this;
}
var ninjia0 = new Ninjia("mike",'boy');
ninjia0.getWeapon().attack().hello();