javascript是一门浏览器语言,对于后台攻城湿们。则是这样对其定义的
1. js是一门前端语言,因为js通常是web中的view部分,用来渲染最终呈现给用户的页面。
2. js是一门弱类型语言和解释性语言,没有使用编译器(编译器会检查语法错误,同样性质的比如php,ruby,python等。当然,不能说完全没有编译过程,只是不是严格意义上的编译),因为编译的目的最终应该是生成可执行的代码,而不是中间结果。
本文将关注两个方面
1.js重要概念
2.js小tips 主要关注容易被忽略的小问题
1.js重要概念
1.1. 对象
var obj = {};
上面的代码定义了一个对象。在以后的使用中,可以动态的给这个对象增加新的属性。
obj.SayNo = func (){ return "no..."; }; obj.Name = "name";
javascript中,每个对象都连接到一个原型对象,并且可以从中继承属性,比如,所有通过上面方式定义的对象,默认都连接到Object.prototype。它是js的标配对象。原型通过prototype来获取,可以给原型增加方法,这样,所有由原型产生的对象又自动获取了该方法,比如,通过以下方式给string增加trim方法。
Function.prototype.method = function(name,func) { this.prototype[name] = func; return this; } String.method(‘trim‘, function(){ return this.replace(/^\s+|\s+$/g, ‘‘); }); var str = " sss "; str.trim();
1.2. 函数
javascript中的函数就是对象,所以函数可以保存在变量,对象和数组中,函数可以作为参数被传递,也可以返回函数,而且,作为对象,也可以拥有方法。
函数有四种调用模式
1. 方法调用模式
2. 函数调用模式
3. 构造器调用模式
4. apply调用模式
函数在调用的时候会自动获得两个免费的参数,this和arguments。上述四种调用模式在如何初始化this上存在差异(其实就是坑)
1. 方法调用模式,this被绑定到该对象上
var obj = { name : "hello kitty", SayHello : function(){ return "hello. i am " + this.name; }, }; obj.SayHello();
2. 函数调用模式,this被绑定到全局对象(坑来了...)
var name = "name1"; var obj = {name:"name2"}; obj.tell = function(){ var sayHello = function(){ return this.name; }; console.log(sayHello()); //输出是name1.因为this指代的是全局的this... };
解决方案
var name = "name1"; var obj = {name:"name2"}; obj.tell = function(){ var that = this; var sayHello = function(){ return that.name; }; console.log(sayHello()); //输出是name2.因为that指代的是对象... };
3. 构造器调用模式
4. apply调用模式
function Person(name,age){ this.name=name; this.age=age; } function Student(name,age,grade){ Person.apply(this,arguments); //apply模式 // 注意:js 中的函数其实是对象,函数名是对 Function 对象的引用。 this.grade=grade; } var student=new Student("qian",21,"一年级"); //构造器 console.log(student.name); console.log(student.age); console.log(student.grade);
其实还有一种调用方式(call),如下(跟apply类似)
function Animal(){ this.name = "Animal"; this.showName = function(){ alert(this.name); } } function Cat(){ this.name = "Cat"; } var animal = new Animal(); var cat = new Cat(); animal.showName.call(cat,",");
上述方式,把cat用animal的this替换了,所以,输出是cat.
比如,在设置时间监听时,可以使用call来完成
addEventHandler: function(obj,eventName,fun,param) { var fn = fun; if(param){ fn = function(e){ fun.call(this, param); } } if(obj.attachEvent){ obj.attachEvent(‘on‘+eventName,fn); }else if(obj.addEventListener){ obj.addEventListener(eventName,fn,false); }else{ obj["on" + eventName] = fn; } },
1.3 js的同缘策略
js为了安全考虑,采取了同源策略。要求两个同源的js才能互相操作dom。
1. 这里的同源(协议,域名,端口三者必须一致),指定的是页面的同源,而不是js。因为页面可以任意引用其他域名下的js(因为是主动包括,所以都实际上都属于同一个源的js,比如很多页面会加入百度广告的js,或者谷歌统计的js等。这些js是可以直接对页面的dom进行操作的)。更具体来说,就是JS只能与同一个域中的页面进行通讯.如:运行在 http://www.cnblogs.com/weijiaen/page.html上的脚本不能和http://www.cnblogs.com/weijiaen2/page.html的浏览器窗口或iframe 进行交互.不能访问它的cookie,接收它的HTTP响应等(但它可以向任何其他源发送HTTP请求,浏览器会阻止它读写响应);AJAX 和 webservice 也受此策略管束.
2. 同源策略的一个解决方式(让一个页面能访问另外一个域的接口)就是jsonp。jsonp其实是利用页面可以使用<script>任意引用其他域名的js(必须是可执行js段,比如var arr=[1,2,3]而不是一个数据,比如{a:[1,2,3]}),然后通过注册函数(这又是函数的一大用处),然后从另外一个域返回函数(参数为数据{}),这样就可以对返回的数据进行处理,jsonp只是一个技术而不是一个标准的协议。
当一个页面尝试包含其他页面(比如百度广告会在你的页面中包括百度域下的一个页面),并且尝试让两个页面进行通信的时候,会遇到同源策略限制的问题。但是可以通过主页面改变url中的hash值(改变iframe的src中的hash,并不会引起页面刷新)的方式(在子页面中监听hash参数的变化)进行通信。
2. js小tips
2.1. 对象通过引用来传递,永远不会被复制
2.2. 直接使用未经声明的变量,会产生隐式全局变量,这会导致bug查找非常困难
2.3. JavaScript只有函数作用域,没有块级作用域,在函数内部任何地方定义的变量,在函数内部任何地方可见(比如在一个for循环定义的变量在另外一个for循环可见)。
2.4. 一个函数总是会返回值,不指定返回值,则返回undefined. 如果在函数调用前加上了new,则返回this。如果我们想办法让函数返回是this,则可以启用级联。作用类似c++的cout。
比如,getElementById返回的就是一个this指针
2.5. 如何正确的生成动态script标签,并执行
div_content = [ ‘(function() {‘, //some code string here... ‘ })()‘].join(‘‘); var script_div = document.createElement("SCRIPT"); script_div.innerHTML = div_content; script_div.type = "text/javascript"; target_div=document.getElementById(‘yourid‘); target_div.appendChild(script_div);
2.6. css之定位
css定位分绝对定位(absolute,fixed),相对定位(relative)
absolute是指绝对定位,即将对象从文档流中拖出,使用left,right,top,bottom等属性进行绝对定位,而其层叠通过z-index属性定义。在没有设定上面四种属性时,默认依据父级的做标原始点为原始点。如果设定并且父级没有设定position属性,那么当前的absolute则以浏览器左上角为原始点进行定位,位置将由设定值决定。
比如,如果不设置父节点为relative。效果如下图
如果设置了父节点为relative。效果如下图
ralative是指相对定位,就是依据left,right,top,bottom等属性在正常文档流中偏移位置。