本文通过几个实例谈谈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()
用实例谈谈javascript中的this和prototype