var colors = {
//...
};
复制代码
function Person(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function (){
console.log(this.name);
}
return o;
};
var person1 = Person('李雪峰','26','web前端开发');
var person2 = Person('hq','25','摄影师');
复制代码
function Animal(name,color){
this.name = name;
this.color = color;
thia.sayName = function(){
console.log(this.name);
}
}
var dog = new Animal('旺财','黑色')
var dog2 = new Animal('阿拉斯加','黑白相间')
复制代码
function Animal(){};
Animal.prototype.name = "旺财";
Animal.prototype.age = 3;
Animal.prototype.sayName = function(){
console.log(this.name);
};
var dog = new Animal();
dog.sayName(); //旺财
var dog2 = new Animal();
dog2.sayName(); //旺财
console.log(dog.sayName === dog2.sayName) //true
复制代码
function Animal(name,age,color){
this.name = name;
this.age = age;
this.color = color;
this.friends = ['旺旺','旺财','二哈']
}
Animal.prototype.sayName = function(){
console.log('狗狗的名字叫:'+this.name);
}
var dog = new Animal('二狗子','3','黑色');
dog.friends.push('陈二狗'); //陈二狗被黑的最惨的一次
console.log(dog.friends)
console.log(dog.sayName())
var dog2 = new Animal('狗腿子','10','五光十色');
dog2.friends.push('走狗');
console.log(dog2.friends);
console.log(dog2.sayName())
console.log(dog.friends == dog2.friends) //false
console.log(dog.sayName == dog2.sayName) //true
复制代码
function Person(name,age,job){
//属性
this.name = name;
this.age = age;
this.job = job;
//方法
if(typeof this.sayName != 'function'){
Person.prototype.sayName = function(){
console.log(this.name);
}
}
}
var friend = new Person('李雪峰','26','web前端开发');
friend.sayName();
复制代码
function Person(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
console.log(this.name);
}
return o;
}
// 比工厂模式多了个new调用, 而且把Person叫作了构造函数
var friend = new Person('李学峰','26','web前端开发');
friend.sayName();
// 应用
function SpecialArray(){
//建立数组
var values = new Array();
//添加值
values.push.apply(values,arguments);
//添加方法
values.toPipedString = function(){
return this.join('||');
};
//返回数组
return values;
}
var colors = new SpecialArray('red','pink','orange','blue');
console.log(colors.toPipedString()); //red||pink||orange||blue
复制代码
- 变量Person中保存的是一个稳妥对象,而除了调用sayName()
- 没有别的方式能够访问其数据成员.
function Person(name,age,job){
// 建立要返回的对象
var o = new Object();
//能够在这里定义私有变量和函数
o.sayName = function(){
console.log(name);
}
return o;
}
var friend = Person('lxf','111','web');
friend.sayName();
复制代码
原型链的概念: 其基本思想是利用原型让一个引用类型继承另外一个引用类型的属性和方法前端
这里要先说一下: 构造函数/原型/实例的关系web
每一个构造函数都有一个
原型对象
,原型对象都包含一个指向构造函数的指针 constructor
,而实例
都包含一个指向原型对象的内部指针[[proto]](__proto__)
.数组
假如咱们让
原型对象
等于另外一个类型的实例
,结果就是,此时的原型对象
将包含一个指向另外一个另外一个原型的指针
bash
假如另外一个
原型
又是另外一个类型
的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条
. 这就是所谓原型链的基本概念app
//实现一个原型链
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
}
function SubType(){
this.subproperty = false;
}
//继承了SuperType --> 一个函数的原型对象等于一个类型(函数)的实例
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function(){
return this.subproperty;
}
var instance = new SubType();
console.log(instance.getSuperValue)
复制代码
instance.constructor
如今指向的是 SuperType
,这是由于原来 SubType.prototype 中的constructor 被重写
的缘故实际上
,不是SubType的原型的 constructor 属性被重写了,而是 SubType 的原型指向了另外一个对象 SuperType 的原型
,而这个原型对象的 constructor 属性指向的是 SuperType引用红宝书中的图片说明函数
经过实现原型链,本质上扩展了前面介绍的原型搜索机制,
当以读取模式访问一个实例属性时
首先会在实例
中搜索该属性.测试
若是,没有找到该属性,则会继续搜索实例的原型.ui
在经过原型链实现继承的状况下,搜索过程就得沿着
原型链继续向上
.this
上边的例子中的搜索顺序spa
引用红宝书中的图片说明
肯定原型和实例的关系
第一种:
instanceof
操做符这个操做符来测试实例与原型中出现过的构造函数,结果就会返回true
console.log(instance instanceof Object); //true
console.log(instance instanceof SubType); //true
console.log(instance instanceof SuperType); //true
复制代码
因为原型链的关系,能够输 instance 是 Object | SuperType | SubType 中任何类型的实例
第二种:
isPrototypeOf()方法
一样,只要是
原型链中出现过的原型
,均可以说是该原型链所派生的实例的原型
console.log(Object.isPrototypeOf(instance)); // true
console.log(SuperType.isPrototypeOf(instance)); // true
console.log(SubType.isPrototypeOf(instance)); // true
复制代码
原型链的问题
function SuperType(nane){
this.name = name;
this.colors = ['red','pink','orange','green'];
}
function SubType(nane,age){
SuperType.call(this); // 不传递参数的状况
//SuperType.call(this,name); //传递参数
//SuperType.apply(this,arguments); // 传递参数
// 实例属性
this.age = age;
}
var instance1 = new SubType();
instance1.colors.push('blue');
console.log(instance1.colors);
var instance2 = new SubType();
console.log(instance2.colors)
复制代码
方法都在构造函数中定义,一次函数复用就无从谈起.
function SuperType(name){
this.name = name;
this.colors = ['red','blue','pink'];
}
SuperType.prototype.sayName = function(){
console.log(this.name);
}
function SubType(name,age){
SuperType.call(this,name); //继承实例属性
this.age = age;
}
SubType.prototype = new SuperType(); //继承方法
SubType.prototype.constructor = SubType; // 构造函数回指
SubType.prototype.sayAge = function (){
console.log(this.age);
}
var instane1 = new SubType('lixuefeng','26');
instane1.colors.push('green','222');
console.log(instane1.sayName())
console.log(instane1.sayAge())
console.log(instane1.colors)
var instane2 = new SubType('zhangyu','23');
instane2.colors.push('122','#fff');
console.log(instane2.sayName())
console.log(instane2.sayAge())
console.log(instane2.colors)
复制代码
组合继承避免了原型链和借用构造函数的缺陷,融合了他们的优势,
instanceof
和isPrototypeOf()
也可以用于识别组合继承建立的对象
function object(o){
function F(){};
F.prototype = o;
return new F();
}
// 应用
var person = {
name : 'lixuefeng',
friends:['red','pink','blue']
};
var anotherPerson = object(person);
anotherPerson.name = 'Greg';
anotherPerson.friends.push('Rob');
var yetAnotherPerson = object(person);
yetAnotherPerson.name = '你你你';
yetAnotherPerson.friends.push('#fff');
console.log(person.friends)
复制代码
Object.create()
方法规范化了原型式继承.Object.create()
与object()
方法的行为相同一个参数的时候
var person = {
name : 'lixuefeng',
friends:['red','pink','blue']
};
var anotherPerson = Object.create(person);
anotherPerson.name = 'Greg';
anotherPerson.friends.push('Rob');
var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = '你你你';
yetAnotherPerson.friends.push('#fff');
console.log(person.friends)
复制代码
两个个参数的时候
var person = {
name : 'lixuefeng',
friends:['red','pink','blue']
};
var anotherPerson = Object.create(person,{
name:{
value:'<<离人愁>> ==> 李元杰'
}
});
console.log(anotherPerson.name)
复制代码
function createAnother(original){
var clone = Object.create(original); // 经过调用函数建立一个新对象 返回一个传入对象的新的实例赋值给 clone
clone.sayHi = function(){ // 以某种方式来加强这个对象
console.log('hi');
};
return clone; // 返回这个对象
}
var person = {
name : 'xxname',
friends:['red','blue','van']
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi(); // hi
anotherPerson.friends.push('11','sss')
console.log(anotherPerson.friends)
console.log(anotherPerson.name)
复制代码
function SuperType(name){
this.name = name;
this.colors = ['red','blue','pink','orange'];
}
SuperType.prototype.sayName = function(){
console.log(this.name);
}
function SubType(name,age){
SuperType.call(this,name); // 这里调用一次 SuperType()
//SuperType.apply(this,arguments)
this.age = age;
}
SubType.prototype = new SuperType(); // 这里调用一次 SuperType()
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function (){
console.log(this.age);
}
var instance =new SubType('小明','100');
instance.colors.push('#333');
console.log(instance.sayName());
console.log(instance.sayAge());
console.log(instance.colors);
var instance2 = new SubType('小蓝','122312');
instance2.colors.push('#fff','#ff0000');
console.log(instance2.sayName());
console.log(instance2.sayAge());
console.log(instance2.colors);
复制代码
在第一次调用 SuperType
构造函数时,SubType.prototype
会获得两个属性:
SuperType
的实例属性,只不过如今位于 SubType
的原型中当调用SubType构造函数时,又会调用一次 SuperType构造函数,这一次又在新对象上建立了实例属性 name
和 colors
因而,这两个属性就屏蔽了原型中的两个同名属性
寄生构造模式能够解决这个问题
function inheritPrototype(subType,superType){
var prototype = Object.create(superType.prototype); // 建立对象
prototype.constructor = subType; // 加强对象
subType.prototype = prototype; // 指定对象
}
function SuperType(name){
this.name = name;
this.colors = ['red','blue','pink','orange'];
}
SuperType.prototype.sayName = function(){
console.log(this.name);
}
function SubType(name,age){
SuperType.call(this,name); // 这里调用一次 SuperType()
//SuperType.apply(this,arguments)
this.age = age;
}
//SubType.prototype = new SuperType(); // 这里调用一次 SuperType()
//SubType.prototype.constructor = SubType;
inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge = function (){
console.log(this.age);
}
var instance =new SubType('小明','100');
instance.colors.push('#333');
console.log(instance.sayName());
console.log(instance.sayAge());
console.log(instance.colors);
var instance2 = new SubType('小蓝','122312');
instance2.colors.push('#fff','#ff0000');
console.log(instance2.sayName());
console.log(instance2.sayAge());
console.log(instance2.colors);
复制代码
这个例子只调用了一次
SuperType
构造函数,而且所以避免了在SubType.prototype
上面建立没必要要的,多余的属性。于此同时,原型链还能保持不变。
所以,还可以正常使用
instanceof
和isPrototypeOf()
寄生组合式继承是引用类型最理想的继承范式
记录理解,有不对的地方,欢迎指出
有趣好玩Games
推荐一些有趣好玩的小游戏手机游戏等