javascript语言精髓笔记

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等属性在正常文档流中偏移位置。 

          

posted on 2014-10-13 18:59  魏加恩  阅读(343)  评论(0编辑  收藏  举报