经常会有下边三种形式

JavaScript未有类的概念,但差相当少所有事物又是基于对象的,同不平日间也能兑现持续,那就是js跟其余OOP语言最大的分裂之处,那也是js最难掌握的一块。上边作者来讲说自家个人的领悟。

先是从创建对象说到,平常会有下边二种办法:

1.创设叁个Object实例,然后给它增加属性和措施。

var person() = new Object();
person.name = 'mikej';
person.sayName = function(){
  alert(this.name);
}

2.也得以这么写:

var parson = {
  name : 'mikej',
  sayName : function(){
    alert(this.name);
  }
}

3.这三种创立对象的艺术很简短,但都有欠缺,使用同一个方式创立对象的时候,会时有发生大量双重代码。于是就有了工厂方式:

function createPerson(name){
  var p = new Object();
  p.name=name;
  p.sayName = function(){
    alert(this.name);
  };
  return p;
}
var p1 = createPerson('mikej');
var p2 = createPerson('tom');

如此那般就足以无限成立对象了。

4.还也有大器晚成种艺术,跟工厂情势不谋而合,叫做布局函数情势:

function Person(name){
  this.name=name
  this.sayName = function(){
   alert(this.name);
  }
  this.say = function(){
    alert('hi');
  }
}
var p1 = new Person('mikej');
var p2 = new Person('tom');

此处有多少个值得关切的地点:未有展现的创立对象、函数名Person使用的是大写字母P(那是必需的)、p1和p第22中学都有二个constructor(构造函数)属性,指向Person。同期p1和p2既是Object的实例,也是Person的实例。

alert(p1.constructor == Person); //true
alert(p1 instanceof Object); //true
alert(p1 instanceof Person); //true

//5.11更新:以多少个phper的角度看的话,在此以前超轻巧将创立对象的流水生产线想成那样,Person就是一个“类”,然后用new Person('mikej')实例化了那一个类,而且传入参数。但实质上并非如此的,创造的流水生产线应该是这般:首先,创立三个空对象,然后用apply方法,首个参数是以此空对象,第叁个参数是上下文的参数,这样Person中的this就能够指向这些目的,也正是p1。

var p1 = new Person('mikej');
//上面代码就相当于
var p1 = {};
Person.apply(p1, ['mikej']);

布局函数方式看上去很好,可是它有两个缺欠就是浪费内部存款和储蓄器,接上例

alert(p1.say == p2.say) //false

.为了幸免这么些毛病,但是使用原型情势来创造对象,js中的每一个对象都有二个prototype属性用来针对别的贰个对象,这一个目的的富有属性和方法都会被布局函数的实例世襲,是分享的,那就表示,大家能够把那多少个不变的性情和措施,定义到prototype对象上。

function Person(name){
  this.name = name;
}
//Person的原型对象
Person.prototype = {
  say: function(){
    alert('hi');
  },
  sayName: function(){
    alert(this.name);
  }
};
var p1 = new Person("mikej");
var p2 = new Person("tom");
p1.sayName();
p2.sayName();
//下面就可以看出方法实现了共享
alert(P1.say == P2.say) //true
alert(P1.sayName == P2.sayName) //true

再来扩张一下地点的例证,使用原型来兑现接二连三。

function Person(name){
  this.name = name;
}

Person.prototype = {
  say: function(){
    alert('hi');
  },
  sayName: function(){
    alert(this.name);
  }
};

function Programmer(){
  this.say = function(){
    alert('im Programmer, my name is ' + this.name);
  }
}

Programmer.prototype = new Person('mikej');
//手动修正构造函数
Programmer.prototype.constructor = Programmer;
var p1 = new Programmer();

console.dir(Programmer.prototype.constructor);//Programmer
console.dir(p1.constructor);//Programmer
console.dir(p1);

Programmer的原型指向了Person的二个实例,那么全部的Programmer的实例都能世袭Person和Person的原型了。

此地会有多个主题材料。

私下认可原型对象里有贰个constructor属性,指向它的布局函数。而每二个实例也是有三个constructor属性,会私下认可调用prototype对象的constructor属性。

借使未有Programmer.prototype = new Person('mikej');

Programmer.prototype.constructor是指向Programmer的。p1的组织也本着Programmer

alert(Programmer.prototype.constructor == Programmer) //true
alert(p1.constructor == Programmer) //true

但有了这句Programmer.prototype = new Person('mikej');之后,

Programmer.prototype.constructor就本着了Object,也正是Person.prototype指向的对象的协会。p1.constructor也针对了Object。但p1明明是布局函数Programmer生成的,那就招致了继续的絮乱,所以大家必须手动校勘布局函数,也便是底下那代码。

Programmer.prototype.constructor = Programmer;

好了,以往大家再来看看原型链:

console.dir(p1);

那句代码的结果是

图片 1

能够见见,p1是Programmer的实例,Programmer的原型是Person,Person的原型是Object,再网络就是JS的对象了。那就是原型链,也正是说,JavaScript的世袭是基于原型链来实现的。

相关文章

发表评论

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

*
*
Website