ECMAScript:为“不同种类的宿主”环境提供核心的脚本编程能力,因此核心的脚本语言是与任何特定的宿主环境分开进行规定的。其描述了 语法、类型、语句、关键字、保留字、运算符、对象。
ECMAScript分为 JavaScript、ActionScript、ScriptEase。
DOM:是HTML和XML的应用程序接口(API),Dom将整个界面规划成由节点层级构成的文档,HTML或XML页面的每个部分都是一个节点的衍生物。
DOM不是JavaScript专有的,事实上许多其他语言都实现了它,不过,Web浏览器中的DOM已经用ECMAScript实现了,现在是Javascript语言的一个很大组成部分。
BOM:可以对浏览器窗口进行访问和操作的特性。
通常浏览器特定的javascript扩展都被看做BOM的一部分。包括:
弹出新的浏览器窗口
移到、关闭浏览器窗口及调整窗口大小
提供web浏览器详细信息的导航对象
对cookie的支持
ie扩展了BOM,加入了ActiveXObject类,可以通过JavaScript实例化ActiveX对象。
如果变量未声明而使用typeof外的运算符会报错。
如:
//var a;
a+1;//报错
alert(a==1);//报错
alert(typeof(a));//undefined
类可以看成是对象的配方。
var paramStr = new String("Test Js Info");
paramStr = null;//强制废除对象
ECMAScript 是晚绑定,从不是强类型可以看出其不是早绑定。
ECMAScript对象并非同等创建的,一般可以创建并使用的对象有三种:
本地对象:独立于宿主环境的ECMAScript实现提供的对象,就是ECMA-262定义的类。
如:Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、
EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError
Array:
length 最大为 4294967295
join() 连接字符串值。
arrNum.join(","); 使用“,”连接数组中各项值。
Concat() 将参数附加在数组末尾。
Slice() 提取数组中的项,参数为 (开始位置和结束位置);(开始位置)。
Push() 压栈
Pop() 出栈
Unshift() 在数组头增加项
Shift() 去除数组头项
Sort() 升序
Reverse() 降序
Splice() 删除(0,2);替换而不删除(2,0,“aa”,“bb”);替换并删除(2,1,“aa”,“bb”)
EncodeURI()
DecodeURI()
EncodeURIComponent()
DecodeURIComponent()
Eval() 把参数解释为真正的ECMAScript语句,并把其插入该函数所在位置。
Math
Ceil() 向上舍入函数
Floor() 向下舍入函数
Round() 标准舍入函数
20111013笔记
URI方法 EncodeURI()、EncodeURIComponent()、DecodeURI()和DecodeURIComponent代替了BOM的Escape()和Unescape()方法,URI方法更可取,因为它们会对所有Unicode符号编码,而BOM方法只能对ASCII符号正确编码,尽量避免使用Escape()和Unescape()方法。
//创建对象
虽然ECMAScript越来越正式化,但创建对象的方法却被置之不理,且其规范化至今还遭人反对,一部分是语义上的原因(它看起来不像使用带有构造函数的new运算符那么正规),一部分是功能上的原因。功能问题在于用这种方式必须创建对象的方法。
/*
*工厂方法
*/
function Car() {
var car = new Object();
car.company = "上海大众";
car.name = "帕萨特 3.0 V6 DSG";
car.color = "red";
car.run = function() {
alert(this.company + "生产的" + this.type + "最高时速为:" + "240.0 ");
};
return car;
}
var tempcar = Car();
tempcar.color;
tempcar.run();
有些开发者在工厂函数外定义对象的方法,然后通过属性指向该方法,避免每次调用函数CreateCar都要创建新函数Run(意味着每个对象都有自己的Run版本,事实上,每个对象都共享了同一个函数)。
//在工厂函数外定义方法
function run() {
alert("this car is Running!");
}
function CreateCar(company,name,color,speed) {
var newCar = new Object();
newCar._company = company;
newCar._name = name;
newCar._color = color;
newCar._speed = speed;
newCar.Run = run;//指向方法
return newCar;
}
从功能上讲,这种外部定义,内部指向的方法解决了重复创建函数对象的问题,但是此函数看起来不像对象的方法。
所以引发开发者定义了构造函数的方式。
//构造函数方式
/*
*构造函数方法
*/
function House(length, width, height) {
this._length = length;
this._width = width;
this._height = height;
this.createHouse = function() {
alert("this house length: " + this._length + " ; width: " + this._width + " ; height: " + height);
}
}
var myhouse = new House(10, 7, 6);
myhouse.createHouse();
此方法就像工厂函数,构造函数会重复生成函数,为每个对象都创建独立的函数版本,不过,与工厂函数相似,也可以用外部函数重写构造函数,同样,这样做语义上无任何意义。这正式下面原型方式的优势所在。
//原型方式
/*
*原型方式
*/
function User(){//定义构造函数,其不可以带参数
}
User.prototype.name="";
User.prototype.age=24;
User.prototype.sex="";
User.prototype.Eat = function() {
alert(this.name + " is Eating");
};
var u = new User();
u.Eat();
alert(u instanceof User);
var u1 = new User();
var u2 = new User();
u1.name = "andy";
u1.Eat(); //andy is Eating
u2.Eat(); //mick is Eating
u1.address.pop();
alert(u1.address.toString()); //Asia,Europe,Africa,North America,South America,Oceania
alert(u2.address.toString()); //Asia,Europe,Africa,North America,South America,Oceania
属性address指向Array对象的指针,address是引用值,user的两个实例都指向了同一个数组。这意味着两个实例中的address会变化(任何一个实例执行中改变address)。
//混合的构造函数/原型方式
/*
*混合的构造函数/原型方式
*/
function Archive(archiveCode, startDT, endDT) {
this._archiveCode = archiveCode;
this._startDT = startDT;
this._endDT = endDT;
this._goods = new Array("AAA","BBB","CCC");
}
Archive.prototype.Create = function() {
alert("OK");
}
//动态原型方法
/*
*动态原型方式
*/
function Book(name, pagecount, bookman) {
this._name = name;
this._pageCount = pagecount;
this._bookMan = bookman;
this._auther = new Array("Tom", "Dived");
if (typeof Book._initialized == "undefined") {//如果_initialized未定义则为book添加Publish方法
Book.prototype.Publish = function() {
alert("book had Publish");
};
Book._initialized = true;//增加publish方法后,设置_initialized为true,将不在为对象重新设置publish方法
};
}
var b = new Book("JavaScript","550","图灵");
alert(b._name);
b.Publish();
var c = new Book();
c = null;
c.Publish();
//重新定义已有方法
Function.prototype.toString = function() {
alert(typeof this);
}
function bill() {
this.company = "HTC";
this.money = 1200;
}
bill.prototype.print = function() {
alert("aa");
}
bill.toString();
20111014
//继承
//对象冒充方法
function classA() {//父类
this.name = "tom";
this.getName = function() {
alert(this.name);
};
}
function classB() {//子类
this.newclassA = classA;//使用字段newclassA指向函数classA
this.newclassA();//通过调用构造函数,在classB构造classA中字段和函数
delete this.newclassA; //删除字段newclassA
//上边三句可看成
// this.newclassA = classA;
// this.name = "tom";
// this.getName = function() {
// alert(this.name);
// };
// delete this.newclassA;
}
var bb = new classB();
bb.getName();//tom
//这里存在一个弊端,如果classB和classA具有同名的属性或方法,classB具有高优先级。
function classB(){
this.newclassA=classA;
this.newclassA();
delete this.newclassA;
this.name = "Lily";
}
var bb = new classB();
bb.getName();//Lily
//call()方法
function classA1() {
this.name = "tom";
this.getName = function() {
alert(this.name);
}
}
function callclassA1() {
classA1.call(this);//将classA1中关键字this等于新创建的callclassA1对象。
}
var callA1 = new callclassA1();
callA1.getName();
//apply()方法
function classA1() {
this.name = "tom";
this.getName = function() {
alert(this.name);
}
}
function callclassA1() {
classA1.apply(this);
}
var callA1 = new callclassA1();
callA1.getName();
function classA1(name,working) {
this.getName = function() {
alert(name + " is " + working);
}
}
function callclassA1(_name, _working) {
//classA1.apply(this,new Array(_name,_working));
this.aworking = _working;
this.aname = _name;
this.aage = 25;
classA1.apply(this, arguments); // 一个数组,它的元素是要传递给函数 function 的参数值。
}
var callA1 = new callclassA1("tom", "eating");
callA1.getName();
20111017
//原型链 调用父类的构造函数时,没有给其传递参数,这是原型链中的标准做法,要确保构造函数没有参数传递。
//原型链弊端是不支持多重继承, 原因是子类的prototype被父类重写。
function classA() {
}
classA.prototype.name = "Tom";
classA.prototype.alertName = function(name) {
alert(name);
}
function classB() {
}
classB.prototype = new classA();
classB.prototype.name = "bb";
classB.prototype.alertName = function() {
alert(this.name);
}
var cb = new classB();
alert(cb.name);
cb.alertName("LiLy");
//混合方式
function classA(name) {
this._name = name;
}
classA.prototype.alertName = function() {
alert(this._name);
};
function classB(name, sex) {
classA.call(this, name);
this._sex = sex;
}
classB.prototype = new classA();
classB.prototype.alertSex = function() {
alert(this._sex);
};
var b = new classB("tom","boy");
b.alertName();
b.alertSex();
//例子 多边形 父类
function polygon(_sides) {
this.sides = _sides;
}
polygon.prototype.getArea = function() {
return 0; //占位
};
//三角形 子类
function triangle(iLength, iWidth) {
// polygon.call(this, 3);
this.length = iLength;
this.width = iWidth;
}
triangle.prototype = new polygon(3);
triangle.prototype.getArea = function() {//重写
return this.length * this.width / 2;
};
//四边形
function rectangle(iLength, iWidth) {
// polygon.call(this, 4);
this.length = iLength;
this.width = iWidth;
}
rectangle.prototype = new polygon(4);
rectangle.prototype.getArea = function() {//重写
return this.length * this.width;
};
var trgle = new triangle(3, 5);
alert(trgle.getArea());
var regle = new rectangle(10, 20);
alert(regle.getArea());