JavaScript中的创建对象方式


-----看了好多的资料,整理一下,加上自己的理解,希望看见的人有什么问题,请多多指教!

对象定义:无序属性的集合,其属性可以包含基本值、对象、函数。严格来讲,对象是一组没有特定顺序的值,也可以理解为散列表,无非就是一组名值对,其中值可以是数据或函数。
首先,用对象字面量的方法创建对象:
var person = {
	name: "Lee",
	sayName: function(){
		alert(this.name);
	}
}
这种方式创建很多对象,会产生大量的重复代码,工厂方式解决该问题。

工厂方式
用函数来封装特定接口创建对象
function fnc(name,age){
	var f = new Object();
	f.name = name;
	f.age = age;
	f.show = function(){
		alert(this.name);
	}
	return f;
}
var f1 = fnc("Lee",22);
var f2 = fnc("Zhao",22);
优势:可以无数次调用这个函数,每次都会返回一个对象
劣势:无法确定一个对象的类型

构造函数模式
可以创建自定义的构造函数,定义对象类型的属性和方法
function fnc(name,age){
	this.name = name;
	this.age = age;
	this.show = function(0{
		alert(this.name);
	})
}
var f1 = new fnc("Lee",22);
var f2 = new fnc("Zhao",22);
这种模式与工厂模式的区别:
1.没有显示的创建对象
2.直接将属性和方法赋值给了this对象
3.没有return
劣势:每个方法都要在每个实例上差创建一遍,没有共享,没有封装性可言。

原型模式
每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而对象包含可以由特定类型的所有实例共享的属性和方法。
不必在构造函数中,定义对象实例的一些方法或者属性,而是直接将这些添加到原型对象中。
function fnc(){}
fnc.prototype.name = "Lee";
fnc.prototype.age = 22;
fnc.prototype.show = function(){
	alert(this.name);
}

var f1 = new fnc();
f1.show();   //Lee
var f2 = new fnc();
f2.show();   //Lee
图解原型,构造函数,实例的关系:




       fnc是一个构造函数,里面有一个属性,叫做Prototype,指向构造函数性的原型,原型里有一个constructor属性,又指向回该构造函数,f1,f2为两个实例,他们底下有一个_proto_([[Prototype]])属性,指向了原型,也就说明了f1和f2与构造函数没有什么直接的关系。
       对于一个实例上的属性,首先,从对象实例开始搜索,如果在实例中找到了具有该属性的名字,就返回该值,如果没有找到,就继续搜索原型对象,在原型对象中查找,直至找到,否则,返回undefined。
       当然我们在实例上添加一个属性的话,该属性名如果和原型上的属性名重复,这样子, 该属性会覆盖原型上的属性,但是不会修改原型上的属性,可是使用delete实例属性,又可以恢复原形的属性。

function fnc(){}
fnc.prototype.name = "Lee";
fnc.prototype.age = 22;
fnc.prototype.show = function(){
	alert(this.name);
}

var f1 = new fnc();
var f2 = new fnc();
f1.name = "Zhao";

alert(f1.name); //Zhao
alert(f2.name);  //Lee

delete f1.name;
alert(f1.name);  //Lee

可以使用hasOwnProperty()方法可以判断一个属性在事例中,还是在原型中,这个方法是继承Object的,只有给定属性在实例中,才会返回true。操作符in,无论该属性存在实例还是原型,都返回true。可以用该方法判断一个属性存在哪里:
function juge(object,name){
    return!object.hasOwnPropertype(name)&&(name in object)
}

接下来再看一段代码:
function fnc(){}
fnc.prototype = {
	constructor: fnc,
	name: "Lee",
	friends: ["Zhao","Sonly"],
}

var f1 = new fnc();
var f2 = new fnc();
f1.friends.push("Day");

alert(f1.friends); //Zhao,Sonly,Day
alert(f2.friends);  //Zhao,Sonly,Day

传递引用类型的值,问题很明显,在一个实例进行了修改,另一个也就一样修改了,这就是应为在原型上进行了修改,因此,问题就是共享的同样的可能

构建函数+原型模式
构造函数用于实现实力属性,原型模式用于定义方法和共享的属性。
这样子的模式组合,在构造函数定义的属性,修改时,只会影响修改的对象,其他的不受影响。
function Fnc(name,age){
	this.name = name;
	this.age = age;
	this.friends = ["Sonly","Chat"];
}
Fnc.prototype = {
	constructor: Fnc,
	show: function(){
		alert(this.name);
	}
}
var f1 = new Fnc("Lee",22);
var f2 = new Fnc("Tuyg",22);
f1.friends.push("Haye");

alert(f1.friends); //Sonly,Chat,Haye
alert(f1.friends); //Sonly,Chat

这种模式,是流传最广的,也是能实现共享,同时又互不影响的一种完美结合的方法。
当然还有其他的一些创建对象的方法,但是这四种,是最基础的,最后一种相结合的方式是最直接完美的,各有各的优点,同时也有缺点,根据喜好,自创对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值