/*("javascript高级程序设计"读书笔记)
javascript对象基础
author:shine
*/
一、对象的应用
//对象的构成,对象声明和实例化,与java中一样,此处略过。
1.对象废除。
必须把对象的所有引用都设为null,才能算是把该对象废除。
2.早绑定和晚绑定
1)早绑定又称静态绑定,是指在编译时就确定值(即在变量或方法声明时就确定值),在java中有
private,final,static修饰的方法,和所有变量都是静态绑定,除持之外都是动态绑定的,简单来说:不能被
覆盖的方法和变量就是静态绑定,反之亦然。由于javascript是不是强类型语言,所以javascript不能早绑
定。
2)晚绑定又称动态绑定,是指在运行时,确定值(即在new的时候才确定值),javascript就是采用的动
态绑定。
二、对象的类型。
本地对象:(这里只介绍两种)由ECMAScript实现提供,独立于宿主环境的所有对象。
1.Array类
1)声明:(四种方式)
【a】限定长度的数组:var arr = new Array(n);
【b】不限长度的数组:var arr = new Array();
【c】在声明时赋值:var arr = new Array("a","b","c");
【d】简单的声明赋值:var arr = ["a","b","c"]; (注:是中括号不是小括号)
2)Array类的方法:
【a】toString()可以一次性输出所有的数组元素。
【b】join()方法可以按照特殊的字符串串联数组元素。
如:var arr = ["a","b","c"]; alert(arr.join("--shine--")); //output: a--shine--b--shine--c
【c】split()方法可以把字符串按指定字符分割成数组。
如:var arr = "bacad"; var arr = arr.split("a"); alert(arr.toString()); //output: b,c,d
【d】concat()方法可以附加数组元素(就像append())
如:var arr = ["a","b","c"]; arr = arr.concat("d","e"); alert(arr.toString());
【e】slice()方法返回具有特定项的新数组。(和String类的slice()一样)
如:var arr = ["a","b","c"]; arr = arr.slice(1,2); alert(arr.toString()); //output b
【f】栈操作 :push()入栈和pop()出栈
如:var arr =["a","b","c"]; arr.push("d"); alert(arr.toString()); //output a,b,c,d
alert(arr.pop()) //output d
【g】队操作 :push()入队和shift()出队
如:var arr =["a","b","c"]; alert(arr.shift()); //output a
【h】reverse():使数组元素反向;
如:var arr = [1,2,"x"]; arr.reverse(); alert(arr.toString()); //output x,1,2
【i】sort():对数组排序(这种排序会先把数组元素转换为字符串,才进行比较)
如:var arr = [1,23,4,24]; arr.sort(); alert(arr.toString()); //output 1,23,24,4
【j】splice():可以对数组进行指定位置的删除和替换。
如:var arr = [1,2,3,4]; arr.splice(1,2); alert(arr.toString()); //output 1,4
arr.splice(1,2,"a","d"); alert(arr.toString()) //output 1,a,d,4
2.Date类
1)声明
【a】无参数。如:var d = new Date();
【b】参数为parse()函数。如:var d = new Date(Date.parse("02/04/2008"));(其中月份 是第几个月,从
0开始,如02是第二个月,即3月)
【c】参数为UTC()函数。如:var d = new Date(Date.UTC(2008,2,4,13,5));(月份如上)
2)Date类的常用方法。
【a】toString()返回的是全格式日期和时间。
【b】toDateString()返回的是日期。(年,月,日)
【c】toTimeString()返回的是时间。(时,分,秒)
【d】getYear(),getMonth(),getDate(),getDay(),getHours(),getMinutes(),getSeconds();(还有相应的set方
法)用来得到或设置年,月,日,星期几,时,分,秒。
【e】getTime()返回时间的毫秒数,采用来测试性能。
内置对象:由ECMAScript实现提供,独立于宿主环境的所有对象,并且在ECMAScript程序开始执行时
实例化。(也就是说内置对象是一种特殊的本地对象)
1.Global对象
Global对象很特殊,它的目的是把javascript中所有的全局方法,全局变量都集中在一个对象上。如:
isFInite(),isNaN(),parseInt(),parseFloat(),NaN,Infinity,Object,Array,Function等等。Global不能直接
使用,也不能使用new。
(Global对象除上面的方法方法外,还有:)
【a】encodeURI():对字符串中非特殊字符进行编码。
【b】encodeURIComponent():对字符串中所有非标准字符进行编码。
【c】decodeURI():对应encodeURI的解码。
【d】decodeURIComponent():对应encodeURIComponent的解码。
【e】eval():把其中的字符串参数当作javascirpt表达式进行执行。(有点像sql中的exec);
2.Math对象。
Math对象属性中记住一个:PI (拼拼看 “派”:3.14...)
Math方法:
【a】max()和min():判断一堆数中的最大值和最小值。如:alert (Math.min(1,2,3,4,,5,6)) //output 1
【b】abs():求绝对值。
【c】ceil()和floor():求向上舍入和向下舍入的值。
【d】round():求四舍五入的值。
【e】power():求幂。
【f】sqrt():求算术平方根。
【g】random():返回0~1之间的随机数。
三、javascript中的“访问修饰符”。
1)在javascirpt中没有public ,private, protect ,但却有些小技巧来弥补。
用个小例子就可以搞清楚:
function Test() {
var color = "red"; //var 此处声明的是局部变量,可以被认为是私有变量
this.color2 = "green"; //this 此处声明的就是公有变量
var showcolor = function () { //var 此处声明的是局部方法,可以被认为是私有方法
alert(color);
};
this.showcolor2 = function() { //this 此处声明的是公有方法
alert(this.color2);
};
showcolor(); //在Test类中调用的是私有方法,是允许的
}
var test = new Test(); //output:red
alert(test.color); //output:undefined 在Test类外调用私有属性color,不被允许
alert(test.color2); //output:green 在Test类外调用公有属性color2,允许
alert(typeof test.showcolor); //output:undefined 在Test类外调用私有方法showcolor,不允许
alert(typeof test.showcolor2); //output:function 在Test类外调用公有方法showcolor2,允许
总结:在类内部,var修饰的属性或方法是私有属性或方法,this点出的属性或方法是公有属性或方法。
2)在javascript中没有static,但也可以用些小技巧来弥补。
如:
function Test() {
this.color = "red"; //公有非静态变量color
this.showcolor = function() { //公有非静态方法showcolor
alert(this.color);
}
}
Test.color2="green"; //静态变量color2;
Test.showcolor2 = function() { //静态方法showcolor2
alert(this.color2);
}
Test.showcolor3 = function() { //静态方法内调用非静态变量
alert(this.color);
}
alert(Test.color2); //output:green 静态属性color2可以通过[类名点属性名]访问。
alert(Test.color); //output:undefined 非静态属性color不能通过[类名点属性名]访问。
Test.showcolor2(); //output:green 静态方法showcolor2可以通过[类名点方法名]访问。
Test.showcolor();//错误,非静态方法showcolor不能通过[类名点方法名]访问。
Test.showcolor3();//output:undefined 由于没有创建对象所以showcolor3中的this没有指向,所以
this.color没有定义。
总结:由[类名.属性名]或[类名.方法名]创建的属性或方法就是静态方法。
四、定义类或对象的方式
1.工厂方式:
1)“散装版”
var test = new Object(); //先创建对象
test.name = "yaoyao"; //再加属性和方法
test.age = "22";
test.sal = "10000";
test.showsal = function () {
alert(this.sal);
}
test.showsal;
2)“封装版”
function createYaoYao() {
var test = new Object();
test.name = "yaoyao";
test.age = "22";
test.sal = "10000";
test.showsal = function () {
alert(this.sal);
}
return test;
}
var test1 = new createYaoYao();
test1.showsal();
3)“精装版”(带参数)
function createYaoYao(_name,_age,_sal) {
var test = new Object();
test.name = _name;
test.age = _age;
test.sal = _sal;
test.showsal = function() { //该方法随着createYaoYao()调用一次,就创建一次(浪费资源啊)
alert(this.sal);
}
return test;
}
var test2 = createYaoYao("yaoyao","22",10000); //可以加new,也可以不加new.
test2.showsal();
4)“改良精装版”:(避免了创建多余函数的缺陷)
function showsalOne () { //该方法只创建了一次
alert(this.sal);
}
function createYaoYao(_name,_age,_sal) {
var test = new Object();
test.name = _name;
test.age = _age;
test.sal = _sal;
test.showsal = showsalOne;
return test;
}
var test = createYaoYao("yaoyao",22,10000);
test.showsal();
总结:
a.工厂模式的特征,先创建对象,再往里面加属性,方法。(如果是“封装版”,还得有return)
b.在创建新对象时可以不加new,像普通方法一样调用。在强调一下,在javascript中new和this是配对使用
的,new创建的对象。只能调用在类内用this创建的属性和方法。这就是上面讲到的“公有性和私有性”。
2.构造函数方式:
function CreateYaoYao(_name,_age,_sal) {
this.name = _name;
this.age = _age;
this.sal = _sal;
this.showsal = function() {
alert(this.sal);
}
}
var test = new CreateYaoYao("yaoyao",22,10000);
test.showsal();
总结:
a.特征:构造函数方式没有再创建对象和return了,取而代之的是使用了this。javascript中this指的是调用
该方法或属性的对象。
b.构造函数方式也必须“改良”一下(如工厂方式一样),才能避免重复创建方法的缺陷。
3.原型方式
function Test() {};
Test.prototype.name = "yaoyao";
Test.prototype.age = 22;
Test.prototype.sal = 10000;
Test.prototype.showsal = function() {
alert(this.sal);
}
var test = new Test();
test.showsal();
总结:
a.特征:利用prototype去除了重复创建方法的缺陷。因为所有对象中都存储的是指向函数的指针。
b.但还存在缺陷:不能“参数化”。
4.混合的构造函数/原型方式
function Test(_name,_age,_sal) {
this.name = _name;
this.age = _age;
this.sal = _sal;
}
Test.prototype.showsal = function () {
alert(this.sal);
}
var test = new Test("yaoyao",22,10000);
test.showsal();
总结:
a.特征:属性使用构造函数方式,而方法采用原型方式。
b.弥补了原型方式不能”参数化“的缺点。
5.动态原型方式
function Test(_name,_age,_sal) {
this.name = _name;
this.age = _age;
this.sal = _sal;
if(typeof Test._init == "undefined") {
this.showsal = function() {
alert(this.sal);
}
Test._init = true;
}
}
var test = new Test("yaoyao",22,10000);
test.showsal();
总结:
a.特征:在视觉上进行了封装,和java中类视觉上差不多。
b.但是由于_init变量是Test的静态属性,所以可以在外部进行修改,如:Test._init=undefined; 如此就破
环了这个类。
6.混合工厂方式。
在工厂方式的基础,用new来声明类。存在和工厂方式一样的缺陷,用的很少,再此不做细说。
综合一下:
一句话:提倡使用混合构造函数/原型方式
/*
下一篇: javascirpt继承基础 2月7日
*/