如何创建对象
使用 constructor
[js]
var obj = new Object(); // var 可以省略
var obj = new Date();
[/js]
使用对象字面值(object literals)
[js]
var obj = "123" // 创建一个 String 对象
var obj = /^abc$/ //创建一个 RegExp 对象
[/js]
更加复杂的情况是, 我们可以直接生成一个自定义的只有属性的对象.
[js]
var obj = {
name : "test",
home : "Hunan Province China"
}
document.write(obj.name + "<br />")
document.write(obj.home)
[/js]
结果
killercat
Hunan Province China
JavaScript中的属性
[js]
str = "Hunan Province China" // str 一个字符串对象的引用
document.write(str.length)
[/js]
通过对象的引用加上
.再加上属性名, 可以访问到这个属性, 也可以修改这个属性, 甚至是添加一个属性, 比如.[js]
var obj = new Object()
obj.name = "test" // 为对象直接添加一个属性
document.write(obj.name) // 访问对象的属性
obj.name = "test1" // 修改对象的属性
document.write(obj.name)
[/js]
枚举属性值
使用
for ... in 语句可以枚举属性(具体来说就是枚举属性名)[js]
for(ele in window){
document.write(ele + "<br />")
}
[/js]
如何得到属性值
[js]
obj = new Object()
obj.p1 = "a"
obj.p2 = "b"
obj.p3 = "c"
for(ele in obj)
document.write(obj.ele) // 这是新手可能犯的错误, obj.ele 的值是undefined
[/js]
应该这样访问属性值
[js]
document.write(eval("obj." + ele))
[/js]
未定义的属性:
[js]
obj = new Object()
document.write(obj.name)
[/js]
结果是
undefined
删除属性
[js]
obj = new Object()
obj.name = "killercat"
delete obj.name
document.write(obj.name)
[/js]
结果是
undefined
理解属性
在 Java, C++ 中, 属性要么属于某个类(类属性或说是静态属性), 要么属于对象, 也就是说, 同一个类的对象, 一定有一样的属性, 但是 JavaScript 不一样, 同样是 Object 的对象, 却可以有不同的属性. 除了这类的属性, JavaScript 中还有静态的属性(变量).
Constructor
源于某些未知原因, 有些人似乎不愿意在 JavaScript 提到 classes 这个词, 取代的是 对象的类型(object types), 甚至有些人直接叫函数, 于是可以看见这样的说法: "我们通过预先定义好的函数, 产生了一个对象". 本文使用类, 这个名词.
JavaScript 定义方法的方式和定义类的方式一模一样
[js]
function User(name,sex){ // 定义了类 User
this.name = name;
this.sex = sex;
}
user = new User("kc","man")
document.write(user.name + "<br />"+ user.sex)
[/js]
contructor 的作用就是在初始化属性(变量)
方法
以下例子引用于 JavaScript: The Definitive Guide
[js]
function Rectangle_area( ) { return this.width * this.height; }
function Rectangle_perimeter( ) { return 2*this.width + 2*this.height; }
function Rectangle_set_size(w,h) { this.width = w; this.height = h; }
function Rectangle_enlarge( ) { this.width *= 2; this.height *= 2; }
function Rectangle_shrink( ) { this.width /= 2; this.height /= 2; }
function Rectangle(w, h) {
this.width = w;
this.height = h;
this.area = Rectangle_area;
this.perimeter = Rectangle_perimeter;
this.set_size = Rectangle_set_size;
this.enlarge = Rectangle_enlarge;
this.shrink = Rectangle_shrink;
}
[/js]
这种风格可能和 Java, C++很不同. 方法中的
this 表示调用它的对象的引用. prototype
prototype 是一个对象, 每个类都包含一个 prototype 对象(注意, 每个类一个, 而不是每个对象一个).
看看下面的例子
[js]
function User(name) {
this.name = name
}
User.prototype.name = "killercat" // 类名.prototype.属性(或方法)
user = new User("who" + "<br />")
document.write(user.name)
delete user.name
document.write(user.name)
[/js]
再看一个例子
[js]
function User(name) {
}
User.prototype.name = "human"
user1 = new User()
user2 = new User()
document.write(user1.name + "<br />")
document.write(user2.name)
[/js]
结果
human
human
说明每个类一个 prototype 对象, 而不是每个对象单独一个.
obj.x 这条语句的查找顺序是, 先在obj中找 x 属性, 假如没有, 再进入 obj 对应的类中找 prototype.x, 对于方法来说, 也一样. 因此, 不要出现这样的语句: user.prototype.name = "xxx" 必须是 user.name = "xxx" (prototype对象属于一个类, 而不是一个对象)
类名.prototype.属性 == 相当于一个实例变量(属性), 对方法也一样
类名.属性 == 相当于一个静态变量(属性), 对方法也一样, 调用的时候必须使用"类名.属性", 不能使用"类对象.属性", 因为它属于一个类, 而不是一个对象.
例如:
[js]
function User(name) {
this.name = name
}
User.type = "human"
user = new User("kc")
document.write(User.type + "<br />")
document.write(user.type)
[/js]
结果:
human
undefined
另外, 每个 prototype 都有一个 constructor 属性, 默认用于保存 constructor 的定义, 例如上面的 user 对象, 调用
user.constructor得到: [js]
function User(name) { this.name = name; }
[/js]
我们可以通过 typeof, 知道参数的类型, 假如是对象, 就返回
object, 假如是方法就返回 function利用 prototype 实现类间的继承
[js]
// 父类
function Circle(r) {
this.r = r;
}
Circle.PI = 3.14;
Circle.prototype.getArea = function (){
return Circle.PI * this.r * this.r;
};
Circle.prototype.toString = function (){
if(( typeof this == "object") && (this.constructor == Circle)){
return "circle with a radius " + this.r ;
} else {
return "unknown object";
}
};
Circle.max = function (c1,c2){
return c1.r >= c2.r ? c1 : c2;
};
// 子类
function ColorCircle(r,color){
this.r = r;
this.color = color;
}
ColorCircle.prototype = new Circle(0); // 保存父类的对象
ColorCircle.prototype.constructor = ColorCircle; // 为constructor 改名字
ColorCircle.prototype.toString = function(){
if(( typeof this == "object") && (this.constructor == ColorCircle)) {
return this.color+" circle with a radius " + this.r ;
} else {
return "unknown object";
}
}
ColorCircle.prototype.getColor = function(){
return this.color;
}
ColorCircle.prototype.setColor = function(color){
this.color = color;
}
[/js]
也就是, 使用 prototype 保存父类的对象, 在构造子类的时候, 父类对象同时被构造(因为 prototype 被构造). 也就是 JavaScript 继承其实就是让子类的 prototype 对象保存父类的对象.
没有评论:
发表评论