首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > JavaScript >

js函数、prototype属性、作用域着重点总结

2012-11-10 
js函数、prototype属性、作用域重点总结近看完了javascript面向对象基础技术专栏,现把其中比较重要的、易错的

js函数、prototype属性、作用域重点总结

近看完了javascript面向对象基础技术专栏,现把其中比较重要的、易错的知识点做个总结

?

函数:

创建函数:
1,function f(x) {........}
2,var f = function(x) {......}
上面这两种形式都可以创建名为f()的函数,不过后一种形式可以创建匿名函数
函数定义时可以设置参数,如果传给函数的参数个数不够,则从最左边起依次对应,其余的用undefined赋值,如果传给函数
的参数多于函数定义参数的个数,则多出的参数被忽略.
区别为:1种方式定义的函数,对函数的调用用可以在它之前,
而2种方式对函数的调用必须出现在函数定义之后。

?

函数的prototype属性:
先来说明一点:每一个函数都包含了一个prototype属性,这个属性指向了一个prototype对象。

function Person(name,sex) {  //Person类的构造函数        this.name = name;          this.sex = sex;      }     Person.prototype.age = 12;   //为Person类的prototype属性对应的prototype对象的属性赋值,                                                     //相当于为Person类的父类添加属性     Person.prototype.print = function() { //为Person类的父类添加方法       alert(this.name+"_"+this.sex+"_"+this.age);     };    var p1 = new Person("name1","male"); //p1的age属性继承子Person类的父类(即prototype对象)    var p2 = new Person("name2","male");     p1.print();  //name1_male_12    p2.print();  //name2_male_12    p1.age = 34; //改变p1实例的age属性    p1.print();  //name1_male_34    p2.print();  //name2_male_12    Person.prototype.age = 22;  //改变Person类的超类的age属性    p1.print();  //name1_male_34(p1的age属性并没有随着prototype属性的改变而改变)    p2.print();  //name2_male_22(p2的age属性发生了改变)    p1.print = function() {  //改变p1对象的print方法          alert("i am p1");     }     p1.print();  //i am p1(p1的方法发生了改变)     p2.print();  //name2_male_22(p2的方法并没有改变)     Person.prototype.print = function() { //改变Person超类的print方法        alert("new print method!");     }     p1.print();  //i am p1(p1的print方法仍旧是自己的方法)     p2.print();  //new print method!(p2的print方法随着超类方法的改变而改变)

在JS中,当我们用new操作符创建了一个类的实例对象后,它的方法和属性确实继承了类的prototype属性,类的prototype属性中定义的方法和属性,确实可以被这些实例对象直接引用.但是,当我们对这些实例对象的属性和方法重新赋值或定义后,那么实例对象的属性或方法就不再指向类的prototype属性中定义的属性和方法,此时,即使再对类的prototype属性中相应的方法或属性做修改,也不会反应在实例对象身上.这就解释了上面的例子:
一开始,用new操作符生成了两个对象p1,p2,他们的age属性和print方法都来自(继承于)Person类的prototype属性.然后,我们修改了p1的age属性,后面对Person类的prototype属性中的age重新赋值(Person.prototype.age = 22),p1的age属性并不会随之改变,但是p2的age属性却随之发生了变化,因为p2的age属性还是引自Person类的prototype属性.同样的情况在后面的print方法中也体现了出来.

?

作用域:

?

var sco = "global";  //全局变量    function t() {        var sco = "local";  //函数内部的局部变量         alert(sco);         //local 优先调用局部变量   }    t();             //local    alert(sco);      //global  不能使用函数内的局部变量

在javascript中没有块级别的作用域,也就是说在java或c/c++中我们可以
用"{}"来包围一个块,从而在其中定义块内的局部变量,在"{}"块外部,这些变量不再起作用,
同时,也可以在for循环等控制语句中定义局部的变量,但在javascript中没有此项特性看如下例子:

?

function f(props) {          for(var i=0; i<10; i++) {}          alert(i);         //10  虽然i定义在for循环的控制语句中,但在函数                           //的其他位置仍旧可以访问该变量.         if(props == "local") {              var sco = "local";          alert(sco);           }          alert(sco);       //同样,函数仍可引用if语句内定义的变量     }     f("local");      //10  local   local

在函数内部定义局部变量时要格外小心:

?

var sco = "global";   function print1() {      alert(sco);   //global   }   function print2() {       var sco = "local";       alert(sco);   //local   }   function print3() {       alert(sco);   //undefined       var sco = "local";        alert(sco);   local   }      print1();  //global   print2();  //local   print3();  //undefined  local

前面两个函数都很容易理解,关键是第三个:第一个alert语句并没有把全局变量"global"显示出来,
而是undefined,这是因为在print3函数中,我们定义了sco局部变量(不管位置在何处),那么全局的
sco属性在函数内部将不起作用,所以第一个alert中sco其实是局部sco变量,从这个例子我们得出,
在函数内部定义局部变量时,最好是在开头就把所需的变量定义好,以免出错。

?

?

以上都是看完js基础系列后的总结,具体可以参看:http://www.iteye.com/wiki/Object_Oriented_JavaScript

?

?

热点排行
Bad Request.