日期:2014-05-16  浏览次数:20507 次

用实例谈谈javascript中的this和prototype

    本文通过几个实例谈谈js中一些基础概念的问题。首先回顾一下js这门语言的特点:除了对象什么都没有。函数在js语言中被看作一种特殊的数据类型,特殊在包含代码并且可以执行,但落点在它是一种数据类型,与数字、字符串等一样。

   理解了这个,那么js语言中的全局作用域和函数作用域、全局变量和局部变量。可以通过全局对象和非全局对象划分。如果函数或其他数据类型,不依托非全局变量,那么就默认依托全局变量,即作为全局对象的属性或方法,否则被当作局部对象方法或属性。this被用作指向属性和方法所依托的对象。搞清楚了这个,this的判断就基本上不会出现问题了。

   以下实例(点击查看)为第七个内容的实例。

var x = 100;
var y=77;
var a1={
x:99,
xx:function(){
  //var y=88;  //如果没有注释这个变量,y将是全局变量的77
  alert(y); //没有使用this指针,调用函数的对象无法影响y的值,函数运行时将从这里按作用域链逐级搜索取值
  alert(this.x);  //使用了 this 指针,调用函数的
}
}

a1.xx();
a1.xx.call(window);

var jj = a1.xx;

jj(); //效果跟a1.xx.call(window); 一样
   以上代码,倒数第三、四行代码都不难理解,倒数第一行代码怎么理解呢?首先我们看jj定义在全局对象中,即jj是window的属性,从jj的赋值我们知道,jj是一个方法,jj()也就相当于window.jj(),即调用函数的this指向全局对象window。

   如下代码是回复一个网友提问的解答:

function A()
{
 this.d=5;
 this.c=5;
}
A.prototype.name="father";
var a= new A();//构造函数会给创建的实例添加所有属性和方法包括自有属性和prototype的属性
var b={};
A.call(b);//apply和call方法只会返回对象的自有属性,prototype属性都会丢弃
/*如下四种实例可证*/
console.log(a.d);
console.log(b.d);
console.log(a.name);
console.log(b.name);

       call和apply函数都可以改变this指针的指向,但是prototype属性会被丢弃掉,通过实例不难验证。

  如下代码是对一个网友算法(点击查看)的优化,同时也是prototype属性的应用。函数对象的属性prototype,此属性初始值为boject空对象。可以给作为原型属性的这个对象添加属性和方法。函数对象作为构造器函数生成新对象,可用prototype属性添加的属性和方法。

   原型链概念:当构造器生成新对象,这个对象查找对象属性时,先找对象属性,如果没有则上溯到原型中查找,直到查找到object。对象自身属性优先级高于原型属性。可以覆盖。

   下述代码旨在删除数组中重复的内容,用到了prototype属性,给内建Array对象添加了新的方法。算法优化在于遍历和替代同时进行,遍历完,也替代完,并截取替代长度即可,减少了时间复杂度。

 Array.prototype.uniq = function() {// 利用原型属性,给内建对象添加新的方法剔除重复字符串
        var temp={},k=0,m,tempA=[];
        for(var i=0; i < this.length; i++)  {  
            if(temp[this[i]] == undefined)//这里的undefined要注意,没有引号
            {
		m=k;
		temp[this[i]]=1;
		this[k++]=this[i];
            }  
        }
        this.length=k;
        return this;
    }  
    
var array= [1,'a',1,'a','kl',"name","karl",'kl'];
array.uniq()