js prototype的理解【转】

prototype属性可算是JavaScript与其他面向对象语言的一大不同之处。 prototype就是“一个给类的对象添加方法的方法”,使用prototype属性,可以给类动态地添加方法,以便在JavaScript中实现“ 继承”的效果。

具体来说,prototype 是在 IE 4 及其以后版本引入的一个针对于某一类的对象的方法,当你用prototype编写一个类后,如果new一个新的对象,浏览器会自动把prototype中 的内容替你附加在对象上。这样,通过利用prototype就可以在JavaScript中实现成员函数的定义,甚至是“继承”的效果。

对于javascript本身而言是基于对象的,任何元素都可以看成对象。然而类型和对象是不同的,而我们所讲的prototype属性即是基于类型的一 种属性。对于prototype的基本使用就如对象的创建及属性赋值一样的简单。直接通过赋值操作即可完成属性的创建。


/**
 * 
关于prototype,
理解这个很有必要

可以在类型上使用proptotype来为类型添加行为。这些行为只能在类型的实例上体现。

JS中允许的类型有Array,
Boolean,
Date,
Enumerator,
Error,
Function,
Number,
Object,
RegExp,
String

以后这样分,没有实例化的类称为类型,实例化的类称为对象实例简称实例

 */
Object.prototype.name = "zhangsan";

Object.prototype.nihao = function () {

    alert("i can method name is " + this.name);

}

var obj = new Object();

obj.nihao();

alert(obj.name);



// 在实例上不能使用prototype,否则会发生编译错误

obj.prototype.sex = "男"; //error,无法给一个实例prototype
var o = {

    name: "zhangsan"

}

o.prototype.age = 30; //error,无法给一个实例prototype
//可以为类型定义“静态”的属性和方法,直接在类型上调用即可
alert(Object.name);

Object.nihao();

//实例不能调用类型的静态属性或方法,否则发生对象未定义的错误。
Object.class = "三年二班"; //类静态属性
var ob = new Object();

alert(ob.class); //error 实例不能调用类型的静态属性和方法
//可以在外部使用prototype为自定义的类型添加属性和方法。
function Mytest() {

    this.name = "zhangsan";

    this.age = 20;

}

Mytest.prototype.hello = function () {

    alert(this.name);

}

var m = new Mytest();

m.hello();

//在外部不能通过prototype改变自定义类型的属性或方法。
//该例子可以看到:调用的属性和方法仍是最初定义的结果。
Mytest.prototype.name = "lisi";

var mm = new Mytest();

alert(mm.name);

//可以在对象实例上改变或增加属性。(这个是肯定的)
//也可以在对象上改变或增加方法。(和普遍的面向对象的概念不同)
mm.name2 = "lisi";

mm.hello = function () {

    alert(this.name2);

}

//mm.hello();
//继承,这个例子说明了一个类型如何从另一个类型继承。
function Mytest2() { }

Mytest2.prototype = new Mytest;

var m2 = new Mytest2();

alert(m2.name);

//这个例子说明了子类如何重写父类的属性或方法。
Mytest2.prototype.name = "wangwu";

Mytest2.prototype.hello = function () {

    alert('i can mytest2 extend Mytest save method hello');

}

var m3 = new Mytest2();

m3.hello();

//子类中的name属性值不会被父类覆盖
function Mytest3() {

    this.name = "子类中的name属性值不会被父类覆盖";

    this.age = 20;

}

Mytest3.prototype = new Mytest();

var m4 = new Mytest3();

alert(m4.name);

    Object.prototype.name = "zhangsan";

    Object.prototype.nihao = function(){

        alert("i can method name is "+this.name);

    }

    var obj = new Object();

    obj.nihao();

    alert(obj.name);



    / / 在实例上不能使用prototype否则会发生编译错误

obj.prototype.sex = "男"; //error,无法给一个实例prototype
var o = {

    name: "zhangsan"

}

o.prototype.age = 30; //error,无法给一个实例prototype
//可以为类型定义“静态”的属性和方法,直接在类型上调用即可
alert(Object.name);

Object.nihao();

//实例不能调用类型的静态属性或方法,否则发生对象未定义的错误。
Object.class = "三年二班"; //类静态属性
var ob = new Object();

alert(ob.class); //error 实例不能调用类型的静态属性和方法
//可以在外部使用prototype为自定义的类型添加属性和方法。
function Mytest() {

    this.name = "zhangsan";

    this.age = 20;

}

Mytest.prototype.hello = function() {

    alert(this.name);

}

var m = new Mytest();

m.hello();

//在外部不能通过prototype改变自定义类型的属性或方法。
//该例子可以看到:调用的属性和方法仍是最初定义的结果。
Mytest.prototype.name = "lisi";

var mm = new Mytest();

alert(mm.name);

//可以在对象实例上改变或增加属性。(这个是肯定的)
//也可以在对象上改变或增加方法。(和普遍的面向对象的概念不同)
mm.name2 = "lisi";

mm.hello = function() {

    alert(this.name2);

}

//mm.hello();
//继承,这个例子说明了一个类型如何从另一个类型继承。
function Mytest2() {}

Mytest2.prototype = new Mytest;

var m2 = new Mytest2();

alert(m2.name);

//这个例子说明了子类如何重写父类的属性或方法。
Mytest2.prototype.name = "wangwu";

Mytest2.prototype.hello = function() {

    alert('i can mytest2 extend Mytest save method hello');

}

var m3 = new Mytest2();

m3.hello();

//子类中的name属性值不会被父类覆盖
function Mytest3() {

    this.name = "子类中的name属性值不会被父类覆盖";

    this.age = 20;

}

Mytest3.prototype = new Mytest();

var m4 = new Mytest3();

alert(m4.name);

来源:http://my.oschina.net/tongjh/blog/265209

构造函数通常没有返回值。他们初始化作为this的值来传递的对象,并没有返回值。然而,一个构造函数是允许返回一个对象值的,并且,如果这么做,返回的对象成为new表达式的值。在此情况下,作为this的值得对象会被抛弃。