Chapter 11. Creating Custom JavaScript Objects
JavaScript中所见的四种不同域的对象:
JavaScript内置的对象.
浏览器对象模型中的对象.
文档对象模型中的对象.
开发人员自己的自己定义的对象.
JavaScript中的原型(prototyping) prototype属性
1.对内置对象的扩展
(String添加trim()方法)
****************
String.prototype.trim = function(){
return(this.replace(/^[/s/xA00+]+/,"").replace(/[/s/xA0]+$/));
}
var strTemp = new String(" a ");
strTemp = strTemp.trim();
****************
(直接在对象实例上添加trim()方法)
*********************
var strTemp = " a ";
strTemp.trim = function(){...}
*********************
只是该种添加之后只有这个实力能够访问新增函数.
JavaScript中的共有和私有属性 this
1 .this 的作用:
this用来给对象的属性赋值.它作为对上级对象的引用 ,指向我们创建的新对象的一个实例.(准确地讲,this所做的是:创建一个可以从对象之外访问的共有属性 .)
而对象中使用var创建的变量属性则仅能 在对象内部访问,不能从对象之外访问,则成为私有成员.
JavaScript中的对象封装(函数在外部定义)
封装一个跨浏览器调节透明度的div对象
var theobjs = new Array( );
function alphaOpacity(value) {
var opacity = value * 100;
this.style.filter = "alpha(opacity:"+opacity+")";
}
function cssOpacity(value) {
this.obj.style.opacity = value;
}
function getOpacity( ) {
if (this.obj.style.filter) {
return this.obj.style.filter.alpha;
} else {
return this.obj.style.opacity;
}
}
function DivObj(obj) {
this.obj = obj;
this.objGetOpacity = getOpacity;
this.objSetOpacity = obj.style.filter ? alphaOpacity : cssOpacity ;
}
function changeOpacity( ) {
// div1
var currentOpacity = parseFloat(theobjs["div1"].objGetOpacity( ));
currentOpacity-=0.1;
theobjs["div1"].objSetOpacity(currentOpacity);
// div2
currentOpacity = parseFloat(theobjs["div2"].objGetOpacity( ));
currentOpacity+=0.1;
theobjs["div2"].objSetOpacity(currentOpacity);
}
function setup( ) {
theelements = document.getElementsByTagName("DIV");
for (i = 0; i < theelements.length; i++) {
var obj = theelements[i];
if (obj.id) {
theobjs[obj.id] = new DivObj(obj);
}
}
// set initial opacity
theobjs["div1"].objSetOpacity(1.0);
theobjs["div2"].objSetOpacity(0.0);
// event handlers
document.οnclick=changeOpacity;
}
链式构造函数和JS继承(apply和call方法)
apply 方法
应用某一对象的一个方法,用另一个对象替换当前对象。
apply([thisObj[,argArray]])
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
call 方法
调用一个对象的一个方法,以另一个对象替换当前对象。
call([thisObj[,arg1[, arg2[, [,.argN]]]]])
thisObj 可选项。将被用作当前对象的对象。
arg1, arg2, , argN 可选项。将被传递方法参数序列。
call 方法可以用来代替另一个对象调用一个方法。call 方法可将被调用函数的上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
函数的apply和call方法使你能在另一个对象的上下文环境中对一个方法进行应用和调用,实现函数功能的继承 .
如果apply和call方法使用在对象构造函数上,它会链起(chain 将两个函数功能有一定顺序拼接在一起)构造函数:从而实现一个类型对另一个类型的所有属性和方法的继承 .
obj.call(this,arg1,arg2,..., argn);
obj.apply(this,arguments);
apply与call的唯一区别是他们所传递的参数,它们的行为是相同的.
一次性对象
创建一次性对象的一种方式:为属性和方法创建一个关联数组,然后将它们赋给一个变量.
var oneoff={
variablea : "valuea",
variableb : "valueb".
method : function ( ) {
return this["variablea"] + " " + this["variableb"];
}
首先构造一个Object新对象,然后把属性和方法增加到对象实例上.
var oneOff = new Object( );
oneOff.variablea = "valuea";
oneOff.variableb = "valueb";
oneOff.method = function ( ) {
return this.variablea + " " + this.variableb;
};
使用构造函数来直接初始化赋值给一个变量.
var oneOff = new function( ) {
this.variablea = "variablea";
this.variableb = "variableb";
this.method = function ( ) {
return this.variablea + " " + this.variableb;
}
}
高级错误处理技术(try,throw和catch)
6个错误类型:
EvalError
当使用不正确(所执行的代码不正确)时,由eval抛出这个错误.
RangeError
数字值超出范围
ReferenceError
使用了无效的引用
当检测到无效的引用时,发生本错误。例如,如果所想要使用的引用为 null 时就会发生本错误。
SyntaxError
使用了无效的语法
当对错误语法的源文本进行解析时,发生本错误。例如,调用 eval 函数时其参数不是有效的程序文本,就会发生本错误。
TypeError
当变量不是所预期的类型时抛出
URIError
当不挣取得使用encodeURI()或decodeURI()时抛出
当检测到非法的统一资源标识符 (URI) 时发生本错误。例如,在被编码或解码的字符串中发现非法字符,就会发生本错误。
ConversionError
当试图将一个对象转换为其不能转换的某种类型时,产生本错误。
RegExpError
当正则表达式产生编译错误时,发生本错误。然而,只要该正则表达式经过了编译,就不会产生本错误。例如,如果使用无效语法,或标志不为 i 、g 、m ,或者同一标志出现多次的样式声明正则表达式时,就会发生本错误。
RangeError
当函数的某个给出的参数不在允许范围时,发生本错误。例如,当试图建立的 Array 对象的长度不是有效的正整数时就会发生本错误。
使用instanceOf(指明对象是否是特定类的一个实例)f可以知道错误是否为某种内置类型.
JavaScript中随机数生成方法
Math.random();生成0(包括)-1(不包括)之间的一个随机数.
Chapter 1. Introduction and First Looks
Script标记的有效属性: type,src,defer和charset
charset
属性定义了脚本使用的字符编码方式,除非需要使用的编码方式与文档所定义的字符编码方式不同,否则该属性通常不需要设置.
defer
一个非常有用的属性.它标识了该段script与页面的关系:是否需要立即执行,是否会动态地生成文档.当吧defer属性值设置为true时,它告诉浏览器:脚本不会生成任何文档内容,浏览器可以继续处理页面的其他部分,当页面处理和显示完成之后再返回到脚本.
defer与src属性联合使用(即引用外部js文件),可以使这些脚本在后台被下载,前台的内容则正常显示给用户。
[以下引用自http://www.cnblogs.com/stupidliao/articles/797698.html]
使用defer属性应注意的问题
1、不要在defer型的脚本程序段中调用document.write命令,因为document.write将产生直接输出效果(动态生成了文档)。
2、而且,不要在defer型脚本程序段中包括任何立即执行脚本 要使用的全局变量或者函数。
加上 defer 等于在页面完全在入后再执行,相当于 window.onload ,但应用上比 window.onload 更灵活!
// 该段click将在加载完成之后执行,能够正确执行
// 该段执行时将出错,因为myButton处于未定义状态.
JavaScript代码的位置
最佳方式 :将JavaScript程序代码块放入到外部JavaScript文件中.
JS块放置位置规则:
1.当JavaScript要再页面加载过程中动态建立一些Web页面的内容时,应将JavaScript放在body中.
2.定义为函数并用于页面时间的JavaScript应放在head标记中,因为它会在body之前加载.
*仅当页面载入器件脚本会建立一些Web页面内容时,才将脚本嵌入body中;否则,将其放在head中.
关键字var和作用域
使用var声明的变量,每个变量的作用域都是局部的,这意味着它们将只能在它们所定义的函数内部访问.
如果不使用var的话,变量的作用域就是全局的,也就是变量可以被Web页面中任何地方的JavaScript代码(或者在本页面所包含的任何外部JS库中)访问.
rules regarding scope:
If a variable is declared with the var keyword in a function, its use is local to that function.
If a variable is declared without the var keyword in a function, and a global variable of the same name exists, it's assumed to be that global variable.
If a variable is declared locally with a var keyword but not initialized (i.e., assigned a value), it is accessible but not defined.
If a variable is declared locally without the var keyword, or explicitly declared globally, but not initialized, it is accessible globally but not defined.
Chapter 5. Functions
创建函数的方式
JavaScript中主要有3种创建函数的方式:静态声明方式,动态匿名方式和直接量方式.
静态 声明的函数:
最常见的的函数创建方式是静态声明方式.这种方式开头有个function关键字,接着是括号,其中包含有0或几个参数,最后是函数体.
function functionname (param1, param2, ..., paramn) {
function statements
}
静态声明的函数只解析一次,就是在加载页面时,而每一次调用这个函数时,所使用的都是其第一次加载后结果.这种方法易于阅读和理解,也没有内存泄露之类的负面影响.
函数返回值及参数:
对于基于基本数据类型的变量(字符串,布尔量,数值),会以传值的方式传给函数. ----值传递.
对于对象类型的变量,则采用传引用的方式传给函数. ----引用传递.
动态匿名创建的函数(使用函数的构造函数)
函数也是对象. 使用构造函数,像创建String对象或其他对象那样,创建一个函数,然后将其赋值给一个变量,即为匿名函数.
var variable = new Function ("param1", "param2", ... , "paramn", "function body");
var sayHi = new Function("toWhom","alert('Hi ' + toWhom);");
sayHi("World!");
对于那些只有在运行时才能确定函数必须满足何种需要的情况,动态函数是定义功能的一种重要方法.
函数直接量
不使用构造函数,而像使用String那样,让JavaScript隐式地将函数语句进行包装.
var func = function (x, y) {
return x * y;
}
alert(func(3,3));
// invoking third argument as function
function funcObject(x,y,z) {
alert(z(x,y));
}
// third parameter is function
funcObject(1,2,function(x,y) { return x * y});
var func = function multiply(x,y)
{
return x * y;
}
// 这个名字只能在函数内部访问除非要实现一个递归函数时间可以使用.
英文:
Declarative function
A function in a statement of its own, beginning with the keyword function. Declarative functions are parsed once, static, and given a name for access.
Anonymous function
A function created using a constructor. It's parsed each time it's accessed and is not given a name specifically.
Function literal or function expression
A function created within another statement as part of an expression. It is parsed once, is static, and may or may not be given a specific name. If it is named, the name is accessible only from within the functi o n itself.
回调函数
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。
Array中需要用到回调函数的方法:fliter,forEach,every,map和some, 属 JavaScript 1.6标准,为保证在其他版本通用,使用时间可以加上下面对应的各段代码(摘自http://www.tutorialspoint.com/javascript/index.htm)
filter(过滤)方法:对数组中的元素进行过滤,将通过规则的值加入到返回的数组中去.( This method creates a new array with all elements that pass the test implemented by the provided function.)
if (!Array.prototype.filter) { Array.prototype.filter = function(fun /*, thisp*/) { var len = this.length; if (typeof fun != "function") throw new TypeError(); var res = new Array(); var thisp = arguments[1]; for (var i = 0; i < len; i++) { if (i in this) { var val = this[i]; // in case fun mutates this if (fun.call(thisp, val, i, this)) res.push(val); } } return res; }; }
every(每个都符合)方法:对数组中元素进行某个规则的测试,验证是否都符合该规则;对数组中的每个元素运行一个回调函数,直到返回一个假值.( This method tests whether all elements in the array pass the test implemented by the provided function.)
if (!Array.prototype.every) { Array.prototype.every = function(fun /*, thisp*/) { var len = this.length; if (typeof fun != "function") throw new TypeError(); var thisp = arguments[1]; for (var i = 0; i < len; i++) { if (i in this && !fun.call(thisp, this[i], i, this)) return false; } return true; }; }
some(某些符合)方法:与every相反,它对数组的每个元素运行一个回调函数,直到返回一个真值.(This method tests whether some element in the array passes the test implemented by the provided function.)
if (!Array.prototype.some) { Array.prototype.some = function(fun /*, thisp*/) { var len = this.length; if (typeof fun != "function") throw new TypeError(); var thisp = arguments[1]; for (var i = 0; i < len; i++) { if (i in this && fun.call(thisp, this[i], i, this)) return true; } return false; }; }
map(数据映射处理)方法:对数组的所有元素运行一个回调函数,对元素进行某种处理,将结果放入到返回数组中去.(This method creates a new array with the results of calling a provided function on every element in this array.)
if (!Array.prototype.map) { Array.prototype.map = function(fun /*, thisp*/) { var len = this.length; if (typeof fun != "function") throw new TypeError(); var res = new Array(len); var thisp = arguments[1]; for (var i = 0; i < len; i++) { if (i in this) res[i] = fun.call(thisp, this[i], i, this); } return res; }; }
forEach(每个都执行操作)方法::对数组的所有元素运行一个回调函数.(This method calls a function for each element in the array.)
if (!Array.prototype.forEach) { Array.prototype.forEach = function(fun /*, thisp*/) { var len = this.length; if (typeof fun != "function") throw new TypeError(); var thisp = arguments[1]; for (var i = 0; i < len; i++) { if (i in this) fun.call(thisp, this[i], i, this); } }; }
回调函数都有三个参数:元素,索引和数组
filter使用例子: