标签:java 使用 数据 javascript 问题 cti
面向对象的程序设计都有一个特点,就是它们都有一个类的概念。而Javascript中没有类的概念,因此它的对象的定义也与其他语言不一样,在Javascript中把对象定义为:无序属性的集合,其属性可以包含基本值,对象和函数。也相当于说对象是一组没有特定顺序的值。
创建自定义对象的最简单方式就是创建一个Object的实例。然后再为它添加属性和方法:
var person = new Object();
person.name = ‘Nicholas‘;
person.age = 29;
person.job = ‘Software Engineer‘;
person.sayName = function() {
alert(this.name);
}
上面的例子创建了一个person对象并为添加了三个属性和一份方法。现在对象字面量成为创建这种对象的首选模式,上面的例子可以写成这样:
var person = {
name: ‘Nicholas‘,
age: 29,
job: ‘Software Engineer‘,
sayName: function() {
alert(this.name);
}
}
这个例子中的person对象和前面的是一样的。
Javascript中有两种属性:数据属性和访问器属性
数据属性包含一个数据值的位置。在这个位置可以读取和写入值,数据属性有四个描述其行为的特性:
name:‘Nocholas‘
。要修改属性默认的特性,必须使用Object.defineProperty()方法,这个方法接收三个参数:属性所在的对象,属性的名字和一个描述符对象。其中描述符必须是以上四个中的一个。 var person = {};
Object.defineProperty(person,‘name‘,{
writable:false,
value:‘hehe‘
});
这个例子中,person对象的name属性的值是只读的,如果尝试为它指定值,在非严格模式下,赋值操作将被忽略,在严格模式下,就导致抛出错误。
类似的规则也适用于不可配置的属性:
var person = {};
Object.defineProperty(person,‘name‘,{
configurable:false,
value:‘hehe‘
});
上面例子表示不可从对象中删除属性,而且一旦把属性变成不可配置的就不能再变回来,再调用Object.defineProperty()方法修改除writabel之外的所有特性,都会导致错误。
访问器属性不包含数据值:它们包含一对儿getter和setter函数(不是必须的)。在读取访问器属性是会调用getter函数,在写入访问器属性时,会调用setter方法。访问器属性有四个特性:
var book = {
_year: 2004,
edition: 1
};
Object.defineProperty(book,‘year‘,{
get:function() {
return this._year;
}
set:function(newValue) {
if(newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
}
});
book.year = 2005;
alert(book.edition);
_year前面的下划线表示是一种常见的记号,表示只能通过对象方法访问的属性。不一定一定要同时制定getter和setter方法。只指定getter方法意味着属性是不能写,尝试写入会被忽略。只指定setter方法表示属性是不能被读,会返回undefined。
虽然Object构造函数或对象字面量都可以用来创建单个对象,但这些方式有一个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码。
考虑都Javascript中无法创建类,开发人员就发明了一种函数,用函数来封装以特定接口创建对象的细节:
function createPerson(name,age,job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
alert(name);
};
return 0;
}
var person1 = createPerson(‘alex‘,23,‘Software Engineer‘);
var person2 = createPerson(‘kim‘,5,‘boy‘);
可以无数次的调用这个函数,每次都会返回一个包含三个属性一个方法的对象。工厂模式解决了创建多个相似对象的问题,但是没有解决对象识别的问题,(即怎么知道一个对象的类型)。
在Javascript中,像Object和Array这样的原声构造函数,在运行时会自动出现在执行环境中。此外,也可以创建自定义的构造函数,从而自定义对象类型的属性和方法。可以使用构造函数模式将前面的例子重写:
function Person(name,age,job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function() {
alert(this.name);
}
}
var person1 = new Person(‘alex‘,23,‘Software Engineer‘);
var person2 = new Person(‘kim‘,5,‘boy‘);
Person()中的代码除了与createPerson()中相同的部分外,还存在以下不同:
构造函数与其他函数的唯一区别就是调用它们的方式不同。任何函数,只要通过new操作符调用,就可以作为构造函数,任何函数,如果不通过new操作符,那它就和普通函数一样。
使用构造函数的主要问题,就是每个方法都要在每个实例上重新创建一遍。在前面的例子中person1和person2都有sayName()方法,但两个方法不是同一个Function对象的实例。此时的构造函数也可以这样定义:
function Person(name,age,job) {
this.name = name;
this.age = age;
this.job = job;
this.sagName = new Function("alert(‘this.name‘)");
}
但是创建两个完成同样任务的Function实例的却没有必要;因此,可以通过把函数定义转移到构造函数外面来解决这个为问题:
function Person(name,age,job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = sayName;
}
function sayName() {
alert(this.name);
}
person1和person2对象共享了在全局作用域中定义的同一个sayName()函数。这样解决了两个函数做同一件事情的问题,但是新问题:在全局作用域中定义的函数实际上只能被某一个对象调用,这让全局作用域有点儿名不副实。而更让人无法接收的是:如果对象需要定义很多方法,那就定义很多全局函数,于是我们这个自定义的引用类型就丝毫没有封装性了,这些问题可以通过原型模式来解决。
Javscript-面向对象1,布布扣,bubuko.com
标签:java 使用 数据 javascript 问题 cti
原文地址:http://www.cnblogs.com/huangt/p/3817488.html