`
luhantu
  • 浏览: 199817 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JavaScript 面向对象

阅读更多

自己以前从来没有接触过javascript的,最近HTML5炒得很火,好像Flash马上就没有前途了一样。小组最近时间空下来就搞了个技术沙龙,每个人研究下HTML的一些知识,为以后的职业发展做些准备。

下面整理了下关于javascript的面向对象的一些知识。

1.关于javascript的类

 

function Person(myName,mySex){
this.name = myName;
this.sex = mySex;
this.showInfo = function (){
	return ("my name is " + this.name + " ," + this.sex);
}
}

 

 this 代表的类似于全局变量

 var 代表的类似于私有变量

2.对于类的使用 可以看到跟标准的OO很像的。

 

 

function testClass(){
var p = new Person("beauty", "female");
p.sex = "male";
document.write(p.showInfo());
}
function showConstructor(){
var p = new Person("beauty", "female");
document.write(p.constructor);
}
function referenceParameter(){
var p = new Person("beauty", "female");
var name = p.name;
var sex = p["sex"];
}
function referenceMethod(){
var p = new Person("beauty", "female");
var info = p.showInfo();
var info2 = p["showInfo"]();
}

 

 

3.prototype 关键字

prototype自动的在构造函数中生成,可以动态的为类定义公共的变量和公共的方法.

prototype还有一个默认的属性:constructor,是用来表示创建对象的函数的(即我们OOP里说的构造函数)constructor属性是所有具有prototype属性的对象的成员。它们包括除GlobalMath对象以外的所有JScript内部对象。constructor属性保存了对构造特定对象实例的函数的引用。 

对于对象的prototype属性的说明,JScript手册上如是说:所有 JScript 内部对象都有只读的 prototype 属性。可以向其原型中动态添加功能(属性和方法),但该对象不能被赋予不同的原型。然而,用户定义的对象可以被赋给新的原型。

对于JScript的解释引擎,它在处理".""[keyName]"引用的对象的属性和方法时,先在对象本身的实例(this)中查找,如果找到就返回或执行。如果没有查找到,就查找对象的prototype(this.constructor.prototype)里是否定义了被查找的对象和方法,如果找到就返回或执行,如果没有查找到,就返回undefined(对于属性)runtime error(对于方法) 

 

 

function sayHello(){
	return ("Hello");
}
function prototypeFunc(){
var p = new Person("beauty", "female");
Person.prototype.sayHello = sayHello;
Person.prototype.sayHi = function(){
	return ("Hi");
}
var p2 = new Person("ugly", "female");
document.write(p2.sayHello() + "," + p2.sayHi() + "," + p2.showInfo());
}

 注意:

 

prototype != static

define by Class(Person),used by instance(p)

4.__proto__ 属性

var p = new Person("a","b");

 

我们来看看这个new究竟做了什么?我们可以把new的过程拆分成以下三步:

<1> var p={}; 也就是说,初始化一个对象p。

<2> p.__proto__=Person.prototype;

<3> Person.call(p);也就是说构造p,也可以称之为初始化p.

 

关键在于第二步,我们来证明一下:

var Person = function () { };

var p = new Person();

alert(p.__proto__ === Person.prototype);

这段代码会返回true。说明我们步骤2的正确。

 

 

我们在这里简单地说下。每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样一直找下去,也就是我们平时所说的原型链的概念。

按照标准,__proto__是不对外公开的,也就是说是个私有属性,但是Firefox的引擎将他暴露了出来成为了一个共有的属性,我们可以对外访问和设置。

 

 

function __protoFunc(){
var p = new Person("beauty", "female");
p.__proto__.story = function(){
	return ("long long ago...there was a...");
}
p.__proto__.mom = "Joy";
var p2 = new Person("handsome", "male");
document.write(p2.showInfo() + "--" + p2.mom + "" + p2.story());
}

 

 所以p.__proto__.mom实际是修改了Person的prototype了。

5.Return,Object,get,set

return跟其他程序的return关键字功能一样:

 

 

function ReturnFunc(){
return{
name:"Joy",
sex:"female",
showInfo:function(){
	return ("Hi, I am " + this.name, + " " + this.sex);
}
}
}
function testRetunFunc(){
var test = new ReturnFunc();
document.write(person.shoInfo());
}

 

 任何一个类都是基础自Object的

 

 

function PrototypeObject(){
}
function prototypeObjTest(){
PrototypeObject.prototype = {
name:"Joy",
sex:"femal",
showInfo:function(){
	return ("Hi I am " + this.name + "---" +this.sex);
}
}
var test = new PrototypeObject();
document.write(test.name + "-----" + test.showInfo());
}

 get set 方法和普通方法一样,只不过你可以设定一些特别的名字就可以了。譬如getLabel, setLabel等方法。

 

6.继承

1 就是给用户自定义对象赋新原型

 

 

function ChildClass(){
}
function extendTest1(){
ChildClass.prototype = new Person("beauty child","baby girl");

var child = new ChildClass();
document.write(child.showInfo());
}

 

 但是这样的继承有些问题,例如:

 

 

function Person(name,age)
{
	var gender = 1;
	this.showInfo = function()
	{
		document.write(gender++ + "person" + this.age);
	}
	this.name = name;
	this.age = age;
}

function Employee2()
{
	
}


function clickHandler()
{
	Employee2.prototype = new Person("kenny",19);
  	var test = new Employee2();
  	test.showInfo();
  	var test2 = new Employee2();
  	test2.showInfo();
}

 

 你会发现gender第一是1,第二次是2,就是说私有变量没有回复原始值。

如果在test2之前再Employee2.prototype = new Person("kenny",19);赋一次原型,就不会出现此问题。

这个问题还没有找到找到解释。

2.在子类中使用$super来实现。

 

 

function ChildClass1(myName,mySex){
this.$super = Person;
this.$super(myName, mySex);
} 

 

 这种方法是最好的,没有上面说的那些问题,建议以这样的方式来做继承。

7.Static静态的方法和变量

 

 

Person.staticProperty = "123"; 
Person.showInfo = function(){};

 

 和真正的oo一样,static不能被继承。

静态类:

 

function StaticClassTest(){
	throw new Error("This is static class,can not be instance!");
}

 8.override & overwrite

和真正的oo一样,也支持重载和重写。

 

还可以参考一些原型链的文章,有助于理解:

http://hi.baidu.com/mjy_camilla/item/77e9bbef2a6f58d9eb34c958

http://blog.csdn.net/junkaih2008/article/details/2653142

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics