原文地址:http://www.cnblogs.com/xiaofu/articles/1613463.html
本文是在原作者的基础上挑选摘录
1.1 数字转换为字符串
var number=100;
var s=number.toString();
还可以指定转换的基数,
var s=number.toString(16);
还有三个函数可以精确指定转换后的数字格式,toFixed(),toExponential(),toPrecision();
1.2 字符串转换为数字
当把一个字符串用于数字环境中,它也会自动地转换为一个数字,
Var t=”21” * “2”;
利用这一优点,只要把一个字符串减去0就可以将其转换为一个数字。
Var t=string_value-0;
ParseInt()和ParseFloat(),这两个函数可以从字符串开始处转换和返回任何的数字,忽略或舍去非数字部分。
ParseInt()甚至可以接受另一个参数来指定要解析的数字的基数。合法的范围在2至36之间。
ParseInt(“012”,2);
ParseInt(“0x23”);//默认返回10进制
这两个函数不能把指定的字符串转换为数字,它们会返回NaN.
ParseInt(“ele”);//返回NaN
1.3 undefined
使用了已经声明但还没有赋值的变量时,又或者使用了一个并不存在的对象属性时,返回的就是这个值。注意这个特殊的undefined值不同于null。但是==运算符却将两者相等的。
1.4 in运算符,检查属性是否存在
var point={x:1,y:2};
var has_x_record=”x” in point;//return true
var has_z_record=”z” in point;//return false
1.5 delete运算符
它将删除运数所指定的对象的属性、数组元素或变量或函数的属性。如果删除成功返回true,若不能删除,返回false。并非所有的属性和变量都是可以删除的,某些内部的核心和客户端属性不能删除,用var语句声明的用户定义变量也不能被删除。
注意,删除属性、变量(数组不一样)不只是把它们的值设置为undefined,当删除它们后,它们全部变成未定义的,也即不存在的,再次尝试读取它们时会出错。
Delete所能影响的只是属性值,并不能影响被这些属性引用的对象,即这些对象只要用其它属性引用就还存在!
1.6hasOwnProperty和isPrototypeOf方法
hasOwnProperty:是用来判断一个对象是否有你给出名称的属性或对象。不过需要注意的是,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员。
isPrototypeOf是用来判断要检查其原型链的对象是否存在于指定对象实例中
如果此方法所属的对象是参数的原型对象,那么就返回true。
Var o={};
Object.prototype.isPrototypeOf(o);//true
Object.isPrototypeOf(o);//false
1.7函数定义和调用
JS也不会检测传递的数据是不是那个函数所要求的类型,也不会检测传递给它的参数个数是否正确。如果传递的参数比函数需要的个数多,那么多余的值会忽略掉; 如果传递的参数比函数需要的个数少,那么所被忽略的参数就被赋予undefined。
函数命名
函数名小写字母开始!
var f=function(x) {return x*x;}
或
var f=fucntion fact(x) {return x*x;}//也可以加函数名字
var test=(function(x) {return x*x;})(10);//定义后马上调用
1.8定义自己的函数属性
当函数需要使用一个在调用过程中都保持不变的值时,使用function对象的属性比定义全局变量更加方便。也即我们可以为函数定义属性。
例:
uniqueInteger.counter=0;
function uniqueInteger(){
return uniqueInteger.counter++;
}
这里的counter相当于函数的静态局部变量一样!!!
1.9作为方法的函数
var calculator={
operand1:1,
operand2:2,
compute:function(){
this.result=this.operand1+this.operand2;
}
}
calculator.compute()
任何用作方法的函数都被效地传递了一个隐式的参数,即this,调用对象。
当一个函数作为函数而不是作为方法调用的时候,这个this关键字引用全局对象.
当一个嵌套的函数(作为函数)在一个包含的函数之中调用,而这个包含的函数是作为方法调用的,this关键字在包含的函数中有一个值,但是它却引用嵌套的函数体的内部的全局对象。
1.20原型和继承(下一篇详细说)
JS对象从它的原型那里继承属性
一个对象的原型就是它的构造函数的prototype属性的值。所有的函数都有一个prototype属性,当这个函数被定义的时候,prototype属性自动创建和初始化。Prototype属性的初始化是一个对象,这个对象中带有一个属性。这个属性名为constructor,它指回到和原型相关联的那个构造函数。添加给这个原型对象的任何属性,都会成为被构造函数所初始化的对象的属性。
原型对象是放置方法和其他不变属性的理想地方。
注意,继承作为查找一个属性值的过程的一部分。属性并非从原型对象那里复制到新对象,它们只是像那些对象的属性一样地出现。首先,使用原型对象可以显著地减少每个对象的内存数量。其次,即便是在对象创建以后才添加到原型中的属性,对象也可以继承它。
读取和写入继承的属性
当读取对象o的属性p的时候,JS首先检查o是否有一个名为p的对象。如果没有,它接下来检查o的原型对象是否有一个p的属性。
当写入一个对象的属性值的时候,JS不会使用原型对象。
1.21JS中模拟类
实例属性
每个对象都拥有它的实例属性的一份单独拷贝。默认情况下,JS中的任何对象属性都是一个实例属性,这里我们特指由构造函数创建和初始化的属性。
实例方法
在JS中,通过构造函数的原型对象中的一个属性设置为一个函数值,从而定义了一个实例方法。每个实例方法由一个类的所有实例方法共享。
类属性
也就是为构造函数定义属性,跟普通的函数一样的。
Test.Unique=2;
类方法
也就是为让相应函数成为构造函数的一个属性而已。
Test.f=function() {}
私有成员
JS中没有私有成员。一般把属性设置为以下划线开头的属性。
来自JS高级程序设计:定义类的常用两种方法
1.混合构造函数/原型方式
Function Car(scolor,sdoors){
This.color=scolor;
This.door=sdoors;
}
Car.prototype.showColor=function (){ alert(this.color);};
2.动态原型方法
Function Car(scolor,sdoors){
This.color=scolor;
This.door=sdoors;
If( typeof Car._initialized==”undefined”)
{
Car.prototype.showColor=function(){alert(this.color);};
Car._initialized=true;
}
}
1.22通用对象模型
toString方法
当定义一个类时,就为它定义一个toString()方法。
valueOf方法
如果一个类需要把对象转换为某种基本类型,一般是转换为数字。那么可以为这个类定义此方法。
注意,在某些条件下,在把一个对象转换为一个字符串的时候,valueof方法可以比toString()方法更优先使用。因此如果要把类强制转换为一个字符串时,可能需要更加显式调用toString()方法。
1.23超类和子类
例:function Rectangle(w,h){this.width=w;this.height=h;}
Rectangle.prototype.area=function(){return this.width*this.height;}
Function DerivedRectangle(x,y,w,h)
{
Rectangle.call(this,w,h);//this就是子类的一个实例对象,那么超类Rectangle成了这个实例对象的一个属性方法来调用,那么这个方法里的this就变成了当前的实例对象,显然里面的属性也成了这个实例对象的属性!!
This.x=x;
This.y=y;
}
DerivedRectangle.prototype=new Rectangle();
Delete DerivedRectangle.prototype.width;
Delete DerivedRectangle.prototype.height;
DerivedRectangle.prototype.constructor=DerivedRectangle;
DerivedRectangle.prototype.contains=function(){return this.x+this.y+this.width+this.height;
}
首先超类构造函数作为新创建的对象的一个方法调用的。必须显示地把这个原型对象创建为超类的一个实例,然后显示地设置原型对象的constructor属性。另外,可以删除超类构造函数在原型对象中创建的所有属性,因为我们要的原型对象从它的原型那里继承的那些属性。
1.23constructor属性
返回对创建此对象的数组函数的引用。
<script type="text/javascript">
function employee(name,job,born)
{
this.name=name;
this.job=job;
this.born=born;
}
var bill=new employee("Bill Gates","Engineer",1985);
document.write(bill.constructor);
</script>
输出:
function employee(name, jobtitle, born)
{this.name = name; this.jobtitle = job; this.born = born;}
1.24一个变量第一次被声明时赋了值,而接着又再一次声明了它,但没有赋值,那么这时使用它时,它还是显示第一次声明时的值。这种在检测名称空间是否存在时很合适。
如:var tt=2;
var tt;
alert(tt);//显示2
1.25匿名函数
闭包
由于闭包会携带包含它的函数的作用域,因些会比其它函数占用更多的内存。过度使用闭包可能会导致内存占用过多。一般建议少用闭包。
关于this对象
一般this对象在运行时基于函数的执行环境绑定的:在全局环境中,this等于window,而当函数作为某个对象的方法调用时,this等于那个对象。不过。匿名函数的执行环境具有全局性,因此其this对象通常指向window。
例: var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()()); //"The Window"
出现上面的情况的原因是:每个活动对象在被调用时,其活动对象会自动取得两个特殊变量:this和arguments。内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此不可能直接访问外部函数中的这两个变量。
解决方法,把外部的this对象放在一个闭包能访问到的变量里:
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()()); //"MyObject"
私有变量
多查找作用域链中的一个层次,就会在一定程序上影响查找速度。而这正是使用闭包和私有变量明显的不中之处。
2.1 call方法:
语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
2.2 apply方法:
语法:apply([thisObj[,argArray]])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
a、
function add(a,b)
{
alert(a+b);
}
function sub(a,b)
{
alert(a-b);
}
add.call(sub,3,1);
这个例子中的意思就是用 add 来替换 sub,add.call(sub,3,1) == add(3,1) ,所以运行结果为:alert(4); // 注意:js 中的函数其实是对象,函数名是对 Function 对象的引用。
b、
function Animal(){
this.name = "Animal";
this.showName = function(){
alert(this.name);
}
}
function Cat(){
this.name = "Cat";
}
var animal = new Animal();
var cat = new Cat();
//通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。
//输入结果为"Cat"
animal.showName.call(cat,",");
//animal.showName.apply(cat,[]);
call 的意思是把 animal 的方法放到cat上执行,原来cat是没有showName() 方法,现在是把animal 的showName()方法放到 cat上来执行,所以this.name 应该是 Cat
c、实现继承
function Animal(name){
this.name = name;
this.showName = function(){
alert(this.name);
}
}
function Cat(name){
Animal.call(this, name);
}
var cat = new Cat("Black Cat");
cat.showName();
Animal.call(this) 的意思就是使用 Animal对象代替this对象,那么 Cat中不就有Animal的所有属性和方法了吗,Cat对象就能够直接调用Animal的方法以及属性了.
d、多重继承
function Class10()
{
this.showSub = function(a,b)
{
alert(a-b);
}
}
function Class11()
{
this.showAdd = function(a,b)
{
alert(a+b);
}
}
function Class2()
{
Class10.call(this);
Class11.call(this);
}
很简单,使用两个 call 就实现多重继承了
当然,js的继承还有其他方法,例如使用原型链,这个不属于本文的范畴。说了call ,当然还有 apply,这两个方法基本上是一个意思,区别在于 call 的第二个参数可以是任意类型,而apply的第二个参数必须是数组,也可以是arguments 还有 callee,caller..
3.arguments对象中有一个非常有用的属性:callee。arguments.callee返回此arguments对象所在的当前函数引用。在使用函数递归调用时推荐使用arguments.callee代替函数名本身。arguments对象用callee属性来引用当前正在执行的函数!!如下:
function count(a){
if(a==1){
return 1;
}
return a + arguments.callee(--a);
}
var mm = count(10);
alert(mm);
3128



被折叠的 条评论
为什么被折叠?



