this是Javascript语言的一个关键字。

它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。比如,

  function test(){

this.x = 1;

}

随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,调用函数的那个对象。

下面分四种情况,详细讨论this的用法。

情况一:纯粹的函数调用

这是函数的最通常用法,属于全局性调用,因此this就代表全局对象Global。

请看下面这段代码,它的运行结果是1。

  function test(){

this.x = 1;

alert(this.x);

}

test(); // 1

为了证明this就是全局对象,我对代码做一些改变:

  var x = 1;

function test(){

alert(this.x);

}

test(); // 1

运行结果还是1。再变一下:

  var x = 1;

function test(){

this.x = 0;

}

test();

alert(x); //0

情况二:作为对象方法的调用

函数还可以作为某个对象的方法调用,这时this就指这个上级对象。

  function test(){

alert(this.x);

}

var o = {};

o.x = 1;

o.m = test;

o.m(); // 1

情况三 作为构造函数调用

所谓构造函数,就是通过这个函数生成一个新对象(object)。这时,this就指这个新对象。

  function test(){

this.x = 1;

}

var o = new test();

alert(o.x); // 1

运行结果为1。为了表明这时this不是全局对象,我对代码做一些改变:

  var x = 2;

function test(){

this.x = 1;

}

var o = new test();

alert(x); //2

运行结果为2,表明全局变量x的值根本没变。

情况四 apply或call调用

apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是这第一个参数。

  var x = 0;

function test(){

alert(this.x);

}

var o={};

o.x = 1;

o.m = test;

o.m.apply(); //0

apply()的参数为空时,默认调用全局对象。因此,这时的运行结果为0,证明this指的是全局对象。

如果把最后一行代码修改为

  o.m.apply(o); //1

运行结果就变成了1,证明了这时this代表的是对象o。

call的用法跟apply差不多,只是后面第二个参数不同,第一个参数是一样的用法。

参考:http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html

 

第一种 prototype 引用型原型继承
语言支持:js原生支持的继承方式 构造器的的prototype属性作为类的原型 每个该类的对象都持有一个到原型的引用 当对象中的属性不存在时 可以访问原型的属性

代码示例:

<script>
function parent(){
this.x=10;
}
function child(){
}
child.prototype=new parent();
var childObj=new child();
alert(childObj.x);
</script>

第二种 复制型原型继承
语言支持:js new运算符的性质 当构造函数return值为非空对象时 new表达式返回return的对象
代码示例:
<script>
function parent(){
this.x=10;
}
function child(){
var ret=new parent();
ret.y=20;
return ret;
}
var childObj=new child();
alert(childObj.x);</script>

第三种 类继承 属性抄写
语言支持:for in枚举对象所有属性
<script>
function parent(){
this.x=10;
}
function child(){
var parentObj=new parent();
for(var p in parentObj)this[p]=parentObj[p];
}
var childObj=new child();
alert(childObj.x);
</script>

第四种 类继承 对象冒充
语言支持: 1.动态添加和删除方法 2.函数的call和apply
代码:
用语言支持1实现的类继承
<script>
function parent(){
this.x=10;
}
function child(){
this.parent=parent;
this.parent();
delete this.parent;
}
var childObj=new child();
alert(childObj.x);</script>

用语言支持2实现的类继承
<script>
function parent(){
this.x=10;
}
function child(){
parent.call(this);
}
var childObj=new child();
alert(childObj.x);</script>

第五种 原型抄写
语言支持:通过修改类的原型对象 可以为一类对象添加属性和方法
代码
<script>
function parent(){}
parent.prototype.me=function(){alert(“parent”)};
function child(){}
for(var p in parent.prototype)child.prototype[p]=parent.prototype[p];
var childObj=new child();
childObj.me();</script>

第六种 元类
语言支持: js函数都是对象 且js函数可被构造
<script>function parent(string){
var child=new Function(“this.x=10;”+string);
return child;
}
var child=new parent(“this.y=20;”);
var childObj=new child();
alert(childObj.y);
</script>

对js对象来说 它的属性来自两部分:prototype属性和自身属性 call/apply只能继承自身属性 原型抄写只能继承prototype属性
将它们混用互相没有任何干扰 而且实现了所有属性的继承。但是我觉得,如果按规范编码的话,似乎只用其一就足够了,对一个类来说,同时给prototype和构造函数添加属性的情况很少见吧?

转自:http://hi.baidu.com/tangdecai/blog/item/6c7e6306698b837d020881ff.html

 

//构造函数 myObject
//使自己的对象多次复制,同时实例根据设置的访问等级可以访问其内部的属性和方法
//当对象被实例化后,构造函数会立即执行它所包含的任何代码
function myObject(msg){
//特权属性(公有属性)
this.myMsg = msg; //只在被实例化后的实例中可调用
this.address = ‘上海’;

//私有属性
var name = ‘豪情’;
var age = 29;
var that = this;

//私有方法
function sayName(){
alert(that.name);
}
//特权方法(公有方法)
//能被外部公开访问
//这个方法每次实例化都要重新构造而prototype是原型共享,所有实例化后,都共同引用同一个
this.sayAge = function(){
alert(name); //在公有方法中可以访问私有成员
}
//私有和特权成员在函数的内部,在构造函数创建的每个实例中都会包含同样的私有和特权成员的副本,
//因而实例越多占用的内存越多
}
//公有方法
//适用于通过new关键字实例化的该对象的每个实例
//向prototype中添加成员将会把新方法添加到构造函数的底层中去
myObject.prototype.sayHello = function(){
alert(‘hello everyone!’);
}
//静态属性
//适用于对象的特殊实例,就是作为Function对象实例的构造函数本身
myObject.name = ‘china’;
//静态方法
myObject.alertname = function(){
alert(this.name);
}
//实例化
var m1 = new myObject(’111′);
//—- 测试属性 —-//
console.log(myObject.name); //china
console.log(m1.name); //undefined, 静态属性不适用于一般实例
console.log(m1.constructor.name); //china, 想访问类的静态属性,先访问该实例的构造函数,然后再访问该类静态属性
console.log(myObject.address); //undefined, myObject中的this指的不是函数本身,而是调用address的对象,而且只能是对象
console.log(m1.address); //上海 此时this指的是实例化后的m1

//—- 测试方法 —-//
myObject.alertname(); //china,直接调用函数的类方法
m1.alertname(); //FF: m1.alertname is not a function, alertname 是myObject类的方法,和实例对象没有直接关系
m1.constructor.alertname(); //china, 调用该对象的构造函数(类函数)的方法(函数)
m1.sayHello(); //hello everyone, myObject类的prototype原型下的方法将会被实例继承
myObject.sayHello(); //myObject.sayHello is not a function,sayHello是原型方法,不是类的方法

//—- 测试prototype —-//
console.log(m1.prototype); //undefined, 实例对象没有prototype
console.log(myObject.prototype); //Object
alert(myObject.prototype.constructor); //console.log返回myObject(msg),此时alert()更清楚,相当于myObject
console.log(myObject.prototype.constructor.name); //china, 相当于myObject.name;

转自:http://www.cnblogs.com/jikey/archive/2011/05/13/2045005.html

 

第二篇  

<script type=”text/javascript”>

//构造函数  Person     //其中一种类方法定义的方法
  function Person(name){
     //类变量
     this.name = name;
     this.age  = 0;

      this.gender = 0;

     this.pets = new Array();
  }

  //类setName(name)的函数
  Person.prototype.setName=function(name){
     this.name=name;
  }

  //类getName(name)的函数
  Person.prototype.getName=function(){
     return this.name;
  }

  //类pushPetsArr(item)的函数
  Person.prototype.pushPetsArr=function(item){
     this.pets[this.pets.length] = item;
  }

//构造函数 Person    //另一种类方法定义的方法
  function Person(name){
     //类变量
     this.name = name;
     this.age  = 0;
     this.gender = 0;
     this.pets = new Array();
  }

  //类setName(name)的函数
  Person.prototype = {
      setName: function(name){
          this.name=name;
      },

      //类getName(name)的函数

      getName: function(){
          return this.name;
      },

      //类pushPetsArr(item)的函数
      pushPetsArr: function(item){
          this.pets[this.pets.length] = item;
      }
  }
</script>

<script type=”text/javascript”>

 var myNameSpace = new Object(); //构造一个命名 空间myClass

 //类的属性
 myNameSpace.names=”cnscn”;
 myNameSpace.age=”30″;

 myNameSpace.ClassPersons=function(argName,argAge){ //构造类名,即构造函数
    this.names=argName;
    this.age=argAge;
 }

 myNameSpace.ClassPersons.prototype={//类方法的定义
    //方法getName()
    getName:function(){
      alert(this.names);
    }//注意这里是”逗号
     //方法setName(argName)
    setName:function(argName){
       this.names=argName;
    }
 }

 var obj=new myNameSpace.ClassPersons(“yao”, 23);
 obj.getName();
 obj.setName(“hhhh”);
 obj.getName();
alert(myNameSpace.name);

</script>

转自:http://blog.sina.com.cn/s/blog_675879000100ijui.html

© 2012 Hedgehog Suffusion theme by Sayontan Sinha