本文实例讲述了JavaScript 面向对象程序设计。分享给大家供大家参考,具体如下:类的创建于实例对象工厂模型创建对象
function CreatePerson ( name,sex,age ) {

var obj = new Object();

obj.name = name;
obj.sex = sex;
obj.age = age;

obj.sayName = function () {



console.log( this.name );


}

return obj;

}

var p1 = CreatePerson('zf','女',22);

p1.sayName(); //zf

console.log( p1.name ); //zf

function CreatePerson ( name,sex,age ) {

var obj = new Object();

obj.name = name;
obj.sex = sex;
obj.age = age;

obj.sayName = function () {



console.log( this.name );


}

return obj;

}

var p1 = CreatePerson('zf','女',22);

p1.sayName(); //zf

console.log( p1.name ); //zf
构造函数式
//函数的第一个字母大写(类的模板)
function Person ( name,age,sex ) {

this.name = name;
this.age = age;
this.sex =sex;

this.sayName = function () {



alert(this.name);


}

}

//构造一个对象, 使用new关键字, 传递参数, 执行模板代码, 返回对象。

var p1 = new Person('zf',20,'女'); //类的概念:根据模板创建出不同的实例对象

console.log( p1.name );

p1.sayName();

//函数的第一个字母大写(类的模板)
function Person ( name,age,sex ) {

this.name = name;
this.age = age;
this.sex =sex;

this.sayName = function () {



alert(this.name);


}

}

//构造一个对象, 使用new关键字, 传递参数, 执行模板代码, 返回对象。

var p1 = new Person('zf',20,'女'); //类的概念:根据模板创建出不同的实例对象

console.log( p1.name );

p1.sayName();
创建类的实例:



当作构造函数去使用

var p1 = new Person('a1',20);





作为普通函数去调用

Person('a2',20); //在全局环境中定义属性并赋值, 直接定义在window上。





在另个一对象的作用域中调用

var o = new Object();

Person.call(o,'a3',23);




当作构造函数去使用

var p1 = new Person('a1',20);

当作构造函数去使用var p1 = new Person('a1',20);

作为普通函数去调用

Person('a2',20); //在全局环境中定义属性并赋值, 直接定义在window上。

作为普通函数去调用Person('a2',20); //在全局环境中定义属性并赋值, 直接定义在window上。

在另个一对象的作用域中调用

var o = new Object();

Person.call(o,'a3',23);

在另个一对象的作用域中调用var o = new Object();

Person.call(o,'a3',23);Object每个实例都会具有的属性和方法:
Constructor: 保存着用于创建当前对象的函数。(构造函数)
hasOwnProperty(propertyName):用于检测给定的属性在当前对象实例中(而不是原型中)是否存在。
isPrototypeOf(Object): 用于检查传入的对象是否是另外一个对象的原型。
propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in语句来枚举。
toLocaleString():返回对象的字符串表示。该字符串与执行环境的地区对应.
toString():返回对象的字符串表示。
valueOf():返回对象的字符串、数值或布尔表示。
Constructor: 保存着用于创建当前对象的函数。(构造函数)
hasOwnProperty(propertyName):用于检测给定的属性在当前对象实例中(而不是原型中)是否存在。
isPrototypeOf(Object): 用于检查传入的对象是否是另外一个对象的原型。
propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in语句来枚举。
toLocaleString():返回对象的字符串表示。该字符串与执行环境的地区对应.
toString():返回对象的字符串表示。
valueOf():返回对象的字符串、数值或布尔表示。判断一个对象是不是另一个对象的实例,通常使用的是 instanceof. 比较少使用constructor。原型创建每一个函数的时候,都有一个prototype属性. 这个是属性,是一个指针。而这个对象总是指向一个对象。
这个对象 的用途就是将特定的属性和方法包含在内,是一个实例对象, 起到了一个所有实例所共享的作用。
屏蔽了,构造函数的缺点,new 一个对象,就把构造函数内的方法实例化一次。
function Person () {


}

var obj = Person.prototype;

console.log( obj ); //Person.prototype 就是一个对象
//Person.prototype 内部存在指针,指针指向一个对象。 这个对象称之为:原型对象。原型对象,被所有的实例对象所共享。

console.log( obj.constructor ); //function Person(){} //obj这个对象的构造器就是 Person

function Person () {


}

var obj = Person.prototype;

console.log( obj ); //Person.prototype 就是一个对象
//Person.prototype 内部存在指针,指针指向一个对象。 这个对象称之为:原型对象。原型对象,被所有的实例对象所共享。

console.log( obj.constructor ); //function Person(){} //obj这个对象的构造器就是 Person
原型图例:console.log(Person.prototype) 的结果:
常用方法Object.getPrototypeOf()根据实例对象获得原型对象每次代码读取一个对象的属性的时候:首先会进行一次搜索,搜索实例对象里,看看是否存在,如果没有,再去实例所对的原型中寻找属性.如果有则返回,如果两次都没有则返回undefined每次代码读取一个对象的属性的时候:首先会进行一次搜索,搜索实例对象里,看看是否存在,如果没有,再去实例所对的原型中寻找属性.如果有则返回,如果两次都没有则返回undefined
function Person () {
}

Person.prototype.name = 'z1';
Person.prototype.age = 20;

Person.prototype.sayName = function () {

console.log( '我是原型对象方法' );

}

var p1 = new Person();

console.log( p1.name ); //z1

console.log( Object.getPrototypeOf(p1) );
console.log( Object.getPrototypeOf(p1) == Person.prototype ); //true

function Person () {
}

Person.prototype.name = 'z1';
Person.prototype.age = 20;

Person.prototype.sayName = function () {

console.log( '我是原型对象方法' );

}

var p1 = new Person();

console.log( p1.name ); //z1

console.log( Object.getPrototypeOf(p1) );
console.log( Object.getPrototypeOf(p1) == Person.prototype ); //true
hasOwnProperty()判断是否是 实例对象自己的属性
function Person () {
}

Person.prototype.name = 'z1';
Person.prototype.age = 20;

Person.prototype.sayName = function () {

console.log( '我是原型对象方法' );

}


// 判断一个对象属性 是属于 原型属性 还是属性 实例属性

var p3 = new Person();
console.log( p3.name ); //zf 是原型上的

//hasOwnProperty() 是否是 实例对象自己的属性
console.log( p3.hasOwnProperty('name') ); //false

function Person () {
}

Person.prototype.name = 'z1';
Person.prototype.age = 20;

Person.prototype.sayName = function () {

console.log( '我是原型对象方法' );

}


// 判断一个对象属性 是属于 原型属性 还是属性 实例属性

var p3 = new Person();
console.log( p3.name ); //zf 是原型上的

//hasOwnProperty() 是否是 实例对象自己的属性
console.log( p3.hasOwnProperty('name') ); //false
in 操作符无论是 原型的属性, 还是实例对象的属性, 都区分不开。 如果存在,返回true
function Person () {
}

Person.prototype.name = 'z1';
Person.prototype.age = 20;

Person.prototype.sayName = function () {

console.log( '我是原型对象方法' );

}


//判断属性是否存在 实例对象 和 原型对象中.

var p1 = new Person();
console.log('name' in p1); //true //表示,name的属性到底在不在p1的属性中 true
var p2 = new Person();

p1.name = 'zzz';

console.log('name' in p1); //true

function Person () {
}

Person.prototype.name = 'z1';
Person.prototype.age = 20;

Person.prototype.sayName = function () {

console.log( '我是原型对象方法' );

}


//判断属性是否存在 实例对象 和 原型对象中.

var p1 = new Person();
console.log('name' in p1); //true //表示,name的属性到底在不在p1的属性中 true
var p2 = new Person();

p1.name = 'zzz';

console.log('name' in p1); //true
判断一个属性是否在原型中判断一个属性是否在原型中
function Person () {
}

Person.prototype.name = 'z1';
Person.prototype.age = 20;

Person.prototype.sayName = function () {

console.log( '我是原型对象方法' );

}


//判断属性是否存在 实例对象 和 原型对象中.

var p1 = new Person();
p1.name = '123';

//在原型对象中,是否存在这个值
//@obj 当前对象
//@判断的属性
function hasPrototypeProtoperty ( obj,attrName ) {

return !obj.hasOwnProperty(attrName) && (attrName in obj);

}

console.log( hasPrototypeProtoperty(p1,'name') ); //false

function Person () {
}

Person.prototype.name = 'z1';
Person.prototype.age = 20;

Person.prototype.sayName = function () {

console.log( '我是原型对象方法' );

}


//判断属性是否存在 实例对象 和 原型对象中.

var p1 = new Person();
p1.name = '123';

//在原型对象中,是否存在这个值
//@obj 当前对象
//@判断的属性
function hasPrototypeProtoperty ( obj,attrName ) {

return !obj.hasOwnProperty(attrName) && (attrName in obj);

}

console.log( hasPrototypeProtoperty(p1,'name') ); //false
Object.keys()
function Person () {
}

Person.prototype.name = 'z1';
Person.prototype.age = 20;

Person.prototype.sayName = function () {

console.log( '我是原型对象方法' );

}

//ECMA5新特性 Object.keys();
//拿到当前对象中的所有keys, 返回一个数组

var p1 = new Person();
p1.name = 'zz';
p1.age = 20;

var attr = Object.keys(p1);
console.log( attr ); //["name", "age"]

var attr2 = Object.keys(p1.__proto__);

console.log( attr2 ); //["name", "age", "sayName"]

var attr3 = Object.keys(Person.prototype);

console.log( attr3 ); //["name", "age", "sayName"]

function Person () {
}

Person.prototype.name = 'z1';
Person.prototype.age = 20;

Person.prototype.sayName = function () {

console.log( '我是原型对象方法' );

}

//ECMA5新特性 Object.keys();
//拿到当前对象中的所有keys, 返回一个数组

var p1 = new Person();
p1.name = 'zz';
p1.age = 20;

var attr = Object.keys(p1);
console.log( attr ); //["name", "age"]

var attr2 = Object.keys(p1.__proto__);

console.log( attr2 ); //["name", "age", "sayName"]

var attr3 = Object.keys(Person.prototype);

console.log( attr3 ); //["name", "age", "sayName"]
Object.getOwnPropertyNames()
function Person () {
}

Person.prototype.name = 'z1';
Person.prototype.age = 20;

Person.prototype.sayName = function () {

console.log( '我是原型对象方法' );

}

var p1 = new Person();
p1.name = 'zz';
p1.age = 20;

//ECMA5
//constructor属性,是无法被枚举的. 正常的for-in循环是无法枚举. [eable = false];

//Object.getOwnPropertyNames(); //枚举对象所有的属性:不管该内部属性能够被枚举.

var attr4 = Object.getOwnPropertyNames(Person.prototype); //["constructor", "name", "age", "sayName"]

console.log( attr3 );

function Person () {
}

Person.prototype.name = 'z1';
Person.prototype.age = 20;

Person.prototype.sayName = function () {

console.log( '我是原型对象方法' );

}

var p1 = new Person();
p1.name = 'zz';
p1.age = 20;

//ECMA5
//constructor属性,是无法被枚举的. 正常的for-in循环是无法枚举. [eable = false];

//Object.getOwnPropertyNames(); //枚举对象所有的属性:不管该内部属性能够被枚举.

var attr4 = Object.getOwnPropertyNames(Person.prototype); //["constructor", "name", "age", "sayName"]

console.log( attr3 );
isPrototypeOf()判断原型的方法原型对象.isPrototypeOf(new instance);实现each方法原型的另外一个作用就是扩展对象中的属性和方法
//遍历多维数组
var arr = [1,2,4,5,[455,[456,[345345]]]];

Array.prototype.each = function ( cb ) {

try {


//计数器

this.i || (this.i = 0);


//核心代码

if ( this.length > 0 && cb.constructor === Function ) {


while ( this.i < this.length ) { //计数器 大于 数组长度跳出


//获得每一项值

var e = this[this.i];


//判断是否是 数组

if ( e && e.constructor === Array ) {


//递归

e.each(cb);


} else {


cb.call(null,e);


}


this.i++;


}


//使用完之后,释放变量

this.i = null;


}

} catch (e) {

//do someting


}

return this;

};

arr.each(function( val ){

console.log(val);

});

//遍历多维数组
var arr = [1,2,4,5,[455,[456,[345345]]]];

Array.prototype.each = function ( cb ) {

try {


//计数器

this.i || (this.i = 0);


//核心代码

if ( this.length > 0 && cb.constructor === Function ) {


while ( this.i < this.length ) { //计数器 大于 数组长度跳出


//获得每一项值

var e = this[this.i];


//判断是否是 数组

if ( e && e.constructor === Array ) {


//递归

e.each(cb);


} else {


cb.call(null,e);


}


this.i++;


}


//使用完之后,释放变量

this.i = null;


}

} catch (e) {

//do someting


}

return this;

};

arr.each(function( val ){

console.log(val);

});
简单原型直接通过对象字面量来重写整个原型对象(这种方法会改变原型对象的构造器[改变为Object])
//简单原型


function Person () {

}

Person.prototype = {

constructor: Person, //原型的构造器改变

name: 'zz',
age: 20,

say: function () {

console.log( this.age );
}

}

var p1 = new Person();

console.log( p1.name );
p1.say();

//简单原型


function Person () {

}

Person.prototype = {

constructor: Person, //原型的构造器改变

name: 'zz',
age: 20,

say: function () {

console.log( this.age );
}

}

var p1 = new Person();

console.log( p1.name );
p1.say();
存在的问题,constructor属性是无法被枚举的。加在原型对象上,可以被枚举,被枚举。不符合要求。ECMA5中的Object.defineProperty()方法可以为原型对象重新加入构造器。constructor问题可以被避免。
//3个参数, 参数1:重新设置构造的对象 (给什么对象设置)
参数2:设置什么属性
参数3:options配置项 (要怎么去设置)
Object.defineProperty(Person.prototype,'constructor',{
enumerable: false, //是否是 能够 被枚举
value: Person //值 构造器的 引用
});

//3个参数, 参数1:重新设置构造的对象 (给什么对象设置)
参数2:设置什么属性
参数3:options配置项 (要怎么去设置)
Object.defineProperty(Person.prototype,'constructor',{
enumerable: false, //是否是 能够 被枚举
value: Person //值 构造器的 引用
});
原型的动态特性原型的动态特性注意原型和创建实例的前后顺序
function Person () {


}

var p1 = new Person(); // {}

Person.prototype = {
constructor: Person,
name: 'zf',
age: 20,
say: function () {

console.log('原型');
}
}

//先把原型对象写好,然后再实例化。

//p1.say(); //error 因为
原型对象里面没有任何属性和方法

var p2 = new Person();

p2.say();

//注意 简单原型使用的顺序(实例对象必须在原型对象之后创建)


function Person () {


}

var p1 = new Person(); // {}

Person.prototype = {
constructor: Person,
name: 'zf',
age: 20,
say: function () {

console.log('原型');
}
}

//先把原型对象写好,然后再实例化。

//p1.say(); //error 因为
原型对象里面没有任何属性和方法

var p2 = new Person();

p2.say();

//注意 简单原型使用的顺序(实例对象必须在原型对象之后创建)

原型对象的常用开发模式组合构造函数式和原型模式
function Person( name,age,firends ) {

this.name = name;
this.age = age;
this.firends = firends;

}

Person.prototype = {
constructor: Person,
sayName: function () {

console.log( this.name );
}
}

var p1 = new Person('zz',20,['zf']);
var p2 = new Person('zx',22,['z1']);

console.log( p1.firends ); //['zf']

console.log( p2.firends ); //['z1']

function Person( name,age,firends ) {

this.name = name;
this.age = age;
this.firends = firends;

}

Person.prototype = {
constructor: Person,
sayName: function () {

console.log( this.name );
}
}

var p1 = new Person('zz',20,['zf']);
var p2 = new Person('zx',22,['z1']);

console.log( p1.firends ); //['zf']

console.log( p2.firends ); //['z1']
动态原型模式就是把信息都封装到函数中,这样体现了封装的概念。
//动态原型模式:(让你的代码 都封装到一起)
function Person( name,age,firends ) {

this.name = name;
this.age = age;
this.firends = firends;

//动态原型方法
if ( typeof this.sayName !== 'function' ) {



Person.prototype.sayName = function () {

console.log(this.name);

}


}

}

//动态原型模式:(让你的代码 都封装到一起)
function Person( name,age,firends ) {

this.name = name;
this.age = age;
this.firends = firends;

//动态原型方法
if ( typeof this.sayName !== 'function' ) {



Person.prototype.sayName = function () {

console.log(this.name);

}


}

}
稳妥构造函数式稳妥模式就是没有公共属性,而且其他方法也不引用this对象,稳妥模式最适合在安全的环境中使用。如果程序对于安全性要求很高,那么非常适合这种模式。
也不能使用new关键字。
//稳妥构造函数式 durable object (稳妥对象)
//1,没有公共的属性
//2,不能使用this对象

function Person ( name,age ) {

//创建一个要返回的对象。 利用工厂模式思维。
var obj = new Object();

//可以定义一下是有的变量和函数 private

var name = name || 'zf';

//
var sex = '女';
//
var sayName = function () {
//
}



//添加一个对外的方法
obj.sayName = function () {

console.log(name);
}

return obj;

}

var p1 = Person('xixi',20);

p1.sayName();


//稳妥构造函数式 durable object (稳妥对象)
//1,没有公共的属性
//2,不能使用this对象

function Person ( name,age ) {

//创建一个要返回的对象。 利用工厂模式思维。
var obj = new Object();

//可以定义一下是有的变量和函数 private

var name = name || 'zf';

//
var sex = '女';
//
var sayName = function () {
//
}



//添加一个对外的方法
obj.sayName = function () {

console.log(name);
}

return obj;

}

var p1 = Person('xixi',20);

p1.sayName();

深入原型继承的概念如果让原型对象等于另一个类型的实例,结果会怎么样呢?显然此时的原型对象将包含一个指向另一个原型的指针,相应的另一个原型中也包含着一个指向另一个构造函数的指针。原型链: 利用原型让一个引用类型继承另外一个引用类型的属性和方法。构造函数 原型对象 实例对象构造函数 原型对象 实例对象



构造函数.prototype = 原型对象





原型对象.constructor = 构造函数





实例对象.__proto__ = 原型对象





原型对象.isPrototypeOf(实例对象)





构造函数 实例对象 (类和实例)




构造函数.prototype = 原型对象

构造函数.prototype = 原型对象

原型对象.constructor = 构造函数

原型对象.constructor = 构造函数

实例对象.__proto__ = 原型对象

实例对象.__proto__ = 原型对象

原型对象.isPrototypeOf(实例对象)

原型对象.isPrototypeOf(实例对象)

构造函数 实例对象 (类和实例)

构造函数 实例对象 (类和实例)isPrototypeOf(); //判断是否 一个对象的 原型
//父类的构造函数 Sup
function Sup ( name ) {

this.name = name;

}

//父类的原型对象
Sup.prototype = {
constructor: Sup,
sayName: function () {

console.log(this.name);
}
}

//子类的构造函数 Sub
function Sub ( age ) {

this.age = age;

}

//如果子类的原型对象 等于 父类的 实例

//1, 显然此时的原型对象将包含一个指向另一个原型的指针
//2, 相应的另一个原型中也包含着一个指向另一个构造函数的指针。

//
实例对象.__proto__ = 原型对象
//
Sup的实例对象 和 Sup的原型对象 有一个关系

Sub.prototype = new Sup('zf');

//
console.log( Sub.prototype.constructor ); //function Sup () {}
//

//
console.log( Sub.prototype.__proto__ ); //Sup 的 原型对象


var sub1 = new Sub(20);

console.log( sub1.name ); //zf
sub1.sayName(); //zf

//父类的构造函数 Sup
function Sup ( name ) {

this.name = name;

}

//父类的原型对象
Sup.prototype = {
constructor: Sup,
sayName: function () {

console.log(this.name);
}
}

//子类的构造函数 Sub
function Sub ( age ) {

this.age = age;

}

//如果子类的原型对象 等于 父类的 实例

//1, 显然此时的原型对象将包含一个指向另一个原型的指针
//2, 相应的另一个原型中也包含着一个指向另一个构造函数的指针。

//
实例对象.__proto__ = 原型对象
//
Sup的实例对象 和 Sup的原型对象 有一个关系

Sub.prototype = new Sup('zf');

//
console.log( Sub.prototype.constructor ); //function Sup () {}
//

//
console.log( Sub.prototype.__proto__ ); //Sup 的 原型对象


var sub1 = new Sub(20);

console.log( sub1.name ); //zf
sub1.sayName(); //zf
原型链继承映射图原型链继承映射图继承的三种方式原型继承
//原型继承的特点:
//即继承了父类的模板,又继承了父类的原型对象。 (全方位的继承)
//父类
function Person ( name,age ) {

this.name = name;
this.age = age;

}

Person.prototype.id = 10;

//子类
function Boy ( sex ) {

this.sex = sex;


}

//原型继承
Boy.prototype = new Person('zz');

var b = new Boy();

console.log( b.name ); //zz
console.log( b.id ); //10

//原型继承的特点:
//即继承了父类的模板,又继承了父类的原型对象。 (全方位的继承)
//父类
function Person ( name,age ) {

this.name = name;
this.age = age;

}

Person.prototype.id = 10;

//子类
function Boy ( sex ) {

this.sex = sex;


}

//原型继承
Boy.prototype = new Person('zz');

var b = new Boy();

console.log( b.name ); //zz
console.log( b.id ); //10
类继承类继承 (只继承模板) 不继承原型对象 (借用构造函数的方式继承)
//父类
function Person ( name,age ) {

this.name = name;
this.age = age;

}

Person.prototype.id = 10;

//子类
function Boy ( name,age,sex ) {

//类继承
Person.call(this,name,age);

this.sex = sex;


}

var b = new Boy('zf',20,'女');

console.log( b.name ); //zf
console.log( b.age ); //20
console.log( b.sex ); //女
console.log( b.id ); //父类的原型对象并没有继承过来.



//父类
function Person ( name,age ) {

this.name = name;
this.age = age;

}

Person.prototype.id = 10;

//子类
function Boy ( name,age,sex ) {

//类继承
Person.call(this,name,age);

this.sex = sex;


}

var b = new Boy('zf',20,'女');

console.log( b.name ); //zf
console.log( b.age ); //20
console.log( b.sex ); //女
console.log( b.id ); //父类的原型对象并没有继承过来.


混合继承原型继承+类继承

//父类
(关联父类和子类的关系)
function Person ( name,age ) {

this.name = name;
this.age = age;

}

Person.prototype.id = 10;
Person.prototype.sayName = function () {
console.log( this.name );
}

//子类
function Boy ( name,age,sex ) {

//1 类继承
Person.call(this,name,age); //继承父类的模板

this.sex = sex;


}


//2 原型继承
//父类的实例 和 父类的 原型对象的关系.
Boy.prototype = new Person(); //继承父类的原型对象

var b = new Boy('z1',20,'女');

console.log( b.name );//z1
console.log( b.sex ); //女
console.log( b.id ); //10

b.sayName(); //z1


//父类
(关联父类和子类的关系)
function Person ( name,age ) {

this.name = name;
this.age = age;

}

Person.prototype.id = 10;
Person.prototype.sayName = function () {
console.log( this.name );
}

//子类
function Boy ( name,age,sex ) {

//1 类继承
Person.call(this,name,age); //继承父类的模板

this.sex = sex;


}


//2 原型继承
//父类的实例 和 父类的 原型对象的关系.
Boy.prototype = new Person(); //继承父类的原型对象

var b = new Boy('z1',20,'女');

console.log( b.name );//z1
console.log( b.sex ); //女
console.log( b.id ); //10

b.sayName(); //z1
ExtJs底层继承方式模拟ExtJs底层继承一部分代码
//ExtJs 继承
//2件事: 继承了1次父类的模板,继承了一次父类的原型对象


function Person ( name,age ) {

this.name = name;
this.age = age;

}

Person.prototype = {

constructor: Person,

sayHello: function () {


console.log('hello world!');

}

}

function Boy ( name,age,sex ) {

//call 绑定父类的模板函数 实现 借用构造函数继承 只复制了父类的模板

//
Person.call(this,name,age);


Boy.superClass.constructor.call(this,name,age);

this.sex = sex;


}

//原型继承的方式: 即继承了父类的模板,又继承了父类的原型对象。
//
Boy.prototype = new Person();
//只继承 父类的原型对象
extend(Boy,Person); // 目的 只继承 父类的原型对象 , 需要那两个类产生关联关系.

//给子类加了一个原型对象的方法。
Boy.prototype.sayHello = function () {

console.log('hi,js');

}

var b = new Boy('zf',20,'男');

console.log( b.name );
console.log( b.sex );
b.sayHello();

Boy.superClass.sayHello.call(b);

//extend方法

//sub子类, sup 父类
function extend ( sub,sup ) {

//目的, 实现只继承 父类的原型对象。 从原型对象入手

//1,创建一个空函数, 目的:空函数进行中转
var F = new Function(); // 用一个空函数进行中转。

//
把父类的模板屏蔽掉, 父类的原型取到。

F.prototype = sup.prototype; //2实现空函数的原型对象 和 超类的原型对象转换

sub.prototype = new F(); //3原型继承

//做善后处理。 还原构造器 ,
sub.prototype.constructor = sub; //4 ,还原子类的构造器

//
保存一下父类的原型对象 // 因为 ①方便解耦, 减低耦合性
② 可以方便获得父类的原型对象
sub.superClass = sup.prototype; //5 ,保存父类的原型对象。 //自定义一个子类的静态属性 , 接受父类的原型对象。

//判断父类的原型对象的构造器, (防止简单原型中给更改为 Object)
if ( sup.prototype.constructor == Object.prototype.constructor ) {



sup.prototype.constructor = sup; //还原父类原型对象的构造器


}

}


//ExtJs 继承
//2件事: 继承了1次父类的模板,继承了一次父类的原型对象


function Person ( name,age ) {

this.name = name;
this.age = age;

}

Person.prototype = {

constructor: Person,

sayHello: function () {


console.log('hello world!');

}

}

function Boy ( name,age,sex ) {

//call 绑定父类的模板函数 实现 借用构造函数继承 只复制了父类的模板

//
Person.call(this,name,age);


Boy.superClass.constructor.call(this,name,age);

this.sex = sex;


}

//原型继承的方式: 即继承了父类的模板,又继承了父类的原型对象。
//
Boy.prototype = new Person();
//只继承 父类的原型对象
extend(Boy,Person); // 目的 只继承 父类的原型对象 , 需要那两个类产生关联关系.

//给子类加了一个原型对象的方法。
Boy.prototype.sayHello = function () {

console.log('hi,js');

}

var b = new Boy('zf',20,'男');

console.log( b.name );
console.log( b.sex );
b.sayHello();

Boy.superClass.sayHello.call(b);

//extend方法

//sub子类, sup 父类
function extend ( sub,sup ) {

//目的, 实现只继承 父类的原型对象。 从原型对象入手

//1,创建一个空函数, 目的:空函数进行中转
var F = new Function(); // 用一个空函数进行中转。

//
把父类的模板屏蔽掉, 父类的原型取到。

F.prototype = sup.prototype; //2实现空函数的原型对象 和 超类的原型对象转换

sub.prototype = new F(); //3原型继承

//做善后处理。 还原构造器 ,
sub.prototype.constructor = sub; //4 ,还原子类的构造器

//
保存一下父类的原型对象 // 因为 ①方便解耦, 减低耦合性
② 可以方便获得父类的原型对象
sub.superClass = sup.prototype; //5 ,保存父类的原型对象。 //自定义一个子类的静态属性 , 接受父类的原型对象。

//判断父类的原型对象的构造器, (防止简单原型中给更改为 Object)
if ( sup.prototype.constructor == Object.prototype.constructor ) {



sup.prototype.constructor = sup; //还原父类原型对象的构造器


}

}

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools./code/HtmlJsRun测试上述代码运行效果。在线HTML/CSS/JavaScript代码运行工具在线HTML/CSS/JavaScript代码运行工具http://tools./code/HtmlJsRun关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》javascript面向对象入门教程JavaScript错误与调试技巧总结JavaScript数据结构与算法技巧总结JavaScript遍历算法与技巧总结JavaScript数学运算用法总结希望本文所述对大家JavaScript程序设计有所帮助。