深入解析 Javascript 面向对象编程

发布时间:2020-03-04编辑:脚本学堂
本文详细介绍了javascript 面向对象的相关内容,从原理到实例,有需要的朋友参考下吧。

闭包(closure)
Javascript闭包就是在另一个作用域中保存了一份它从上一级函数或作用域取得的变量(键值对),而这些键值对是不会随上一级函数的执行完成而销毁。
这样在执行完var c=a()后,变量c实际上是指向了函数b,b中用到了变量i,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么因为函数a外的变量c引用了函数a内的函数b,就是说:

当函数a的内部函数b被函数a外的一个变量引用时,就创建了一个通常所谓的“闭包”。
 

复制代码 代码示例:
function a() {
var i = 0;
function b() {
alert(++i);
}
return b;
}
var c = a();
c();

闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。

函数的作用域及this
1、在函数或方法中可以使用this来引用函数所在的当前对象
2、当没有明确指定函数的当前对象时,作用域为window
3、可以使用call及apply来动态改变函数执行的作用域
 

复制代码 代码示例:
var b1={v:"this is b1"};
var b2={v:"this is b2"};
function b(d){
alert(this.v);
}
b();//输出:
window.b();//输出:
b.call(b1);//输出:
b.apply(b2);//输出:

词法作用域(lexcical scope)。通俗地讲,就是javascript变量的作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,编译器通过静态分析就能确定,因此词法作用域也叫做静态作用域(static scope)。但需要注意,with和eval的语义无法仅通过静态技术实现,所以只能说javascript的作用域机制非常接近词法作用域(lexical scope).
javascript引擎在执行每个函数实例时,都会创建一个执行环境(execution context)。执行环境中包含一个调用对象(call object)
调用对象是一个scriptObject结构(scriptObject是与函数相关的一套静态系统,与函数实例的生命周期保持一致),用来保存内部变量表varDecls、内嵌函数表funDecls、父级引用列表 upvalue等语法分析结构(注意varDecls和funDecls等信息是在语法分析阶段就已经得到,并保存在语法树中。函数实例执行时,会将这些信息从语法树复制到scriptObject上)。

apply and call:它们的作用都是将函数绑定到另外一个对象上去运行,两者仅在定义参数方式有所区别:
 

复制代码 代码示例:
apply(thisArg,argArray);
call(thisArg[,arg1,arg2…] ]);

即所有函数内部的this指针都会被赋值为thisArg,这可实现将函数作为另外一个对象的方法运行的目的。

apply的说明

如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。如果没有提供 argArray 和 thisArg任何一个参数,那么 Global 对象将被用作 thisArg,并且无法被传递任何参数。

call的说明

call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisArg指定的新对象。如果没有提供 thisArg参数,那么 Global 对象被用作 thisArg

重点(the point):
应用call和apply还有一个技巧在里面,就是用call和apply应用另一个函数(类)以后,当前的函数(类)就具备了另一个函数(类)的方法或者是属性。
在浏览执行的javascript中,默认情况下对象的作用域为window。
 

复制代码 代码示例:
c.run();
window.c.run();

JavaScript中的系统函数(Global类)
encodeURI及encodeURIComponent方法
返回对一个URI字符串编码后的结果。
decodeURI及decodeURIComponent()方法
将一个已编码的URI字符串解码成最初始的字符串并返回。
parseInt方法
将一个字符串按指定的进制转换成一个整数,语法格式为:parseInt(numString, [radix])。如果没有指定第二个参数,则前缀为 ‘0x' 的字符串被视为十六进制,前缀为 ‘0' 的字符串被视为八进制,所有其他字符串都被视为是十进制。
parseFloat方法
将一个字符串转换成对应的小数。
isNaN方法
用于检测parseInt和parseFloat方法的返回值是否为NaN。
escape方法
返回对一个字符串进行编码后的结果字符串。所有空格、标点、重音符号以及任何其他非 ASCII 字符都用 %xx 编码替换,其中xx等于表示该字符的Unicode编码的十六进制数,字符值大于255的字符以%uxxxx格式存储。
unescape 方法
将一个用escape方法编码的结果字符串解码成原始字符串并返回。
eval 方法
将其中的参数字符串作为一个JavaScript表达式执行。

JavaScript的内部类
动态对象
使用“对象实例名.成员”的格式来访问其属性和方法。
静态对象
直接使用“对象名.成员”的格式来访问其属性和方法。

Object类(对象)
Number类(对象)
String类 (对象)
Math类(对象)
Date类(对象)
toString方法

Object类
Object类是所有javascript类的基类,提供了一种创建自定义对象的简单方式,不需要程序员再定义构造函数
主要属性:
constructor-对象的构造函数
prototype-获得类的prototype对象,static性质
主要方法:
 

hasOwnProperty(property)-是否属于本类定义的属性
isPrototypeOf(object)-是否是指定类的prototype
propertyIsEnumerable(property)-是否可例举的属性
toString()-返回对象对应的字符串
valueOf()-返回对象对应的原始类型值
 

 

复制代码 代码示例:

<script language="javascript">
function getAttributeValue(attr)
{
alert(person[attr]);
}
var person = new Object();
person.name = "zs";
person.age = 18;
getAttributeValue("name");
getAttributeValue("age");
</script>

Number类
Number类代表数据类,包含一些静态的成员及数值处理的方法。
静态属性:
MAX_VALUE、MIN_VALUE、NEGATIVE_INFINITY、POSITIVE_INFINITY、NaN
主要方法:
 

toFixed(n)-取小数位数,自动四舍五入
toPrecision(n)-是否是指定类的prototype
propertyIsEnumerable(property)-是否可例举的属性
toString()-返回对象对应的字符串
valueOf()-返回对象对应的原始类型值
 

 

复制代码 代码示例:

<script language="javascript">
var oNumberObject = new Number(99);
alert(oNumberObject.toFixed(2)); //outputs “99.00”
</script>

String类
length属性
anchor、big、bold、fontcolor、link等方法
charAt方法
注意:一个字符串中的第一个字符的索引位置为0,依次类推。
charCodeAt方法
注意:返回的结果是字符的unicode编码。
 

concat方法,连接字符串
indexOf方法及lastIndexOf方法
match、search方法
replace、split方法

slice方法
说明:str1.slice(0)和str1.slice(0,-1)都是返回整个字符串。
 

substr、substring方法
substring方法返回的内容不包含结束位置的字符。
toLowerCase、toUpperCase 方法

Math类
属性:
 

E,代表数学常数e,约等于 2.718。
LN10,代表10的自然对数,约等于 2.302。
LN2,代表2的自然对数,约等于 0.693。
PI,代表数学常数∏的值,约等于 3.14159。
SQRT1-2,代表2 的平方根分之一,约等于0.707。
SQRT2,代表2 的平方根,约等于1.414。

方法:
abs方法,返回数字的绝对值。
sin、cos方法,分别返回数字的正弦、余弦值。
asin、acos方法,分别返回数字的反正弦、反余弦值。
random方法,返回介于 0 和 1 之间的伪随机数
Math对象是一个静态类,不能使用new关键字创建对象实例,应直接使用“对象名.成员”的格式来访问其属性或方法,例如,var num = Math.random();

Date类
 

toGMTString方法,返回Date对象实例所表示的日期的字符串形式,该字符串使用格林尼治标准时间 (GMT) 格式,例如,“05 Jan 1996 00:00:00 GMT”。
getYear、getMonth、getDate、getDay方法
getHours、getMinutes、getSeconds、getMilliseconds方法
getTime方法,返回自1970年1月1日0点0分0秒算起,至Date对象实例代表的时间为止的毫秒数。

 

复制代码 代码示例:

<script language="javascript">
var current_time = new Date();
var strDate = current_time.getYear() + "年";
strDate += current_time.getMonth() + "月";
strDate += current_time.getDate() + "日 ";
strDate += current_time.getHours() + ":";
strDate += current_time.getMinutes() + ":";
strDate += current_time.getSeconds();
alert(strDate);
</script>

构造方法 :Date()、Date(dateVal) 、Date(year, month, date[, hours[, minutes[, seconds[,ms]]]])
parse方法,分析一个表示日期时间的字符串,返回它所表示的时间值,该值以自1970年1月1日0点0分0秒算起的毫秒值表示。parse方法属于一个静态方法 。

toString方法
toString 方法是JavaScript中的所有内部对象的一个成员方法,它的主要作用就是将对象中的数据转换成某种格式的字符串来表示,具体的转换方式取决于对象的类型。

举例:
 

复制代码 代码示例:
<script language="javascript">
var x = 328;
alert("hex=“ + x.toString(16) + " bin=“ + x.toString(2));
</script>

Array类
三种构造方法:
Array()
Array(4)
Array(3.5,"abc",3)

数组排序例子:
 

复制代码 代码示例:
<script language="javascript">
var arr = new Array();
arr[0] = 3.5;
arr[1] = "abc"
arr[2] = 3;
arr.sort();
var x,str = "";
for(x in arr)
{
str += x + ":“ + arr[x] + "n";
}
alert(str);
</script>

Array类的属性及方法
length-获得数组的长度;
concat-连接数组;
join-把数组转换成字符串;
pop-弹出一个元素;
push-放入一个元素;
reverse-颠倒数据中的元素顺序;
shift-移出第一个元素;
slice-截取数组;
sort-排序数组;
unshift-在前面追加元素;

用对象的方式实现数组
 

复制代码 代码示例:
<script language="javascript">
function MyArray()
{
this.length = arguments.length;
for (var i=0; i<this.length;i++)
{
this[i] = arguments[i];
}
}
var str = "";
var arr = new MyArray(4,3.5,"abc");
for(var i=0; i<arr.length; i++)
{
str += arr[i] + "n";
}
alert(str);
</script>
<script language="javascript">
function MyArray(size)
{
this.length = size;
for (var i=0; i<size; i++)
{
this[i] = "";
}
}
var arr = new MyArray(2);
arr[0] = 3;
arr[1] = "abc";
arr[2] = 4;
var x, str = "";
for(x in arr)
{
str += x + ":" + arr[x] + "n";
}
alert(str);
</script>

用户自定义类及对象
1、工厂方法-使用new Object创建对象并添加相关属性;
2、使用构造函数来定义类。
3、使用prototype
4、构造函数及原型混合方式
5、动态原型方式
实例
Car类(对象)
属性:
color-颜色
doors-门的个数
price-价格
drivers-司机
方法:
showColor-显示出车的颜色

typeof及instanceof 运算符
delete操作符用来删除一个对象的指定成员。
typeof xx-string返回xx对象的类型或undefined。
 

复制代码 代码示例:
var d=7.5;
alert(typeof d);
alert(typeof d2);
alert(typeof new Object());
alert(typeof Object);

xx instanceof 类名,返回boolean类型:
 

复制代码 代码示例:
<script language="javascript">
var o = new String("ab");
alert(o instanceof String);
alert(o instanceof Number);
alert(o instanceof Object);
</script>

delete及void 操作符
delete操作符用来删除一个对象的指定成员。
 

复制代码 代码示例:
var d=new Object();
d.p1="this is p1";
alert(d.p1);
delete d.p1;
alert(d.p1);
delete只能删除用户自义的成员。
delete d.toString;
alert(d.toString());
void 用来把任意数字转换为undefined。
var d=new Object();
alert(void(d));
 

运用场景:
 

复制代码 代码示例:
<a href=”javascript:window.open(‘about:blank')”>Click Me</a>