在JS中,Object是所有类的基类,使用Object类来创建自定义对象时,可以无需定义构造函数(constructor,prototype,hasOwnProperty(property))
var per = new Object(); per.name = 'zhangsan'; per.age = ; alert(per.name + per.age);
我们想在程序中得到一个对象变量,只要能存储大量数据即可,这个时候,我们可以考虑使用Object类。Object类避免了对构造器的定义。 Object类下另一个常用的属性:hasOwnProperty
var per = new Object(); per.name = 'zhangsan'; per.age = ; if per.hasOwnProperty('email'){ alert('具有email'); }else{ alert('无email'); }
2.静态属性
在有些面向对象的语言当中,可以使用static关键字定义类的静态属性或者静态方法,在JS中,可以进行模拟。
语法:
类名.属性名
类名.属性=function(){}
function Person(){ } Person.count = ; var p = new Person(); Person.count++; var p = new Person(); Person.count++; var p = new Person(); Person.count++; alert(Person.count);
添加静态属性和静态方法:
function Person(){ Person.count++; //静态属性 Person.getCount=function(){ //静态方法 alert('当前共有' + Person.count + '个人'); } } Person.count = ; var p = new Person(); var p = new Person(); var p = new Person(); Person.getCount();
3.闭包
概念:所谓闭包,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因此这些变量也是该表达式的一部分。
提出一个问题:
function display(){ var i=; } display(); //在这里,想访问局部变量i
在全局中,不能访问局部变量i,因为作用域不同,而且,在display函数执行完毕后,局部变量i会被回收。 闭包的功能:“访问局部变量”和“使变量所占的内存不被释放”
//例 function fn(){ function fn(){ alert('hello'); } return fn; //返回fn函数首地址 } var test=fn(); //test也指向了fn函数的首地址 test();
通过例1我们知道:变量是可以指向函数的首地址的,函数也可以返回另一个函数的首地址。
//例 function fn(){ var i = ; function fn(){ alert(i); } return fn; //返回fn函数首地址 } var test=fn(); //test也指向了fn函数的首地址 test();
通过例2我们知道:使用一个拒不函数包含变量i,这样局部变量i的内存不会被回收。
//例 function fn(){ var i = ; function fn(){ alert(i++); } return fn; //返回fn函数首地址 } var test=fn(); //test也指向了fn函数的首地址 test(); test(); test();
在例3中,因为i的内存永远不会被回收,所以每次调用fn2,i的值会+1。运行的结果是弹出10,弹出11,弹出12。
闭包的原理:在例3中,共有三个作用域:全局作用域,fn1的作用域,fn2的作用域。在全局作用域里有test=fn1(),其实这句话就相当于test=fn2。在fn1作用域里有 var i=10和return fn2,在fn2作用域例有alert(i++)。当全局作用域下的test=fn1()执行时,test指向了fn2的作用域,这个时候fn2作用域下的i被全局作用域钩住,根据作用域链的法则,fn2下并没有定义i,所以在fn2下的i往上一层作用域上找,找到了fn1作用域下的var i=10。所以全局的test钩住了fn2的i,fn2的i钩住了fn1的i,所以fn1运行完毕后,不会被回收。
4.私有属性
在面向对象思想中,对于有些敏感的,不想公开的成员可以定义为私有的,在JavaScript中可以模拟这个功能。
语法:
function Person(p_name){ var name = p_name; this.age }
var :私有
this :公有
function Person(p_name,p_age){ this.name = p_name; var age = p_age; } var p = new Person('zhangsan',); alert(p.name); alert(p.age);
在上面这个例子中,我们想用 var 来表示私有成员属性,但 Person 构造函数执行完毕后, age 会被回收,不能当做成员属性来使用。
function Person(p_name,p_age){ this.name = p_name; var age = p_age; this.setAge=function(a){ age = a; } this.getAge=function(){ return(age); } } var p = new Person('zhangsan',); p.setAge(); alert(p.getAge());
this.setAge和this.getAge两个方法使用到了局部变量age,所以age不会被回收。
如果只有set方法,说明该属性是只写属性。
如果只有get方法,说明该属性是只读属性。
5.call和apply的使用
call和apply的功能:使用指定的对象调用当前函数。call和apply的功能完全相同,只是在语法上略有不同。
语法:
call([thisObj[,arg1[,arg2[,argN]]]])
第一个参数:函数执行时,this指向谁
后面的参数:根据需要顺序指定
apply([thisObj[,argArray]])
第一个参数:函数执行时,this指向谁
第二个参数:数组,表示参数集合
在js中,函数有几种调用形式: