javascript 中的对象函数闭包

Javascript 对象的创建

 

1.

var a=new Object();

a.x=1;a.y=2;

2.

var b={x:1,b,2}

3.

function Point (x,y){this.x=x;this.y=y}

var point=new Point(1,2); 
 

javascript 中任何合法的函数都可以作为对象的构造函数。一旦函数作为构造函数执行,它内部的 this 属性将引用对象本身 。

    构造函数通常没有返回值,它们只是初始化 this 传进来的对象(例如一个函数作为构造函数后,它内部的 this 属性引用了那个对象,如果对象有 x,y 等属性就可以通过 this.x this.y 来初始化它)。

    构造函数有返回值的情况:

 

function test(){

  this.name='test';

  return 1;

}

function test1(){

  this.name='test1';

  return new String("test1");

}

var a=new test();

alert(a.name);//test

alert(a);//object

var b=new test1();//

alert(b.name);//undefined

alert(b);//test1 
 

如果一个函数的返回类型为引用类型 (数组,对象或函数)的数据时当这个函数作为构造函数用 new 运算符执行构造时,构造函数体内的 this 值丢失,取而代之的是被返回的对象。

如果函数的返回值是一个值类型 ,那么这个函数作为构造函数用 new 运算执行构造时,它的返回值将被舍弃。 new 表达式的结果仍然为 this 所引用的对象。

new foo() 的执行过程可以简单的理解为:

1.        创建一个新的对象实例,并继承foo.prototype

2.       将this绑定到这个新创建的对象上,new foo 跟new foo()是等价的在没有参数时

3.       这个构造函数返回的对象成了这个new表达式的结果。如果构造函数内没有返回对象,那么第一步中创建的对象将作为返回结果。more>>

 

对象的属性,方法:

对象的属性方法有四种类型

1.       私有类型 外界不可直接访问

2.       动态公有类型:外界可以访问,每个实例有一个副本,互相之间不影响。

3.       静态公有类型(原型类型):所有实例共象的一个副本

4.       类属性:类型而非对象的属性,没有构造函数时也可以直接访问

如下“

 

function Test(){

var x=0;// 私有属性

this.y=1;// 动态公有类型

}

var a=new Test();

Test.z=3; // 类属性

Test.prototype.w=20; // 静态公有类型

alert(a.z);//undefined

alert(Test.z);

alert(a.w);//20

a.w=40;

alert(a.w);//40 动态公有属性代替了原型类型

delete(a.w);

alert(a.w);//20 
 

prototype:

   javascript 中每个类型只有一个原型,默认情况下是一个 Object 对象 ,但每一个实例可有多个类型,如:

 

function A(){}

A.prototype=new Object()// 可省略

A.prototype.w=10;

function B(){}

B.prototype=new A();//new A() 的过程:生成对象,将 new Object(),w 这些属性赋给这个对象,

//B 的 prototype 指向的对象中有了 new Object 和 w 这些属性 ……

function C(){}

C.prototype=new B();

var c=new C();

alert(typeof(c));//object

alert(c instanceof B);//true

alert(c instanceof A)//true

alert(c.w); 
 

将一个属性添加为 prototype 的属性后这个属性为该类型的所有的对象所共享,而且这种共享是只读的,任何一个实例中只能通过同名的属性来覆盖它,但不能改变它。一个对象在查找某个属性时,先查找自身域的属性表,如果有则返回,如果没有,查找其 prototype 域,如果还没有则递归的查找 ptototype 所指对象的 prototype 域。

 

根据 new funciton 的执行过程和 prototype 的用法可以方便的创建大量副本

 

 

var p1=new Point(1,2);

var points=[];

var pointPrototype=function(){}

pointPrototype.prototype=p1;

for(var i=0;i<1000;i++){

points[i]=new pointPrototype();

} 
 

 

 

对象的继承:

模拟:

1.       构造继承

 

function BaseObject(name){

this.getName=function(){return name}

}

function ChildObject(name){

  BaseObject.call(this,name);// 这里的 this 指的是 ChildObject 的对象(设为 o ),因此调用 call 后, //BaseObjict 原来构造函数中的 this 就成了 o ,然后 o 就有了 getName 属性。

// 所以这里相当有了 this.getName=function(){return name} 这行代码

}

var c=new ChildObject('chen');

alert(c.getName()); 
 

但是这样不能继承父类型中的静态属性。

2.       原型继承法

 

function MyDate(){}

MyDate.prototype=new Date();

var date=new MyDate(); 

这样并不能调用 DatetoString 方法。也就是说核心对象不能被继承。

 

由于类的原型 (prototype) 实际上是一个 Object 的实例,它不能再次被实例化 ( 它的初始化在脚本装载时已经执行完毕 ) 。这么意思呢?我们知道在新建对象实例时,我们使用语句 new MyDate() ,这时我们可以看做 JavaScript 脚本引擎把 prototype 的一个浅拷贝作为 this 返回给类的实例 ( 这里其实没有 发生拷贝,只是利用浅拷贝 这个概念来帮助理解 ) ,如果类没有附加任何原型属性和原型方法,那么就等于返回了一个 new Object() 实例,如果 prototype 的原型属性类里有对象型的属性,那么就会造成共享对象实例的问题 ( 类似于在传统 OOP 的类定义中使用了 static 修饰符来修饰了属性 ) 如下面的实例。结果中 array 中的数组都打印的是 1,2,3,4count 是不同的。这是因为数组是引用类型的而整数是值类型的。

 

<script>

            function Collect(){

                this.arr=[];

                this.count=0;

            }

            function ArrayList(){

               

            }

            ArrayList.prototype=new Collect();

            ArrayList.prototype.constructor=ArrayList;

// 为什么上面要把 ArrayList 赋值给新 prototype 的 constructor 呢?如果不做这个赋值, // 当我们从 ArrayList 的实例中, 通过 XXX.prototype.constructor 去取其构造函数,将会 // 获得 Collection 。这不是我们的本意,而且这是使用 instanceof 关键之比较对象实例和 // 对象也会出错。

 

            var array=new ArrayList();

            array.arr.push(1);

            array.arr.push(2);

            array.count=1;

            var array2=new ArrayList();

            array2.arr.push(3);

            array2.arr.push(4);

            array2.count=2

            for(var i=0;i<array.arr.length;i++){

                alert(array.arr[i]);

            }

            for(var i=0;i<array2.arr.length;i++){

                 alert(array2.arr[i]);

            }

            alert(array.count);

            alert(array2.count);

        </script> 
 

3.       实例继承

function MyDate(){ var instance =new Date(); instance.someFunction=..; return instance; }

 

用闭包保证 this 不被修改:

 

function MyClass(){

    var $this=this;

    var foo=function(){

        return $this.foo.apply($this,arguments);

    }

} 
 

利用闭包构造私有域

 

var a=0;var b=1;

            (function(){

                showAB=function(){

                    alert(a+"  "+b);

                }

                var a=1;

                var b=2;

                alert(a);alert(b);

                showAB();

            })()

a=2;

b=5;

            showAB();// 输出仍为 1,2 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值