频道栏目
首页 > 资讯 > JavaScript > 正文

js中创建对象的模式与继承及js函数私有变量

17-09-13        来源:[db:作者]  
收藏   我要投稿

直接上代码,详见代码注释。

下面的代码是在sublime text3上编辑在nodejs上运行过的。

【创建对象】

//创建对象
//组合使用构造函数模式(定义实例属性)和原型模式(定义方法、constructor)
function Person_1(name,age,job){
	this.name=name;
	this.age=age;
	this.job=job;
	this.friends=['Shelby','Court'];
}
Person_1.prototype={
	sayName:function(){
		console.log(this.name);
	}
}
Object.defineProperty(Person_1.prototype,'constructor',{
	enumerable:false,
	value:Person_1
});
var person=new Person_1('Nick',20,'Software Engineer');
person.sayName();//Nick
		
//动态原型模式(所有信息封装在构造函数中)
function Person_2(name,age,job){
	this.name=name;
	this.age=age;
	this.job=job;
	this.friends=['Shelby','Court'];
	//if这段代码只有在初次调用构造函数时才会执行
	if(typeof this.sayName !='function'){
		Person_2.prototype.sayName=function(){console.log(this.name);};
	}
}
var person=new Person_2('Nick',20,'Software Engineer');
person.sayName();//Nick
console.log('------------------------------------');

【继承】

//继承
//实现继承的本质是重写原型对象,代之以一个新类型的实例
//确定原型和实例的关系的方法:1、instanceof操作符 2、isPrototypeOf()
function SuperType_1(){
	this.superproterty=true;
}
SuperType_1.prototype.getSuperValue=function(){
	return this.superproterty;
}
function SubType_1(){
	this.subproperty=false;
}
//继承了SuperType_1
SubType_1.prototype=new SuperType_1();
SubType_1.prototype.getSubValue=function(){
	return this.subproperty;
}
var instance=new SubType_1();
console.log(instance.getSuperValue());//true

console.log(instance instanceof Object);//true
console.log(instance instanceof SuperType_1);//true
console.log(instance instanceof SubType_1);//true
console.log(Object.prototype.isPrototypeOf(instance));//true
console.log(SubType_1.prototype.isPrototypeOf(instance));//true
console.log(SuperType_1.prototype.isPrototypeOf(instance));//true
console.log('------------------------------------');
//借用构造函数/伪造对象/经典继承
//在子类构造函数内部调用超类构造函数,使用apply()、call()
//即使超类中有引用类型的属性,也会在子类创建一个副本
function SuperType_2(){
	this.colors=['red','blue','green'];
}
function SubType_2(){
	//继承了SuperType_2
	SuperType_2.call(this);
}
var instance1=new SubType_2();
instance1.colors.push('black');
console.log(instance1.colors);//[ 'red', 'blue', 'green', 'black' ]
var instance2=new SubType_2();
console.log(instance2.colors);//[ 'red', 'blue', 'green' ]

console.log(instance1 instanceof Object);//true
console.log(instance1 instanceof SuperType_2);//false
console.log(instance1 instanceof SubType_2);//true
console.log(Object.prototype.isPrototypeOf(instance1));//true
console.log(SubType_2.prototype.isPrototypeOf(instance1));//true
console.log(SuperType_2.prototype.isPrototypeOf(instance1));//false
console.log('------------------------------------');
//组合继承/伪经典继承
//使用原型链实现对原型属性和方法的继承
//通过构造函数实现对实例属性的继承
//两次调用SuperType_3()
function SuperType_3(name){
	this.name=name;
	this.colors=['red','blue','green'];
}
SuperType_3.prototype.sayName=function(){
	console.log(this.name);
};
function SubType_3(name,age){
	//继承属性
	SuperType_3.call(this,name);//二次调用SuperType_3()
	this.age=age;
}
//继承方法
SubType_3.prototype=new SuperType_3();//一次调用SuperType_3()
SubType_3.prototype.constructor=SubType_3;
SubType_3.prototype.sayAge=function(){
	console.log(this.age);
};

var instance3=new SubType_3('Nicholas',29);
instance3.colors.push('brown');
console.log(instance3.colors);//[ 'red', 'blue', 'green', 'brown' ]
instance3.sayAge();//29
instance3.sayName();//Nicholas

var instance4=new SubType_3('Greg',27);
console.log(instance4.colors);//[ 'red', 'blue', 'green' ]
instance4.sayName();//Greg
instance4.sayAge();//27

console.log(instance4 instanceof Object);//true
console.log(instance4 instanceof SuperType_3);//true
console.log(instance4 instanceof SubType_3);//true
console.log(Object.prototype.isPrototypeOf(instance4));//true
console.log(SubType_3.prototype.isPrototypeOf(instance4));//true
console.log(SuperType_3.prototype.isPrototypeOf(instance4));//true
console.log('------------------------------------');
//原型继承
//ECMAScript5增加了Object.create()方法,接收两个参数(用于创建副本的基本对象,可选的为新对象定义额外属性的对象)
//IE 9+、Firefox 4+、Safari 5+、Opera 12+、Chrome
//只想让一个对象与另一个对象保持类似的情况下,原型继承可行
var person={
	name:'Nicholas',
	friends:['a','b','c']
};

var aperson=Object.create(person);
aperson.name='Greg';
aperson.friends.push('d');

var anotherperson=Object.create(person,{name:{value:'ccc'}});

console.log(person.friends);//[ 'a', 'b', 'c', 'd' ]
console.log(anotherperson.name);//ccc
console.log(anotherperson.friends);//[ 'a', 'b', 'c', 'd' ]
console.log('------------------------------------');
//寄生式继承
//任何能够返回新对象的函数都适用
//为对象添加函数会因为不能做到函数复用而降低效率
function object(o){
	function F(){}
	F.prototype=o;
	//原型指向o,所以对其原型的任何更改也会反映到o上
	return new F();
}
function createAnother(originaobj){
	var clone=object(originaobj);
	clone.sayHi=function(){
		console.log('hi');
	};
	return clone;
}
var person={
	name:'Nicholas',
	friends:['a','b','c']
};
var yetAnotherPerson=createAnother(person);
yetAnotherPerson.sayHi();//hi
console.log('------------------------------------');
//寄生组合式继承
//解决两次调用的问题
//引用类型最理想的继承范式
function inheritPrototype(SubType,SuperType){
	var prototype=Object(SuperType.prototype);//创建超类原型副本
	prototype.constructor=SubType;
	SubType.prototype=prototype;//代替了前面的第一次调用SuperType()
}
function SuperType(name){
	this.name=name;
	this.colors=['red','blue','green'];
}
SuperType.prototype.sayName=function(){
	console.log(this.name);
};
function SubType(name,age){
	//继承属性
	SuperType.call(this,name);//二次调用SuperType()
	this.age=age;
}
inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge=function(){
	console.log(this.age);
}
var instance5=new SubType('Nicholas',29);
instance5.colors.push('brown');
console.log(instance5.colors);//[ 'red', 'blue', 'green', 'brown' ]
instance5.sayAge();//29
instance5.sayName();//Nicholas

var instance6=new SubType('Greg',27);
console.log(instance6.colors);//[ 'red', 'blue', 'green' ]
instance6.sayName();//Greg
instance6.sayAge();//27

console.log(instance6 instanceof Object);//true
console.log(instance6 instanceof SuperType);//true
console.log(instance6 instanceof SubType);//true
console.log(Object.prototype.isPrototypeOf(instance6));//true
console.log(SubType.prototype.isPrototypeOf(instance6));//true
console.log(SuperType.prototype.isPrototypeOf(instance6));//true
console.log('------------------------------------');


【js中实现块级作用域】

//ECMAScript中不存在块级作用域
var count=10;
for (var i = 0; i < count; i++) {
	console.log(i);
}//循环输出0-9
console.log(i);//仍然可以访问到i为10


if(true){
	var c=1;
}
console.log(c);//可以访问到if语句内定义的c为1


function add(num1,num2){
	var sum =num1+num2;
	return sum;
}
var result=add(10,20);
//console.log(sum);会报错,找不到sum


var color='blue';
function getColor(){
	var color='red';
	return color;
}
console.log(getColor());//red
console.log(color);//blue


//匿名函数可以用来模仿块级作用域
(function(){
	var count=10;
	for (var j = 0; j < count; j++) {
		console.log(j);
	}
})();
//console.log(j);//j is not defined
//function(){}();会报错
//因为js将function关键字当做函数声明的开始,函数声明后不能跟()
//所以要给(function(){})加上括号转换成函数表达式
【js函数私有变量】

//静态私有变量
(function(){
	//私有变量和方法
	var privateVariable='';

	function privateFunction(){
		return false;
	}

	//构造函数
	//创建一个全局变量
	Person_3=function(value){
		privateVariable=value;
	};

	Person_3.prototype.getValue=function(){
		return privateVariable;
	}

	Person_3.prototype.setValue=function(value){
		privateVariable=value;
	}
})();
var a=new Person_3('Nick');
console.log(a.getValue());//Nick
a.setValue('Greg');
console.log(a.getValue()); //Greg
var b=new Person_3('Mike');
console.log(b.getValue());//Mike
console.log(a.getValue());//Mike
//这种方式创建静态私有变量会因为使用原型而增进代码复印,但是每个实例都是共享私有变量和函数的
console.log('------------------------------------');

//模块模式
//单例:只有一个实例的对象
//如果必须创建一个对象并以某些数据进行初始化,同时公开访问私有变量的接口
//以这种模式创建的每个单例都是Object(以函数返回的字面量形式创建的Object实例)
var application=function(){
	var components=new Array();

	//初始化,向数组推进一个实例对象
	components.push(new Object());

	return{
		getComponetCount:function(){
			return components.length;
		},
		registerComponet:function(component){
			if(typeof component=='object'){
				components.push(component);
			}
		}
	};
}();
//增强的模块模式
//适合那些单例必须是某种类型的实例
var application=function(){
	var privateVariable=10;
	function privateFunc(){
		return true;
	}

	var returnobj=new String();

	returnobj.publicProperty=false;
	returnobj.publicMethod=function(){
		privateVariable++;
		return privateFunc();
	};

	return returnobj;
}();
console.log('------------------------------------');
相关TAG标签
上一篇:[C++::STL]之map的用法
下一篇:腾讯OMG前端
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站