您的位置:首页 > 移动开发 > Objective-C

javaScript基础:Object类型

2016-06-24 07:20 567 查看
一、简介

什么是对象,其实就是一种类型,即引用类型。在JavaScript层面更简单的说就是一个存放属性的容器。

而对象的值就是引用类型的实例。

在ECMAScript中引用类型是一种数据结构,用于将数据和功能组织在一起。

它也常被称做为类,但ECMAScript中却没有这种东西。虽然ECMAScript是一门面向对象的语言,却不具备传统面向对象语言所支持的类和接口等基
结构。

二、创建一个Object对象 

方式一:

var box = new Object(); //创建对象
box.name = '李炎恢'; //给属性赋值
box.age = 28;


方式二:

var box = {};//创建对象
box.name = '李炎恢';//给属性赋值
box.age = 28;


方式三:

var box = {
name : '李炎恢',
age : 28
};

其它:删除对象的属性

delete box.name;//删除对象的属性
三、创建多个对象的模式

当在工程中创建多个相同类型的对象时不可能每次都用new或字面量方式去一个一个的创建对象添加属性,这时就需要更简单的方法去创建多个相同的对象。这个方法就是一种模式。

1、工厂模式

function createObject(name, age) {
//集中实例化的函数
var obj = new Object();
obj.name = name;
obj.age = age;
obj.run = function () {
return this.name + this.age + '运行中...';
};
return obj;
}
var box1 = createObject('Lee', 100);
var box2 = createObject('Jack', 200);
优点:工厂模式可以避免创建对象产生大量的重复代码。

缺点:1.每个对象内部的方法作用相同,但不是同一个方法。创建一个对象就会新增一个相同功能的方法。2.识别问题,所有创建出来的对象都是Object类型。

2、构造函数

function Box(name, age) {
//构造函数模式
this.name = name;
this.age = age;
this.run = function () {
return this.name + this.age + '运行中...';
};
}
var box1 = new Box('Lee', 100); //new Box()即可
var box2 = new Box('Jack', 200);

3、原型模式

方法一:

//给原型对象增加属性

function Box() {}
Box.prototype.name = 'Lee';
Box.prototype.age = 100;
Box.prototype.run = function () {
return this.name + this.age + '运行中...';
};
方法二:

function Box() {};
//直接将一个对象赋值给原型对象
Box.prototype = {
constructor : Box,//指定原型对象的构造属性
name : 'Lee',
age : 100,
run : function () {
return this.name + this.age + '运行中...';
}
};
4、组合模式:构造+原型

function Box(name, age) {
//不共享的使用构造函数
this.name = name;
this.age = age;
this. family = ['哥哥', '姐姐', '弟弟'];
};
Box.prototype = {
constructor : Box,
//共享的使用原型模式
run : function () {
return this.name + this.age + this.family;
}
};


另一种写法:

function Box(name ,age) {
//将所有信息封装到函数体内
this.name = name;
this.age = age;
this.family = ['哥哥','姐姐','弟弟'];
if (typeof this.run != 'function') {
//仅在第一次调用的初始化
Box.prototype.run = function () {
return this.name + this.age + '运行中...';
};
}
}


PS:原型模式

一、原型模式介绍:

1、每个类型都有一个prototype(原型)属性,这个属性是类型的原型对象,它的用途是让所有实例共享属性和方法。

也就是说不必在构造函数中定义对象信息,而是可以直接将这些信息添加到原型中。
(当你通过原型模式创建一个对象时将会开辟一个空间,对象的属性需要有个初始值,这个初始值是从原型对象那里得到的,也就是值传递。所以可以理解为原型对象只是一个存储共享信息的对象。)

获取原型对象:

box.__proto__;//通过实例对象获取原型对象,不是所有浏览器都支持
Box.prototype;//通过类名获取原型对象
2、每个类型的原型对象都有一个constructor(构造)属性,这个属性是对象的构造方法。

系统默认:(通过new Object();或{}方式创建的对象的构造属性对应的构造方法)

function Object() {
[native code]
}
构造函数创建对象:(通过构造函数创建的对象的构造属性对应的构造方法)

function Box(age,text){
this.age = age;
this.text = text;
this.run = function(){
return this.age + this.text;
};
}
3、重写对象的原型对象。

Box.prototype = {
constructor : Box,
name : 'Lee',
age : 100,
run : function () {
return this.name + this.age + '运行中...';
}
};


此代码中是新创建一个对象,给Box的原型对象赋值。

此代码中的属性constructor就是将新建对象的构造属性指向Box。不设置的话默认是Object。
4、原型对象不仅可以在自定义对象的情况下使用,ECMAScript内置的引用类型都可以使用这种方式。 

alert(Array.prototype.sort); //Array类型的原型方法
alert(String.prototype.substring);//String类型的原型方法
String.prototype.addstring = function () {
return this + ',被添加了!';//类型添加一个方法
};
alert('Lee'.addstring());//使用这个方法


PS:尽管给原生的内置引用类型添加方法使用起来特别方便,但不推荐使用这种方法。因为它可能会导致命名冲突,不利于代码维护。 

5、原型模式的执行流程
若一个类型的实例对象里有age属性,原型对象里也有age属性,那么对象该如何取舍?

原型模式的执行流程:1.先查找构造函数实例里的属性或方法,如果有,立刻返回;2.如果构造函数实例里没有,则去它的原型对象里找,如果有,就返回; 

如何判断属性是在实例里还是在原型里?

 hasOwnProperty()函数来验证实例里是否有某个属性。

in操作符判断是否有某个属性,无论该属性存在于实例中还是原型中。

通过以上两个方法可以准确判断出属性存在实例还是原型里。

function isProperty(object, property) {
//判断原型中是否存在属性
return !object.hasOwnProperty(property) && (property in object);
}


二、原型模式的缺点

利用原型模式可以解决重复创建对象、对象识别、重复创建相同的对象方法的问题。但也有两个较为致命的缺点:

1、原型模式无法传递参数。

2、当原型对象中的属性A为引用类型时,改变其中一个实例对象的A属性,所有的实例对象的属性都会发生改变。

举例:

function Box(){}
Box.prototype = {
name : 'lee',
age :100,
family : ['哥哥','姐姐','弟弟'],//引用类型,放在原型对象中共享会出现问题
run : function(){
return this.name + this.age + '运行中...'
}
};
var box1 = new Box();
var box2 = new Box();
alert(box1.family);//哥哥,姐姐,弟弟
alert(box2.family);//哥哥,姐姐,弟弟
box1.family.push('妹妹');//改变实例对象box1的family属性。
alert(box1.family);//哥哥,姐姐,弟弟,妹妹
alert(box2.family);//哥哥,姐姐,弟弟,妹妹  box2的family属性也发生改变
产生上述现象的原因是实例对象从原型对象那里得到初始信息,基本类型得到的是一个值,引用类型得到的是一个地址。所有的实例对象得到的地址都是一样的,当改变了其中一个实例对象的family属性,就相当于改变了这个地址引用的那个family对象的内容,所以所有的实例对象的family属性发生改变,而基本类型就不存在这种问题。

如果代码改写成如下就不会出现这种问题。

box1.family = ['哥哥','姐姐','弟弟','妹妹'];


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: