首页 > 代码库 > 在JS中,一切东东其实都是对象
在JS中,一切东东其实都是对象
对象是组成JavaScript的基本单元,在JS中,一切东东其实都是对象,而且功能非常强大,它不仅风格独特,功能也与众不同。
一、引用(reference)贵族娱乐城
引用的概念是JS的基础之一,它是指向对象实际位置的指针。见下面的例子:
1 | var items = new Array( "abc" , "def" , "hig" ); |
2 | //创建此数组的引用 |
3 | var Ref = items; |
4 | items.push( "klm" ); |
5 | alert(Ref.lenth); //此处应该显示4 |
但是,如果是字符串,就会出现不同的情况,见下面的代码:
1 | var items = "abc" ; |
2 | var Ref = items; |
3 | items += "def" ; //这里创建了一个新对象,而非原对象的修改。 |
现在Ref与items指向的是不同的对象。
二、函数重载
JS的每个函数都有一个变量argument,它是接收所有参数的伪数组。为什么是“伪”,因为你不能修改它,但它有length属性。我们看看下面的例子:
1 | function myFun(num1,num2) |
2 | { |
3 | if (arguments.length == 2) { alert( "我有两个参数" ); } |
4 | if (arguments.length == 1) { alert( "我有一个参数" ); } |
5 | } |
接下来,我们调用函数myFun("abc"); myFun("abc","def");看看有什么不同,最重要的是,这本来就是函数重载嘛:)
三、作用域
在JavaScript里,作用域是由函数划分的,而不是由块(while,if,for)划分的。这样在理解有些代码时,可能会带来一些麻烦。为了对细节进行说明,我们看下面的例子:
1 | var temp= "oldTemp" //全局变量 |
2 | if ( true ) |
3 | { |
4 | var temp = "newTemp" //这里还在全局中 |
5 | } |
6 | alert(temp == "newTemp" ) //发现相等 |
但是如果我们在一个函数中声明并改变temp变量,效果则完全不同,见例子:
1 | var temp= "oldTemp" ; //全局变量 |
2 | function test() |
3 | { |
4 | var temp = "newTemp" ; |
5 | } |
6 | test(); |
7 | alert(temp == "newTemp" ) ; //发现不相等 |
在JS中,全局变量是window对象的一个属性,在上面的例子中,全局变量temp == window.temp,还有需要注意的是:如果某一个变量缺乏声明,就自动变为全局变量,虽然很可能它只在某个函数中使用。
四、闭包
闭包意味着内层的函数可以引用包围它的函数内的变量,即使外层函数已经终止。见下面的例子:
01 | function AddNum(num1) |
02 | { |
03 | return function (num2) |
04 | { |
05 | return num1 + num2; |
06 | } |
07 | } |
08 | var temp = AddNum(4); //传入第一个参数,然后AddNum消失 |
09 | var temp2 = temp(5); //传入第二个参数,然后相加,返回9 |
10 | alert(temp2); |
这个例子很好体现了闭包的概念,是一种特殊情况,平时当然不这么用。
五、上下文对象
上下文对象通过this变量进行体现,这个变量永远指向当前代码所处的对象中。见下面的代码:
01 | var obj ={ |
02 | yes: function (){ |
03 | this .val = true ; |
04 | }, |
05 | no: function (){ |
06 | this .val = false ; |
07 | } |
08 | } |
09 | alert(obj.val == null ); //这里我们发现对象obj没有val属性 |
10 | obj.yes(); //执行yes函数,obj有了val属性 |
11 | alert(obj.val == true ); |
12 |
13 | window.no = obj.no //把obj的no函数传给window对象 |
14 | window.no(); |
15 | alert(obj.val == true ) ; //发现没有变化 |
16 | alert(window.val == false ) //window里的val变为false; |
这里不太好理解,幸运的是,JS为我们提供了call方法。见下面的例子:
1 | function changeColor(color) |
2 | { |
3 | this .style.color = color; |
4 | } |
5 | changeColor( "Red" ); //这里不行,因为window对象没有style属性 |
6 | var temp = document.getElementById( "temp" ); |
7 | changeColor.call(temp, "White" ); //这里注意call的用法 |
call方法将上下文对象设置为第一个参数,并将其他参数作为原函数的参数。
六、对象
到这里我们才进入正题,但有了前面的概念,这也块内容其实也不是很多。我们直接看例子:
1 | var obj = new Object(); //创建一个对象obj |
2 | obj.val = 5; //创建属性obj,并为其赋值 |
3 | obj.click = function () //创建函数 |
4 | { |
5 | alert( "我被单击了" ); |
6 | } |
上面的代码与下段代码等价:
1 | var obj = { |
2 | val : 5, |
3 | click: function (){ |
4 | alert( "我被单击了" ); |
5 | } |
6 | } |
与其他面向对象语言不同的是,JS并没有Class的概念,在其他语言中,我们基本都需要实例化某个具体类的实例,但JS里却不同,它的做法是:任何函数都可以被实例化为一个对象。我们首先创建一个简单的对象:
1 | function User(name) |
2 | { |
3 | this .name = name; |
4 | } |
5 | var temp = new User( "张三" ); |
6 | alert(temp.name); |
如果上面的对象User只作为函数使用呢?
1 | User( "只作为函数使用" ); |
2 | alert(window.name); |
this的上下文变成了window对象。
七、对象的方法
公共方法在对象的上下文中是最终用户可以接触到的。这里我们需要理解prototype(原型)属性。见下面的代码:
1 | function User(name,age) |
2 | { |
3 | this .name = name; |
4 | this .age = age; |
5 | } |
6 | User.prototype.getName = function (){ return this .name}; |
7 | var user = new User( "张三" ,25); |
8 | alert(user.getName()); |
我们也可以动态创建公共方法,见下面的代码:
1 | function User(name,age) |
2 | { |
3 | this .name = name; |
4 | this .age = age; |
5 | this .getName = function (){ return this .name}; |
6 | } |
7 |
8 | var user = new User( "张三" ,25); |
9 | alert(user.getName()); |
动态生成的方法不是在代码第一次编译时就已经生成,这个技巧被利用prototype开销要大,但也更强大、更灵活。
在JS中,一切东东其实都是对象