当前位置:编程学习 > JAVA >>

javascript面向对象的写法03

js一些基础知识的说明
prototype
首先每个js函数(类)都有一个prototype的属性,函数是类。注意类有prototype,而普通对象没有。
js中有一些常用的内置类。下面代码打印内置类和自定义类的protytype
 
console.log(String.prototype);
console.log(Date.prototype);
console.log(Object.prototype);
 
function ClassA(name,job,born) {
}
console.log(ClassA.prototype);
 
prototype一般作用 
 
prototype作用可以扩展类,为类添加一些属性或者方法的定义。
实际上prototype是类的一个特殊的固有的属性,它指向的是一个简单的普通的对象。因为被指向的是一个普通的对象,所以可以对prototype指向的对象增加属性或修改属性等。prototype指向的对象被更改过后,最后的效果类似把类的定义更改过。
修改prototype指向的对象实例。
Object.prototype.name = "111";    //为Object原型增加一个name属性
function ClassA(name,job,born) {
}
 
ClassA.prototype.name = "123";    //自定义类原型也可以修改
ClassA.prototype.func1 = function(){};    //同样可以修改原型的func1属性为一个函数指针
prototype作用可以扩展类,比如为某个类的原型增加了一些属性,那么该修改过的类所创建的所有对象都有此属性。
 
1
2
3
4
5
6
7
8
9
10
11
12
13
function ClassA(name,job,born) {
    //此时的ClassA类没有定义任何的属性,用它new出来的对象自然是没有name属性
}
var objB = new ClassA();    
console.log(objB.name);         //输出undefined
 
Object.prototype.name = "111";
ClassA.prototype.name = "123";  //prototype的修改对之前new出来的对象同样生效
 
var objA = new Object();
console.log(objA.name);         //内置类的prototype修改也是可以的
 
console.log(objB.name);     //修改过prototype后便有这个属性了
  
 
可以把prototype看做类的另外一半,把prototype和原本的类并在一起就相当于一个完整的类了。
 
 
function ClassA() {
    this.a = 100;
    this.b = 100;
}
ClassA.prototype = {
    'name': '123',
    'getName': function(){}
};
 
//类似于
function ClassA() {
    this.a = 100;
    this.b = 100;
    this.name = '123';
    this.getName = function(){};
}
 
js访问一个对象的属性时,先在自己的属性中寻找,如果没有继而会去从类的prototype中找。自己定义的属性是会覆盖住类prototype定义的属性。
 
 
function ClassA() {
    this.a = 100;
}
ClassA.prototype = {
    'a': 200,
};
 
var obj = new ClassA();
console.log(obj.a);        //输出100
 
 
prototype还可以修改已有的类
 
比如修改内置Array类的prototype,添加一个方法。
Array(数组)没有“是否包含”这样的方法,可以自己扩展一个
 
Array.prototype.containsObject = function(e) {
    for (i=0; i<this.length; i++) {
        if (this[i] == e) {
            return true;
        }
    }
    return false;
};
 
使用prototype的好处
 
使用prototype可以扩展类从而使得类创建的对象拥有扩展的属性或方法,类本身作为构造函数也可以为对象设置属性。
function ClassA() {
    this.a = 100;
}
ClassA.prototype = {
    'b': 200
};
那么两者有何区别呢?使用何种方式好。
 
首先类作为构造函数的写法是同以下形式作用一样,前面文章提到过。
 
function ClassA() {
    this.a = 100;
}
 
//两者等同
function ClassA() {
}
//
var obj = new ClassA();
obj.a = 100;
 
//也就是如果有其他对象要创建的话就如下面一样
var obj02 = new ClassA();
obj02.a = 100;
var obj03 = new ClassA();
obj03.a = 100;
 
也就是说类构造函数方式创建的对象,每个对象都有一份所有属性的拷贝。这个无可厚非,对象的普通属性值在不同对象会不同,因该是每个对象一份拷贝的。
但如果属性是一个函数指针呢,也就是说每个对象的方法也都同普通属性一样,各自有一份拷贝。这个就显得不合理,因为函数的具体内容是一样的,只要存一个地方就行了,多少份拷贝没有任何区别。
所以使用prototype可以有更加完善的类的方法的写法。
 
function ClassA() {
    this.func1 = function() {};        //此方法每个类都有一份拷贝。
}
ClassA.prototype.func2 = function(){};        //此方法存在于类的prototype属性中,只有一个地方有。
 
//调用func2的时候,obj对象自身没有,于是到类的prototype中寻找。
var obj = new ClassA();
obj.func2();
 
注意这两种写法的区别
 
 
function ClassA() {
    
}
//第一种方式扩展方法
ClassA.prototype.func1 = function() {};
ClassA.prototype.func2 = function() {};
 
//第二种,注意此种方易做图有一些影响
ClassA.prototype = {
    "func1": function() {},
    "func2": function() {}
};
 
最关键的地方在于前者ClassA.prototype.func1是对ClassA.prototype的func1属性做操作,字面意思是如果有则修改为,没有则添加一个func1属性。
而后者则是将整个ClassA.prototype指向给替换掉了。替换成了一个{}对象了,{}对象是内置Object类的对象。
看这句更好理解ClassA.prototype = new ClassB()。
后者替换了类原始的prototype属性,后面会提到这种的影响,这个影响应当注意一下,在什么时候会有副作用自己要有所掌控。
constructor
每个js对象都有一个constructor属性,类也有,因为类也是对象,把类当对象使用的时候跟普通对象没区别。
constructor指向的是创建自身对象的构造函数,也就是自身的构造器是哪个。之前提过函数是对象的构造器,同时可以当成类来看待。所以constructor也可以理解成指向创建自己的类,也就是对象自己是由哪个类创建的。
 
function ClassA() {
}
 
var obj = new ClassA();
console.log(obj.constructor);     //这里输出的就是ClassA函数,也就是ClassA类了。
 
console.log(ClassA.constructor);     //类(函数)也是对象,也有constructor。它的是Function
 
原型对象和原型链
 
每个对象都有它自己的原型对象。所谓的原型对象就是上面所说的,对象的类(构造函数)的prototype属性所指的那个对象。
请看下面的例子
 
function ClassA() {
}
var obj = new ClassA();
 
//obj的原型对象是什么? 是obj构造函数的prototype属性所指向的对象
 
<
补充:web前端 , JavaScript ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,