-----看了好多的资料,整理一下,加上自己的理解,希望看见的人有什么问题,请多多指教!
对象定义:无序属性的集合,其属性可以包含基本值、对象、函数。严格来讲,对象是一组没有特定顺序的值,也可以理解为散列表,无非就是一组名值对,其中值可以是数据或函数。
首先,用对象字面量的方法创建对象: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
这种模式,是流传最广的,也是能实现共享,同时又互不影响的一种完美结合的方法。
当然还有其他的一些创建对象的方法,但是这四种,是最基础的,最后一种相结合的方式是最直接完美的,各有各的优点,同时也有缺点,根据喜好,自创对象。