您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 招聘面试 > Javascript之昨是今非
JavaScript之昨是今非Javascript0javascript和ECMAScript的关系1闭包的作用域困扰和自执行函数2call和apply重定义执行Context3面向类继承的js4动态构建和eval函数5ajax并不神秘6js事件和分离式脚本编程7ajax跨域8reverseajax和服务器推技术9js对象技术之背后的实现--google的v8js引擎10js的未来0javascript和ECMAScript的关系(1)•ECMA是欧洲计算机制造商协会的缩写•javascript最初是由netscape公司创造,由其员工Brendaneich在1995年的时候写了一个叫LiveScript,当时由于java的风头正劲,所以正式发布前改名为JavaScript。最终Netscape公司赌赢了。js从此成为因特网必备组件•当Netscape的浏览器取得成功后,微软进入了这个领域,并且也推出了一个叫JScript的脚本语言。同一时期还有其他公司推出不同版本的js,这些脚本语言并没有统一的语法和特性,为了解决浏览器不兼容性,在1997年网景公司将JavaScript1.1版本提交给ECMA的第39技术委员会(TC39),这个委员会被委派来“标准化一个通用的,跨平台的,中立于厂商的脚本语言的语法和语义”。•关系:•尽管ECMAScript是一个重要的标准,但它并不是JavaScript的唯一部分,当然也不是唯一被标准化的部分,一个完整的JavaScript实现由3个部分组成。•1核心(ECMAscript)•2文档对象模型(DOM)•3浏览器对象模型(BOM)0javascript和ECMAScript的关系(2)•BOM是IE3.0和NetscapeNavigator3.0提供的一种特性。可以对浏览器窗口进行访问和操作,使用BOM,开发者可以移动窗口,改变状态栏中的文本以及其他和页面内容不直接相关的内容。使BOM独树一帜且又常常令人怀疑的地方,他只是JavaScript的一部分并没有相关的标准。•BOM主要处理浏览器窗口和框架(frame)包括•1弹出新的浏览器窗口•2移动、关闭浏览器详细以及调整窗口大小•3提供web浏览器中详细信息的导航对象•4提供装载到浏览器中页面的详细信息的定位对象•5对cookie的支持•6最后也是非常重要的是IE扩展了BOM加入了ActiveXObject类,可以通过JavaScript实例化ActiveX对象正式这一特性后来成为ajax的点睛之笔,提供异步交互的可能。1:闭包的作用域困扰和自执行函数(1)•(1)作用域解析和闭包。•首先作用域是指对某一属性(变量)或方法(函数)具有访问权限的代码空间。在js中•作用域是在函数中进行维护的。闭包是与作用域相关的一个概念,它指的是“内部函数即使在外部函数执行完毕并终止以后,仍然可以访问外部函数的属性“。当引用一个变量或方法时,js会沿着由对象执行的路径构成的作用域链对作用域进行解析”。•例子1:•functioninitAnchors(){–for(vari=1;i=3;i++){•varanchor=document.getElementById(”anchor“+i);•anchor.addEventListener('click',function(){–alert(Myidisanchor+i);•});–}•}•单击该dom对象onclick事件时,i都会是3而不是期望的分别为1,2,3,1:闭包的作用域困扰和自执行函数(2)•具体来说,当点击click事件侦听器被调用并在它的内部作用域中查找i的值时,结果没有找到(因为I的值没有在匿名函数中定义)•解决:可以用一个方法包装事件注册,用一个方法来激活一个作用域。•functionregisterListener(anchor,i){–anchohr.addListener('click',function()){alert('Myidisanchor'+i);–}•}•这样原来的代码改写为•functioninitAnchors(w3cEvent){–for(vari=1;i=3;i++){•varanchor=document.getElementById(”anchor“+i);•registerListener(anchor,i);–}•}1:闭包的作用域困扰和自执行函数(3)•2自执行函数。•原型:(function(){})();•(function(){})(),(function(){});//强制其理解为函数,“函数()”表示执行该函数,即声明后立即执行。•functioninitAnchors(){–for(vari=1;i=3;i++){•varanchor=document.getElementById('anchor'+i);•,(function(anchor,i){–anchor.addListener('click',function(){»alert('Myidisanchor'+i);–});•})(anchor,i);–}•}2:call和apply重定义执行Context(1)•在函数的执行环境改变后怎么重新定义Context•functiondoubleCheck(){–this.message=aryousureyouwanttoleave?;•}•docubleCheck.prototype.sayGoodbye=function(){–returnconfirm(this.message);•}•initPage(){–varclickLink=newdoubleCheck();–varlinks=document.getElementsByTagName('a');–for(vari=0;ilinks.length;i++){•links[i].addListener('click',clickedLink.sayGoodbye);–}•}2:call和apply重定义执行Context(2)•这个例子中绑定了clickedLink对象sayGoodbye方法,但是在实际执行时该方法的this对象指向了当前的dom元素对象,而不是我们创建的clickedLink对象。•怎么解决这个问题呢?这就要用到两个Function对象的call和apply方法了。•通过这两个方法可以重新定义方法的执行环境,•调用语法:–functionReference.sayGoodbye.call(object,argment1,argments2,...);–functionReference.sayGoodbye.apply(object,argments);–apply方法可以利用Argments对象(注:Argments对象是js的特殊对象,具有部分数组的功能–例如可以通过下标访问语法,去访问各个参数,但是它不具备一些数组的方法,比如push(),–concat(),slice()等等);–当为了调整方法的执行环境而生成匿名包装函数时,apply()方法特别有用,可以通过联合闭包功能。–例子:–functionbindFunction(obj,func){•reutrnfunction(){func.apply(obj,argmengs);}–}三、面向类继承的js(1)•1:“对js来说面向对象这个词有些多余,因为js这么语言是完全面向对象的,也不可能以非面向对象的方法来使用。”-----JohnResig。•大多数编程新手的常见弱点在于按照功能编写代码,而不考虑任何上下文或者结构。•对象是js的基础(因为dom就是js一种对象)但是js的对象不同样传统语言里的对象,比如java和c++c#等,js的对象更像是散列表。它具有多重性.•例子:•varobj=newObject;•obj.val=5;•obj.click=funciton(){alert(hello);};•//下面一段json方式定义•varobj={•val:5;•click:function(){alert(hello);}•}•一:原型式继承原型式继承不同传统的类/对象继承,和大部分的其他面向对象语言不同的是,js三、面向类继承的js(2)•并没有类(class)的概念。其他面向对象语言中大多需要实例化具体类实例,但是js中不用,js里对象本身可以用来创建新对象,而对象也可以继承自其他对象。这个概念称之为“原型化继承”。•不过js使用何种对象方案,首先还是应该有一种创建新对象的方法。js的做法是任何函数都可以被实例化一个对象。•例子:•functionUser(){}•varme=newUser();•varyou=newme.constructor();•alert(me.constructor=you.constructor);•constructor这个属性的使用,它在每个对象中都存在,并一直指向创建它的函数,这样一来可以有效的复制对象了。用同一个基类创建并赋予不同的属性。•2:创建可重用的代码•例子:三、面向类继承的js(3)•functionPerson(name){–this.name=name;•}•//给Person对象添加一个新方法•Person.prototype.getName=function(){•returnthis.name;•};•//创建一个新的User对象的构造函数•functionUser(name,password){•this.name=name;•this.password=password;•};•//User对象继承所有Person对象的方法•User.prototype=newPerson();•User.prototype.getPassword=function(){returnthis.password;};三、面向类继承的js(4)•类式继承对于大部分开发者来说都已经熟悉,只要有了带方法的类就可以把它实例化为对象。先看一段代码Function.prototype.method=function(name,func){this.prototype[name]=func;returnthis;};这一段代码扩展了Function类,动态绑定新函数到对象的prototype上,这段函数还是比较好理解的。它把函数和构造函数的原型关联起来,之所以有效,是因为所有的构造函数本身都是函数,所以能获得”method“这个新方法。但是下面这个函数就相当复杂,它实现了子类继承父类时,当子类override父类方法时用类似super的方式访问父类被覆盖的方法,这是js大师DouglasCrockford的作品值得我们再三拜读。O(∩_∩)O~三、面向类继承的js(5)•Function.method('inherits',function(parent){•vardepth=0;•varp=(this.prototype=newparent());•this.method('uber',functionuber(name){•varf,r,t=depth,v=parent.prototype;•if(t){•for(t=depth;t0;t-=1){•v=v.constructor.prototype;•}•f=v[name];•}else{•f=p[name];•if(f==this[name]){•f=v[name];•}•}•depth+=1;•r=f.apply(this,Array.prototype.slice.apply(arguments,[1]));•depth-=1;•returnr;•});•returnthis;•});三、面向类继承的js(6)•这个函数定义了一个继承的方法,同时也定义了一个uber方法,该方法可以让子类访问到父类的被override的方法。•depth定义对象继承链的深度,如
本文标题:Javascript之昨是今非
链接地址:https://www.777doc.com/doc-3600572 .html