• JS学习之路,菜鸟总结的注意事项及错误更正


    JavaScript 是一种面向对象的动态语言,它的语法来源于 Java 和 C,所以这两种语言的许多语法特性同样适
    用于 JavaScript。需要注意的一个主要区别是 JavaScript 不支持类,类这一概念在 JavaScript 通过对象原型
    (object prototype)得到延续(有关 ES6 类的内容参考这里Classes)。另一个主要区别是 JavaScript 中的
    函数也是对象,JavaScript 允许函数在包含可执行代码的同时,能像其他对象一样被传递。
    1,script标签可放在head或body中,因为浏览器解释html文件是按先后顺序的,若是记录用来初始化页面的
    css代码的js应放在head中,若是通过时间调用执行的function函数则对位置没有要求
    js代码最好放在页面的底部,引用外部script文件格式:<script src="script.js"></script>
    2,script标签中可不写type=text/javascript,
    3,document.write("");直接在网页写内容,//要写双引号,输出的是双引号内的内容
    三种方式:

    第一种:输出内容用“”括起,直接输出""号内的内容
    第二种:通过变量,输出内容
    第三种:输出多项内容,内容之间用+号连接。
    <script type="text/javascript">
    var mystr="hello";
    document.write(mystr+"I love JavaScript"); //多项内容之间用+号连接
    </script>
    第四种:输出HTML标签,并起作用,标签使用“”括起来。
    <script type="text/javascript">
    var mystr="hello";
    document.write(mystr+"<br>");//输出hello后,输出一个换行符
    document.write("JavaScript");
    </script>
    4,document.getElementById("id名");通过指定的id属性来操作html元素
    例如:
    <body>
    <p id="con">JavaScript</p>
    <script type="text/javascript">
    var mychar= document.getElementById("con") ;
    document.write("结果:"+mychar); //输出获取的P标签。
    </script>
    </body>
    5,单行注释://,多行注释用/**/
    6,定义变量规则:
    变量名可以任意取名,但要遵循命名规则:

    1.变量必须使用字母、下划线(_)或者美元符($)开始。

    2.然后可以使用任意多个英文字母、数字、下划线(_)或者美元符($)组成。

    3.不能使用JavaScript关键词与JavaScript保留字
    变量要先声明再赋值:
    var mychar="hello";
    变量可重复赋值:
    var mychar;
    mychar="javascript";
    mychar="hello";
    7,form表单有时用到提交事件后有跳转,或是一个窗口或是一个页面都用form表单来封装
    <form action="" method="get/post"></form>//不用跳转页面时action和method可省略
    8,警告(alert 消息对话框):有一个确定按钮
    alert(字符串或变量);
    <script type="text/javascript">
    var mynum = 30;
    alert("hello!");
    alert(mynum);
    </script>
    结果按顺序弹出消息框
    9,确认(confirm 消息对话框)
    confirm 消息对话框通常用于允许用户做选择的动作,如:“你对吗?”等。弹出对话框(包括一个确定按钮和
    一个取消按钮)。

    语法:

    confirm(str);
    参数说明:

    str:在消息对话框中要显示的文本
    返回值: Boolean值
    返回值:
    当用户点击"确定"按钮时,返回true
    当用户点击"取消"按钮时,返回false
    注: 通过返回值可以判断用户点击了什么按钮

    看下面的代码:
    <script type="text/javascript">
    var mymessage=confirm("你喜欢JavaScript吗?");
    if(mymessage==true)
    { document.write("很好,加油!"); }
    else
    { document.write("JS功能强大,要学习噢!"); }
    </script>
    10,提问(prompt 消息对话框)
    prompt弹出消息对话框,通常用于询问一些需要与用户交互的信息。弹出消息对话框(包含一个确定按钮、取
    消按钮与一个文本输入框)。

    语法:

    prompt(str1, str2);
    参数说明:

    str1: 要显示在消息对话框中的文本,不可修改
    str2:文本框中的内容,可以修改
    返回值:

    1. 点击确定按钮,文本框中的内容将作为函数返回值
    2. 点击取消按钮,将返回null
    看看下面代码:

    var myname=prompt("请输入你的姓名:");
    if(myname!=null)
    { alert("你好"+myname); }
    else
    { alert("你好 my friend."); }
    11,打开新窗口(window.open)
    open() 方法可以查找一个已经存在或者新建的浏览器窗口。

    语法:

    window.open([URL], [窗口名称], [参数字符串])
    参数说明:

    URL:可选参数,在窗口中要显示网页的网址或路径。如果省略这个参数,或者它的值是空字符串,那么窗口
    就不显示任何文档。
    窗口名称:可选参数,被打开窗口的名称。
    1.该名称由字母、数字和下划线字符组成。
    2."_top"、"_blank"、"_self"具有特殊意义的名称。
    _blank:在新窗口显示目标网页
    _self:在当前窗口显示目标网页
    _top:框架网页中在上部窗口中显示目标网页
    3.相同 name 的窗口只能创建一个,要想创建多个窗口则 name 不能相同。

    4.name 不能包含有空格。
    参数字符串:可选参数,设置窗口参数,各参数用逗号隔开。
    参数表:
    top :窗口顶部离开屏幕顶部的像素数 ,值:数字
    left:窗口左部离开屏幕左端的像素数 ,值:数字
    width:窗口的宽度 ,值:数字
    height:窗口的高度,值:数字
    menubar:有没有菜单,值:yes,no 或者1,0
    toolbar:有没有工具栏,,值:yes,no 或者1,0
    scrollbars(两个滚动条,所以是复数):有没有滚动条,,值:yes,no 或者1,0
    status:有么有状态栏,值:yes,no 或者1,0
    resize:是否可以重新设置大小,值:yes,no或者1,0
    fullscreen:全屏,值:yes,no或者1,0
    例如:在新窗体中打开http://www.imooc.com网站,大小为300px * 200px,无菜单,无工具栏,无状态栏,
    有滚动条窗口,距屏顶100像素,屏左0像素。:

    <script type="text/javascript">
    window.open
    ('http://www.imooc.com','_blank','width=300,height=200,top=100,left=0,menubar=no,toolbar=no,
    status=no,scrollbars=yes')//用双引号括起来也可,
    </script>
    注意:运行结果考虑浏览器兼容问题。
    12,关闭窗口(window.close)
    close()关闭窗口

    用法:

    window.close(); //关闭本窗口

    <窗口对象>.close(); //关闭指定的窗口
    例如:关闭新建的窗口。

    <script type="text/javascript">
    var mywin=window.open('http://www.imooc.com'); //将新打的窗口对象,存储在变量mywin中
    mywin.close();
    </script>
    注意:上面代码在打开新窗口的同时,关闭该窗口,看不到被打开的窗口。
    13,认识DOM
    文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法。DOM 将HTML文
    档呈现为带有元素、属性和文本的树结构(节点树)。
    HTML文档可以说由节点构成的集合,三种常见的DOM节点:
    1,元素节点
    2,文本节点
    3,属性节点
    例如:
    <a href="http://www.imooc.com">JavaScript DOM</a>
    元素节点:a
    文本节点:JavaScript DOM
    属性节点:href="http://www.imooc.com"
    14,innerHTML 属性
    innerHTML 属性用于获取或替换 HTML 元素的内容。

    语法:

    Object.innerHTML
    注意:

    1.Object是获取的元素对象,如通过document.getElementById("ID")获取的元素。

    2.注意书写,innerHTML区分大小写。
    例如:
    <body>
    <h2 id="con">javascript</H2>
    <script type="text/javascript">
    var mychar=document.getElementById("con"); ;
    document.write("原标题:"+mychar.innerHTML+"<br>"); //输出原h2标签内容
    mychar.innerHTML="Hello world!";
    document.write("修改后的标题:"+mychar.innerHTML); //输出修改后h2标签内容

    </script></body>
    15,改变 HTML 样式
    HTML DOM 允许 JavaScript 改变 HTML 元素的样式。如何改变 HTML 元素的样式呢?

    语法:

    Object.style.property=new style;
    注意:Object是获取的元素对象,如通过document.getElementById("id")获取的元素。

    基本属性表(property):
    backgroundColor:背景颜色
    height:高度
    width:宽度
    color:文本颜色
    font:在一行设置字体属性
    fontFamily:设置元素的字体系列
    fontSize:字体大小
    例如:
    <script type="text/javascript">
    var mychar= document.getElementById("con");//注意要使用document.getElementById("con")
    mychar.style.color="red";
    mychar.style.backgroundColor="#ccc";
    mychar.style.width="300px";
    </script>
    16,显示和隐藏(display属性)
    网页中经常会看到显示和隐藏的效果,可通过display属性来设置。
    另一种显示和隐藏的属性是:visibility,值为visible和hidden,但是不同于display属性的是,visibility隐藏时图
    片的位置不隐藏,display隐藏时图片的位置也隐藏了。
    语法:

    Object.style.display = value
    注意:Object是获取的元素对象,如通过document.getElementById("id")获取的元素。

    value取值:
    none:不显示(隐藏)
    block:显示为块级元素
    例如:<script>
    function show(){
    var mychar = document.getElementById("con");
    //或document.getElementById("con").style.display="block";
    mychar.style.display="block";
    }
    function hide(){
    var mychar = document.getElementById("con");
    mychar.style.display="none";
    }
    </script>
    16,控制类名(className 属性)
    className 属性设置或返回元素的class 属性。

    语法:

    object.className = classname
    作用:

    1.获取元素的class 属性

    2. 为网页内的某个元素指定一个css样式来更改该元素的外观
    例如:
    <style>
    .one{
    border:1px solid #ccc;
    230px;
    height:50px;
    background:#9CF;
    color:blue;
    }
    </style>
    <script>
    function add(){
    var p1 = document.getElementById("p1");
    p1.className = "one";//将属性为p1的文字的样式改为one的样式
    }
    </script>
    19,操作符优先级:
    算术操作符>比较操作符>逻辑操作符>“=”赋值操作符
    20,数组:
    myarray.length; //获得数组myarray的长度,因为数组的索引总是由0开始,所以一个数组的上下限分别是:
    0和length-1。
    数组随元素的增加,长度也会改变,
    二维数组:元素用中括号括起来
    20,switch语句中:最后一个default后边不必加break
    21,访问字符串对象的方法:

    使用 String 对象的 toUpperCase() 方法来将字符串小写字母转换为大写:

    var mystr="Hello world!";
    var mynum=mystr.toUpperCase();
    以上代码执行后,mynum 的值是:HELLO WORLD!
    使用toLowerCase()方法,将字符串所有大写字母都变成小写的字符串。
    22,Date 日期对象
    日期对象可以储存任意一个日期,并且可以精确到毫秒数(1/1000 秒)。

    定义一个时间对象 :

    var Udate=new Date();
    注意:使用关键字new,Date()的首字母必须大写。

    使 Udate 成为日期对象,并且已有初始值:当前时间(当前电脑系统时间)。

    如果要自定义初始值,可以用以下方法:
    var d = new Date(2012, 10, 1); //2012年10月1日
    var d = new Date('Oct 1, 2012'); //2012年10月1日
    访问方法语法:“<日期对象>.<方法>”

    Date对象中处理时间和日期的常用方法:
    get/setDate() //返回/设置日期
    get/setFullYear() //返回/设置年份,用四位数表示
    get/setYear()//返回/设置年份
    get/setMonth()//返回/设置月份,0:一月。。。。11:十二月,所以加一
    get/setHours()//返回/设置小时,24小时制
    get/setMinutes()//返回/设置分钟数
    get/setSeconds()//返回/设置秒钟数
    get/setTime()//返回/设置时间(毫秒为单位)
    24,返回指定位置的字符
    charAt() 方法可返回指定位置的字符。返回的字符是长度为 1 的字符串。

    语法:

    stringObject.charAt(index)
    参数说明
    index:必须的,表示字符串中某个位置的数字,即字符在字符串中的下标
    注意:1.字符串中第一个字符的下标是 0。最后一个字符的下标为字符串长度减一(string.length-1)。

    2.如果参数 index 不在 0 与 string.length-1 之间,该方法将返回一个空字符串。
    24,返回指定的字符串首次出现的位置
    indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。

    语法

    stringObject.indexOf(substring, startpos)
    参数说明:
    substring:必须的,规定要检索的字符串值,.该方法将从头到尾地检索字符串 stringObject,看它是否含有子
    串 substring。
    startpos:可选的整数参数,规定在字符串中开始检索的位置,他的合法取值是0到stringObjectLength-1,若
    省略该参数,将从字符串的首字付开始检索,从stringObject的startpos位置开始查找substring,如果没有此
    参数将从stringObject的开始位置查找。
    注意:1.indexOf() 方法区分大小写。

    2.如果要检索的字符串值没有出现,则该方法返回 -1。
    25,字符串分割split()
    知识讲解:

    split() 方法将字符串分割为字符串数组,并返回此数组。

    语法:

    stringObject.split(separator,limit)
    参数说明:
    separator:必须的,从该参数指定的地方分割stringObject,从而分成两个数组,参数左侧为一类,右侧为一
    类。
    limit:可选参数,分割的次数,返回的子串不会多于这个参数指定的个数,如果无此参数将不限制次数
    注意:如果把空字符串 ("") 用作 separator,那么 stringObject 中的每个字符之间都会被分割。
    26,提取字符串substring()
    substring() 方法用于提取字符串中介于两个指定下标之间的字符。

    语法:

    stringObject.substring(starPos,stopPos)
    参数说明:
    startPos:必须的,一个非负的整数,开始位置
    stopPos:可选,一个非负的整数,结束位置,如果省略该参数,那么返回的子串会一直到字符串对象的结尾
    注意:

    1. 返回的内容是从 start开始(包含start位置的字符)到 stop-1 处的所有字符,其长度为 stop 减start。

    2. 如果参数 start 与 stop 相等,那么该方法返回的就是一个空串(即长度为 0 的字符串)。

    3. 如果 start 比 stop 大,那么该方法在提取子串之前会先交换这两个参数。
    27,提取指定数目的字符substr()
    substr() 方法从字符串中提取从 startPos位置开始的指定数目的字符串。

    语法:

    stringObject.substr(startPos,length)
    参数说明:
    startPos:必须的,要提取的子串的起始位置,必须是数值
    length:可选,提取字符串的长度,如果省略,返回从startPos开始一直到结尾的字符
    注意:如果参数startPos是负数,从字符串的尾部开始算起的位置。也就是说,-1 指字符串中最后一个字符,
    -2 指倒数第二个字符,以此类推。

    如果startPos为负数且绝对值大于字符串长度,startPos为0。
    28,Math对象
    Math对象,提供对数据的数学计算。

    使用 Math 的属性和方法,代码如下:

    <script type="text/javascript">
    var mypi=Math.PI;
    var myabs=Math.abs(-15);
    document.write(mypi);
    document.write(myabs);
    </script>
    运行结果:

    3.141592653589793
    15
    注意:Math 对象是一个固有的对象,无需创建它,直接把 Math 作为对象使用就可以调用其所有属性和方法
    。这是它与Date,String对象的区别。
    Math 对象属性:
    E:返回算术常量e,即自然对数的底数(约等于2.718)
    LN2:返回2的自然对数(约等于0.693)
    LN10:返回10的自然对数(约等于2.302)
    LOG2E:返回以2为底的e的对数(1.442)
    LOG10E:返回以10为底的e的对数(0.434)
    PI:返回圆周率(3.141519)
    SQRT1_2:返回2的平方根的倒数(0.707)
    SQRT2:返回2 的平方根(1.414)
    Math 对象方法:
    abs(x):返回x的绝对值
    acos(x):返回x的反余弦值
    asin(x):返回x的反正弦值
    atan(x):返回x的反正切值
    29,向上取整ceil()
    ceil() 方法可对一个数进行向上取整。

    语法:

    Math.ceil(x)
    参数说明:
    x:必须说明的值
    注意:它返回的是大于或等于x,并且与x最接近的整数。
    例如: document.write(Math.ceil(-5.9)) 结果是:-5
    30,向下取整floor()
    floor() 方法可对一个数进行向下取整。

    语法:

    Math.floor(x)
    参数说明:
    x:必须说明的值
    注意:返回的是小于或等于x,并且与 x 最接近的整数。
    31,四舍五入round()
    round() 方法可把一个数字四舍五入为最接近的整数。

    语法:

    Math.round(x)
    注意:

    1. 返回与 x 最接近的整数。

    2. 对于 0.5,该方法将进行上舍入。(5.5 将舍入为 6)

    3. 如果 x 与两侧整数同等接近,则结果接近 +∞方向的数字值 。(如 -5.5 将舍入为 -5; -5.52 将舍入为 -6),
    31,随机数 random()
    random() 方法可返回介于 0 ~ 1(大于或等于 0 但小于 1 )之间的一个随机数。
    语法:

    Math.random();
    注意:返回一个大于或等于 0 但小于 1 的符号为正的数字值。
    获得0 ~ 10之间的随机数:(Math.random())*10
    32,Array 数组对象
    数组对象是一个对象的集合,里边的对象可以是不同类型的。数组的每一个成员对象都有一个“下标”,用来
    表示它在数组中的位置,是从零开始的

    数组定义的方法:

    1. 定义了一个空数组:

    var 数组名= new Array();
    2. 定义时指定有n个空元素的数组:

    var 数组名 =new Array(n);
    3.定义数组的时候,直接初始化数据:

    var 数组名 = [<元素1>, <元素2>, <元素3>...];
    我们定义myArray数组,并赋值,代码如下:

    var myArray = [2, 8, 6];
    说明:定义了一个数组 myArray,里边的元素是:myArray[0] = 2; myArray[1] = 8; myArray[2] = 6。

    数组元素使用:

    数组名[下标] = 值;
    注意: 数组的下标用方括号括起来,从0开始。

    数组属性:

    length 用法:<数组对象>.length;返回:数组的长度,即数组里有多少个元素。它等于数组里最后一个元素
    的下标加一。

    数组方法:

    数组连接concat()
    concat() 方法用于连接两个或多个数组。此方法返回一个新数组,不改变原来的数组。

    语法

    arrayObject.concat(array1,array2,...,arrayN)
    参数说明:
    array1:要链接的第一个数组
    。。。
    arrayn:要连接的第n个数组

    注意: 该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。
    例如:
    <script type="text/javascript">
    var myarr1= new Array("010")
    var myarr2= new Array("-","84697581");
    document.write(myarr1.concat(myarr2));//不是 document.write(concat(myarr1,myarr2));
    </script>
    指定分隔符连接数组元素join()
    join()方法用于把数组中的所有元素放入一个字符串。元素是通过指定的分隔符进行分隔的。

    语法:

    arrayObject.join(分隔符separator)
    参数说明:
    separator:可选,指定要使用的分隔符,如果省略,则使用逗号分隔
    例如:
    <script type="text/javascript">
    var myarr1= new Array("86","010")
    var myarr2= new Array("84697581");
    var myarr3= myarr1.concat(myarr2);
    document.write(myarr3.join("-"));
    </script> //结果是86-010-84697581
    32,颠倒数组元素顺序reverse()
    reverse() 方法用于颠倒数组中元素的顺序。

    语法:

    arrayObject.reverse()
    注意:该方法会改变原来的数组,而不会创建新的数组。
    33,选定元素slice()
    slice() 方法可从已有的数组中返回选定的元素。

    语法

    arrayObject.slice(start,end)
    参数说明:
    start:必须的,规定从何处开始选取,若是负数,它是从数组尾部开始算起的位置,-1就是最后一个元素,-2
    是倒数第二个元素
    end:可选,规定从何处结束,若不指定该参数,则切分的数组从start一直到数组结束 的所有元素,若他是负
    数,则它规定的是从数组尾部开始算起的元素
    1.返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。

    2. 该方法并不会修改数组,而是返回一个子数组。
    注意:

    1. 可使用负值从数组的尾部选取元素。

    2.如果 end 未被规定,那么 slice() 方法会选取从 start 到数组结尾的所有元素。

    3. String.slice() 与 Array.slice() 相似。
    数组排序sort()
    sort()方法使数组中的元素按照一定的顺序排列。

    语法:

    arrayObject.sort(方法函数)
    参数说明:
    方法函数:可选,规定排序顺序,必须是函数
    1.如果不指定<方法函数>,则按unicode码顺序排列。

    2.如果指定<方法函数>,则按<方法函数>所指定的排序方法排序。
    myArray.sort(sortMethod);
    注意: 该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a
    和 b,其返回值如下:

    若返回值<=-1,则表示 A 在排序后的序列中出现在 B 之前。
    若返回值>-1 && <1,则表示 A 和 B 具有相同的排序顺序。
    若返回值>=1,则表示 A 在排序后的序列中出现在 B 之后。
    排序函数:sortNuM(a,b)
    <script type="text/javascript">
    function sortNum(a,b) {
    return a - b;
    //升序,如降序,把“a - b”该成“b - a”
    }
    var myarr = new Array("80","16","50","6","100","1");
    document.write(myarr + "<br>");
    document.write(myarr.sort(sortNum));
    </script> //结果是80,16,50,6,100,1 和 1,6,16,50,80,100
    JavaScript 计时器
    在JavaScript中,我们可以在设定的时间间隔之后来执行代码,而不是在函数被调用后立即执行。
    计时器类型:
    一次性计时器:仅在指定的延迟时间之后触发一次。setTimeout
    间隔性触发计时器:每隔一定的时间间隔就触发一次。setInterval
    setTimeout和setInterval可以相互转换,在setTimeout里再调用一个setTimeout可以产生与setInterval相同的
    作用
    例如:
    function display(){
    。。。。。。。。
    setTimeout("display()",1000);
    }
    计时器方法:
    setTimeout()//指定的延迟时间之后来执行代码
    clearTimeout()//取消setTimeout设置
    setinterval()//每隔指定时间执行代码
    Clearinterval()//取消setinterval()设置
    计时器setInterval()
    在执行时,从载入页面后每隔指定的时间执行代码。

    语法:

    setInterval(代码,交互时间);
    参数说明:
    参数说明:

    1. 代码:要调用的函数或要执行的代码串。

    2. 交互时间:周期性执行或调用表达式之间的时间间隔,以毫秒计(1s=1000ms)。

    返回值:

    一个可以传递给 clearInterval() 从而取消对"代码"的周期性执行的值。

    调用函数格式(假设有一个clock()函数):
    setInterval("clock()",1000)

    setInterval(clock,1000)
    取消计时器clearInterval()
    clearInterval() 方法可取消由 setInterval() 设置的交互时间。

    语法:

    clearInterval(id_of_setInterval)
    参数说明:
    id_of_setInterval:由 setInterval() 返回的 ID 值。

    每隔 100 毫秒调用 clock() 函数,并显示时间。
    例如:
    <script type="text/javascript">
    function clock(){
    var time=new Date();
    document.getElementById("clock").value = time;
    }
    var i= setInterval("clock()",100);
    </script>
    <body>
    <form>
    <input type="text" id="clock" size="50" />
    <input type="button" value="Stop" onclick="clearInterval(i)"/>
    //点击Stop按钮后,取消计时器。
    </form>
    </body>
    34,计时器setTimeout()
    setTimeout()计时器,在载入后延迟指定时间后,去执行一次表达式,仅执行一次。

    语法:

    setTimeout(代码,延迟时间);
    参数说明:

    1. 要调用的函数或要执行的代码串。
    2. 延时时间:在执行代码前需等待的时间,以毫秒为单位(1s=1000ms)。
    35,取消计时器clearTimeout()
    setTimeout()和clearTimeout()一起使用,停止计时器。

    语法:

    clearTimeout(id_of_setTimeout)
    参数说明:
    id_of_setTimeout:由 setTimeout() 返回的 ID 值。该值标识要取消的延迟执行代码块。
    例如:
    <script type="text/javascript">
    var num=0;
    var i;
    function startCount(){
    document.getElementById('count').value=num;
    num=num+1;
    i=setTimeout("startCount()",1000);
    }
    function stopCount(){
    clearTimeout(i);
    }

    </script>
    <form>
    <input type="text" id="count" />
    <input type="button" value="Start" onclick="startCount()" />
    <input type="button" value="Stop" onclick="stopCount()" />
    </form>
    35,History 对象
    history对象记录了用户曾经浏览过的页面(URL),并可以实现浏览器前进与后退相似导航的功能。

    注意:从窗口被打开的那一刻开始记录,每个浏览器窗口、每个标签页乃至每个框架,都有自己的history对象与
    特定的window对象关联。

    语法:

    window.history.[属性|方法]
    注意:window可以省略。
    history对象属性
    length:返回浏览器历史列表中的url数量
    history对象方法
    back():加载history列表中的前一个url//window.history.back()相当于window.history.go(-1)
    forward():加载history列表中的后一个url//window.history.forward()相当于window.history.go(1)
    go():加载history列表中的某个具体页面
    36,返回浏览历史中的其他页面
    go()方法,根据当前所处的页面,加载 history 列表中的某个具体的页面。

    语法:

    window.history.go(number);
    参数:
    1:下一个页面,go(1)等价于forward()
    0:当前页面,
    -1:前一个页面,go(-1)等价于back()
    其他数值:要访问的url在history的url列表中的相对位置
    浏览器中,返回当前页面之前浏览过的第二个历史页面,代码如下:

    window.history.go(-2);
    注意:和在浏览器中单击两次后退按钮操作一样。

    同理,返回当前页面之后浏览过的第三个历史页面,代码如下:

    window.history.go(3);
    36,Location对象
    location用于获取或设置窗体的URL,并且可以用于解析URL。

    语法:

    location.[属性|方法]

    location对象属性图示:
    http://www.imooc.com:8080/list.php?courseid=8&chapterid=86#mediaid118
    protocol:http://
    host:www.imooc.com:8080
    hostname:www.imooc.com
    port:8080
    pathname:/list.php?
    search:courseid=&chapterid=86#
    hash:mediaid118
    hash:设置或返回从#号开始的url(锚)
    host:设置或返回主机名和当前的端口号
    hostname:设置或返回当前url的主机名
    href:设置或返回完整的url
    pathname:设置或返回当前url的路径名
    port:设置或返回当前url的路径部分
    protocol:设置或返回当前url的协议
    search:设置或返回从?开始的url(查询部分)
    location 对象方法:
    assign():加载新文档
    reload():重新加载当前文档
    replace():用新文档替换当前文档
    36,Navigator对象
    Navigator 对象包含有关浏览器的信息,通常用于检测浏览器与操作系统的版本。

    对象属性:
    appcodeName:浏览器代码名的字符串表示
    appName:浏览器名称
    appVersion:浏览器的平台和版本信息
    platform:运行浏览器的操作系统平台
    userAgent:返回由客户机发送服务器的useragent头部的值
    37,userAgent
    返回用户代理头的字符串表示(就是包括浏览器版本信息等的字符串)

    语法

    navigator.userAgent
    几种浏览的user_agent.,像360的兼容模式用的是IE、极速模式用的是chrom的内核。
    38,screen对象
    screen对象用于获取用户的屏幕信息。

    语法:

    window.screen.属性
    对象属性:
    availHeight:窗口可以使用的屏幕高度,单位像素
    availWidth:窗口可以使用的屏幕宽度,单位像素
    colorDepth:用户浏览器表示的颜色位数,通常为32位(每像素的位数)
    pixelDepth:用户浏览器表示的颜色位数,也为32位(每像素的位数)(IE不支持此属性)
    height:屏幕的高度,单位像素
    width:屏幕的宽度,单位像素
    39,屏幕分辨率的高和宽
    window.screen 对象包含有关用户屏幕的信息。
    1. screen.height 返回屏幕分辨率的高
    2. screen.width 返回屏幕分辨率的宽
    注意:
    1.单位以像素计。
    2. window.screen 对象在编写时可以不使用 window 这个前缀。
    40,DOM:文档对象模型
    DOM包括三种:Core DOM (核心dom),XML DOM, HTML DOM
    现在主要讲解html dom
    DOM节点操作主要有四部分:
    增:
    createElement(),
    appendChild(),
    insertBefore(),
    cloneNode()
    删:
    removeChild();
    改:
    更改属性:setAttribute()/对象名.属性名
    更改内容:innerHTML,innerText
    查:getElementById(),getElementsByName(),getElementsByTagName(),parentNode,firstChild,lastChild,
    getElementsByName()方法
    返回带有指定名称的节点对象的集合。

    语法:

    document.getElementsByName(name)
    与getElementById() 方法不同的是,通过元素的 name 属性查询元素,而不是通过 id 属性。

    注意:

    1. 因为文档中的 name 属性可能不唯一,所有 getElementsByName() 方法返回的是元素的数组,而不是一个
    元素。

    2. 和数组类似也有length属性,可以和访问数组一样的方法来访问,从0开始。
    41,getElementsByTagName()方法
    返回带有指定标签名的节点对象的集合。返回元素的顺序是它们在文档中的顺序。

    语法:

    getElementsByTagName(Tagname)
    说明:

    1. Tagname是标签的名称,如p、a、img等标签名。

    2. 和数组类似也有length属性,可以和访问数组一样的方法来访问,所以从0开始。
    例如:
    function getTagElements()
    {
    var myI=document.getElementsByTagName("input");
    alert(myI.length);
    }
    41,区别getElementByID,getElementsByName,getElementsByTagName
    以人来举例说明,人有能标识身份的身份证,有姓名,有类别(大人、小孩、老人)等。

    1. ID 是一个人的身份证号码,是唯一的。所以通过getElementById获取的是指定的一个人。

    2. Name 是他的名字,可以重复。所以通过getElementsByName获取名字相同的人集合。

    3. TagName可看似某类,getElementsByTagName获取相同类的人集合。如获取小孩这类人,
    getElementsByTagName("小孩")。

    把上面的例子转换到HTML中,如下:

    <input type="checkbox" name="hobby" id="hobby1"> 音乐
    input标签就像人的类别。

    name属性就像人的姓名。

    id属性就像人的身份证。

    方法:
    getElementById:只能获得一个
    getElementsByName:获得一组
    getElementsByTagName:获得一组
    注意:方法区分大小写
    例如: <body>
    <form>
    请选择你爱好:<br>
    <input type="checkbox" name="hobby" id="hobby1"> 音乐
    <input type="checkbox" name="hobby" id="hobby2"> 登山
    <input type="checkbox" name="hobby" id="hobby3"> 游泳
    <input type="checkbox" name="hobby" id="hobby4"> 阅读
    <input type="checkbox" name="hobby" id="hobby5"> 打球
    <input type="checkbox" name="hobby" id="hobby6"> 跑步 <br>
    <input type="button" value = "全选" onclick = "checkall();">
    <input type="button" value = "全不选" onclick = "clearall();">
    <p>请输入您要选择爱好的序号,序号为1-6:</p>
    <input id="wb" name="wb" type="text" >
    <input name="ok" type="button" value="确定" onclick = "checkone();">
    </form>
    <script type="text/javascript">
    function checkall(){
    var hobby = document.getElementsByTagName("input");
    for(i = 0;i < hobby.length;i++){
    if(hobby[i].type == "checkbox"){
    hobby[i].checked = true; }
    }
    }
    function clearall(){
    var hobby = document.getElementsByName("hobby");
    for(i = 0;i < hobby.length;i++){
    hobby[i].checked = false;}
    }
    function checkone(){
    var j=document.getElementById("wb").value;
    var hobby = document.getElementById("hobby"+j);
    hobby.checked = true; }
    </script>
    </body>

    42,指定的值。

    语法:

    elementNode.setAttribute(name,value)
    有时改变某个节点的属性时,也可以用elementNode.attributeName="xxxx",即对象名.属性名
    说明:

    1.name: 要设置的属性名。

    2.value: 要设置的属性值。

    注意:

    1.把指定的属性设置为指定的值。如果不存在具有指定名称的属性,该方法将创建一个新属性。

    2.类似于getAttribute()方法,setAttribute()方法只能通过元素节点对象调用的函数。
    节点属性
    在文档对象模型 (DOM) 中,每个节点都是一个对象。DOM 节点有三个重要的属性 :

    1. nodeName : 节点的名称

    2. nodeValue :节点的值

    3. nodeType :节点的类型

    一、nodeName 属性: 节点的名称,是只读的。

    1. 元素节点的 nodeName 与标签名相同
    2. 属性节点的 nodeName 是属性的名称
    3. 文本节点的 nodeName 永远是 #text
    4. 文档节点的 nodeName 永远是 #document

    二、nodeValue 属性:节点的值

    1. 元素节点的 nodeValue 是 undefined 或 null
    2. 文本节点的 nodeValue 是文本自身
    3. 属性节点的 nodeValue 是属性的值

    三、nodeType 属性: 节点的类型,是只读的。以下常用的几种结点类型:

    元素类型 节点类型
    元素 1
    属性 2
    文本 3
    注释 8
    文档 9
    43,访问子结点childNodes
    访问选定元素节点下的所有子节点的列表,返回的值可以看作是一个数组,他具有length属性。

    语法:

    elementNode.childNodes
    注意:

    如果选定的节点没有子节点,则该属性返回不包含节点的 NodeList。
    访问子结点的第一和最后项
    firstChild是第一个出现的子节点,lastChild是最后一个出现的子节点
    一、firstChild 属性返回‘childNodes’数组的第一个子节点。如果选定的节点没有子节点,则该属性返回
    NULL。

    语法:

    node.firstChild
    说明:与elementNode.childNodes[0]是同样的效果。

    二、 lastChild 属性返回‘childNodes’数组的最后一个子节点。如果选定的节点没有子节点,则该属性返回
    NULL。

    语法:

    node.lastChild
    说明:与elementNode.childNodes[elementNode.childNodes.length-1]是同样的效果。

    注意: 上一节中,我们知道Internet Explorer 会忽略节点之间生成的空白文本节点,而其它浏览器不会。我们
    可以通过检测节点类型,过滤子节点。 (以后章节讲解)
    44,访问父节点parentNode
    获取指定节点的父节点

    语法:

    elementNode.parentNode
    注意:父节点只能有一个。

    看看下面的例子,获取 P 节点的父节点,代码如下:

    <div id="text">
    <p id="con"> parentNode 获取指点节点的父节点</p>
    </div>
    <script type="text/javascript">
    var mynode= document.getElementById("con");
    document.write(mynode.parentNode.nodeName);
    </script>
    运行结果:

    parentNode 获取指点节点的父节点
    DIV
    访问祖节点:

    elementNode.parentNode.parentNode
    44,访问兄弟节点
    1. nextSibling 属性可返回某个节点之后紧跟的节点(处于同一树层级中)。

    语法:

    nodeObject.nextSibling
    说明:如果无此节点,则该属性返回 null。

    2. previousSibling 属性可返回某个节点之前紧跟的节点(处于同一树层级中)。

    语法:

    nodeObject.previousSibling
    说明:如果无此节点,则该属性返回 null。

    注意: 两个属性获取的是节点。Internet Explorer 会忽略节点间生成的空白文本节点(例如,换行符号),而
    其它浏览器不会忽略。
    45,插入节点appendChild()
    在指定节点的最后一个子节点列表之后添加一个新的子节点。

    语法:

    appendChild(newnode)
    参数:

    newnode:指定追加的节点。
    例如:
    var otest = document.getElementById("test");
    var newnode=document.createElement("li");
    newnode.innerHTML="PHP";
    otest.appendChild(newnode);
    46,插入节点insertBefore()
    insertBefore() 方法可在已有的子节点前插入一个新的子节点。

    语法:

    insertBefore(newnode,node);

    参数:

    newnode: 要插入的新节点。

    node: 指定此节点前插入节点。
    注意: otest.insertBefore(newnode,node); 也可以改为: otest.insertBefore(newnode,otest.childNodes[0]);
    46,删除节点removeChild()
    removeChild() 方法从子节点列表中删除某个节点。如删除成功,此方法可返回被删除的节点,如失败,则返
    回 NULL。

    语法:

    nodeObject.removeChild(node)
    参数:

    node :必需,指定需要删除的节点。
    例如:
    function clearText() {
    var content=document.getElementById("content");
    for(var i=content.childNodes.length-1;i>=0;i--){
    var childNode = content.childNodes[i];
    content.removeChild(childNode);
    }
    }
    47,替换元素节点replaceChild()
    replaceChild 实现子节点(对象)的替换。返回被替换对象的引用。

    语法:

    node.replaceChild (newnode,oldnew )
    参数:

    newnode : 必需,用于替换 oldnew 的对象。
    oldnew : 必需,被 newnode 替换的对象。
    <script type="text/javascript">
    function replaceMessage(){
    var newnode=document.createElement("i");
    var newnodeTest=document.createTextNode("JavaScript");
    newnode.appendChild(newnodeTest);
    var oldNode=document.getElementById("oldnode");
    oldNode.parentNode.replaceChild(newnode,oldNode);

    }
    47,创建元素节点createElement
    createElement()方法可创建元素节点。此方法可返回一个 Element 对象。

    语法:

    document.createElement(tagName)
    参数:

    tagName:字符串值,这个字符串用来指明创建元素的类型。

    注意:要与appendChild() 或 insertBefore()方法联合使用,将元素显示在页面中。
    48,创建文本节点createTextNode
    createTextNode() 方法创建新的文本节点,返回新创建的 Text 节点。

    语法:

    document.createTextNode(data)
    参数:

    data : 字符串值,可规定此节点的文本。
    50,浏览器窗口可视区域大小
    获得浏览器窗口的尺寸(浏览器的视口,不包括工具栏和滚动条)的方法:

    一、对于IE9+、Chrome、Firefox、Opera 以及 Safari:

    • window.innerHeight - 浏览器窗口的内部高度

    • window.innerWidth - 浏览器窗口的内部宽度

    二、对于 Internet Explorer 8、7、6、5:

    • document.documentElement.clientHeight表示HTML文档所在窗口的当前高度。

    • document.documentElement.clientWidth表示HTML文档所在窗口的当前宽度。

    或者

    Document对象的body属性对应HTML文档的<body>标签

    • document.body.clientHeight

    • document.body.clientWidth

    在不同浏览器都实用的 JavaScript 方案:

    var w= document.documentElement.clientWidth
    || document.body.clientWidth;
    var h= document.documentElement.clientHeight
    || document.body.clientHeight;
    49,页面滚动时使用的函数是window.onscroll=function(){}
    50,网页尺寸scrollHeight
    scrollHeight和scrollWidth,获取网页内容高度和宽度。

    如果oDiv 位于可视区内部:则有以下:
    可视区距离页面顶部的坐标,页面顶部到可视区的距离:
    var scrollTop=document.documentElement.scrollTop || document.body.scrollTop;
    oDiv到顶部的距离:scrollTop+oDiv到可视区顶部的距离,即:
    scrollTop+(document.documentElement.clientHeight-oDiv.offsetHeight)/2

    var sw=document.documentElement.scrollWidth || document.body.scrollWidth;
    一、针对IE、Opera:

    scrollHeight 是网页内容实际高度,可以小于 clientHeight。

    二、针对NS、FF:

    scrollHeight 是网页内容高度,不过最小值是 clientHeight。也就是说网页内容实际高度小于 clientHeight 时
    ,scrollHeight 返回 clientHeight 。

    三、浏览器兼容性

    var w=document.documentElement.scrollWidth
    || document.body.scrollWidth;
    var h=document.documentElement.scrollHeight
    || document.body.scrollHeight;
    注意:区分大小写

    scrollHeight和scrollWidth还可获取Dom元素中内容实际占用的高度和宽度。
    51,网页尺寸offsetHeight
    offsetHeight和offsetWidth,获取网页内容高度和宽度(包括滚动条等边线,会随窗口的显示大小改变)。

    一、值

    offsetHeight = clientHeight + 滚动条 + 边框。

    二、浏览器兼容性

    var w= document.documentElement.offsetWidth
    || document.body.offsetWidth;
    var h= document.documentElement.offsetHeight
    || document.body.offsetHeight;
    //10的编程挑战待完成:
    <!DOCTYPE html>
    <html>
    <head lang="en">
    <meta charset="UTF-8">
    <title>实践题 - 选项卡</title>
    <style type="text/css">
    /* CSS样式制作 */
    ul{
    float:left;
    }
    #chose1{
    margin-top:30px;
    margin-left:30px;
    display:block;
    height:50px;
    280px;
    border:1px d black;
    }
    #chose2{
    margin-top:30px;
    margin-left:30px;
    display:none;
    height:50px;
    280px;
    }
    #chose3{
    margin-top:30px;
    margin-left:30px;
    display:none;
    height:50px;
    280px;
    }
    #btn1{

    height:40px;
    60px;
    }
    #btn2{

    height:40px;
    60px;
    }
    #btn3{
    height:40px;
    60px;
    }
    </style>
    <script type="text/javascript">

    // JS实现选项卡切换


    </script>

    </head>
    <body>
    <!-- HTML页面布局 -->
    <ul><button id="btn1">房产</button></ul>
    <ul><button id="btn2">家居</button></ul>
    <ul><button id="btn3">二手房</button></ul>
    <div id="chose1">
    275万购昌平邻铁三居 总价20万买一居
    200万内购五环三居 140万安家东三环
    北京首现零首付楼盘 53万购东5环50平
    京楼盘直降5000 中信府 公园楼王现房</div>
    <div id="chose2">
    40平出租屋大改造 美少女的混搭小窝
    经典清新简欧爱家 90平老房焕发新生
    新中式的酷色温情 66平撞色活泼家居
    瓷砖就像选好老婆 卫生间烟道的设计
    </div>
    <div id="chose3">
    通州豪华3居260万 二环稀缺2居250w甩
    西3环通透2居290万 130万2居限量抢购
    黄城根小学学区仅260万 121平70万抛!
    独家别墅280万 苏州桥2居优惠价248万
    </div>
    </body>
    </html>
    使用javascript制作网页特效:
    BOM:浏览器对象模型,包括window对象(就是窗口),location对象(网页的地址栏),history对象(历
    史记录),document对象(浏览器内的网页内容),location,history,document三个对象又是window对象
    的属性
    history:是有关浏览过的url信息
    location:是有关当前的url信息,写法:window.location或者location=“http://www.sohu.com”
    跳转链接:location.href=.......
    刷新页面:location.reload()
    <a href="javascript:location.href=‘flower.html ' ; ">查看详情</a>//此处是点击链接跳转到另一个页面,
    再来连接里写javascript代码,需要先写上javascript:
    <a href="javascript:location.reload();"></a>
    document对象的属性:
    referrer:连接来源即点出当前网页的原始网页,document.referrer
    URL:获取当前网页的url地址,document.URL
    onload:是加载完后,
    <script>
    function display(){
    }
    </script>
    <body onload=“display()”></body>//加载完页面后执行display()函数
    或者在script里加载函数:
    <script>
    function display(){
    }
    window.onload=display;//注意此处不是display(),若display(a)有参数,则另当别论,可以使用匿名函数
    </script>
    使用匿名函数:window.onload=function(){ display(); }
    Table表格对象:
    Table对象的属性:
    rows[]:所有的行,形成一个数组,
    常用方法:增加行:insertRow(index),删除行:deleteRow(index)
    TableRow:一行
    TableRow对象有两个属性,分别是ceils[]和rowIndex
    ceils[]:某一行的所有单元格,形成一个数组
    rowIndex表示返回该行在表中的位置,从0开始
    常用方法:
    insertCeil(index):在一行中的指定位置插入单元格
    deleteCeil(index):删除行中指定的单元格
    TableCeil:一个单元格
    有三个属性:
    ceilIndex:返回单元格的位置
    innerHTML:设置或返回单元格的html
    className:设置或返回元素的class属性
    对于TableCeil对象,主要使用它的属性
    级联菜单:
    例如,当选择省份时,右边显示该省份的城市
    数组:
    读取数组的两种方法:
    1,for循环
    2,for ,,,in
    var fruit=new Array("apple","orange","peach","banana");
    for(var x in fruit){//其中var x 可以省略
    document.write(fruit[x]+"<br/>");
    }
    下拉菜单:
    select标签,它包含三个属性,
    1)options属性,是一个选项数组options[],用来返回该下拉菜单中的所有选项。
    创建选项:var option=new Option(显示文本,值)
    2)length:选项总数
    3)selectedIndex:被选中选项的索引号
    常用方法 :
    add(Option对象,添加位置),//添加位置可以为null,表示添加在末尾
    常用事件:
    onchange:表示改变选项时触发
    鼠标变成手型:
    cursor:pointer;
    li选项前边的圆点隐藏:list-style:none;
    <a></a>点击链接即a标签时触发函数的形式:
    <a href="javascript:show()">。。。</a>
    图片设置为绝对定位时:
    向右是正,向下是正;
    设置页面中某个位置的图片,随着滚动条的滚动而一直浮动:
    1)将image放入div中,设置绝对定位浮在页面上
    2)鼠标滚动时,图片的top,left坐标跟随改变
    3)获取鼠标滚动距离,scrollTop(滚动条向上滚动的距或x轴到滚动轮的纵向距离),scrollLeft(滚动条向
    左滚动的距离或y轴到滚动轮的横向距离)
    4)利用鼠标滚动事件onScroll事件调用函数移动div位置:onscroll()
    style对象定位方面的样式:
    left,top:左上角
    right,bottom:右下角
    position:absolute,relative,static(fix)//只有将position设置为absolute或relative时,定位才生效
    z-index:叠放顺序
    要使用表示元素位置的像素值时,要使用parseInt转化整型:
    parseInt(x):将x转化成整型,如var c=parseInt(a)+parseInt(b)+“px”;
    获取或设置元素的坐标:
    IE浏览器:只能用currentStyle对象
    firefox:用getComputedStyle();
    document.defaultView.getComputedStyle(元素对象,null).属性
    获取到文档对象(根节点):即html标签
    var a=document.documentElement,/不用body,/因为因为有些浏览器不兼容
    窗体加载时触发函数:window.onload=函数名;//注意函数不加括号
    窗体滚动时触发函数:window.onscroll=函数名;
    ????下拉菜单中的选项停留问题??????
    1,类:javascript是一种基于原型的语言,没有类的声明语句,比如c++和java,javascript可用方法作类,定
    义一个类和定义一个函数一样简单,如
    function Person(){}或者var Person=function(){}
    2,对象(类的实例):
    function Person(){}
    var person1=new Person();
    var person2=new Person();
    构造器:
    在实例化时构造器被调用 (也就是对象实例被创建时)。构造器是对象中的一个方法。 在JavaScript,中函数就可
    以作为构造器使用,因此不需要特别地定义一个构造器方法. 每个声明的函数都可以在实例化后被调用执行
    构造器常用于给对象的属性赋值或者为调用函数做准备。
    3,属性 (对象属性)
    属性就是 类中包含的变量;每一个对象实例有若干个属性. 为了正确的继承,属性应该被定义在类的原型属性 (
    函数)中。
    可以使用 关键字 this调用类中的属性, this是对当前对象的引用。 从外部存取(读/写)其属性的语法是:
    InstanceName.Property; 这与C++,Java或者许多其他语言中的语法是一样的 (在类中语法 this.Property 常
    用于set和get属性值)
    4,方法(对象属性)
    方法与属性很相似, 不同的是:一个是函数,另一个可以被定义为函数。 调用方法很像存取一个属性, 不同的
    是add () 在方法名后面很可能带着参数. 为定义一个方法, 需要将一个函数赋值给类的 prototype 属性; 这个赋
    值给函数的名称就是用来给对象在外部调用它使用的。
    function Person(firstName) {
    this.firstName = firstName;
    }
    Person.prototype.sayHello = function() {
    alert("Hello, I'm " + this.firstName);
    };
    var person1 = new Person("Alice");
    var person2 = new Person("Bob");
    // call the Person sayHello method.
    person1.sayHello(); // alerts "Hello, I'm Alice"
    person2.sayHello(); // alerts "Hello, I'm Bob"
    继承
    创建一个或多个类的专门版本类方式称为继承(Javascript只支持单继承)。 创建的专门版本的类通常叫做子
    类,另外的类通常叫做父类。 在Javascript中,继承通过赋予子类一个父类的实例并专门化子类来实现。在现
    代浏览器中你可以使用 Object.create 实现继承.
    在下面的例子中, 我们定义了 Student类作为 Person类的子类. 之后我们重定义了sayHello() 方法并添加了
    sayGoodBye() 方法.

    // 定义Person构造器
    function Person(firstName) {
    this.firstName = firstName;
    }

    // 在Person.prototype中加入方法
    Person.prototype.walk = function(){
    alert("I am walking!");
    };
    Person.prototype.sayHello = function(){
    alert("Hello, I'm " + this.firstName);
    };

    // 定义Student构造器
    function Student(firstName, subject) {
    // 调用父类构造器, 确保(使用Function#call)"this" 在调用过程中设置正确
    Person.call(this, firstName);

    // 初始化Student类特有属性
    this.subject = subject;
    };

    // 建立一个由Person.prototype继承而来的Student.prototype对象.
    // 注意: 常见的错误是使用 "new Person()"来建立Student.prototype.
    // 这样做的错误之处有很多, 最重要的一点是我们在实例化时
    // 不能赋予Person类任何的FirstName参数
    // 调用Person的正确位置如下,我们从Student中来调用它
    Student.prototype = Object.create(Person.prototype); // See note below

    // 设置"constructor" 属性指向Student
    Student.prototype.constructor = Student;

    // 更换"sayHello" 方法
    Student.prototype.sayHello = function(){
    console.log("Hello, I'm " + this.firstName + ". I'm studying " + this.subject + ".");
    };

    // 加入"sayGoodBye" 方法
    Student.prototype.sayGoodBye = function(){
    console.log("Goodbye!");
    };

    // 测试实例:
    var student1 = new Student("Janet", "Applied Physics");
    student1.sayHello(); // "Hello, I'm Janet. I'm studying Applied Physics."
    student1.walk(); // "I am walking!"
    student1.sayGoodBye(); // "Goodbye!"

    // Check that instanceof works correctly
    console.log(student1 instanceof Person); // true
    console.log(student1 instanceof Student); // true
    对于“Student.prototype = Object.create(Person.prototype);”这一行,在不支持 Object.create方法的老
    JavaScript引擎中,可以使用一个"polyfill"(又名"shim",查看文章链接),或者使用一个function来获得相
    同的返回值,就像下面:

    function createObject(proto) {
    function ctor() { }
    ctor.prototype = proto;
    return new ctor();
    }
    // Usage:
    Student.prototype = createObject(Person.prototype);
    封装
    在上一个例子中,Student类虽然不需要知道Person类的walk()方法是如何实现的,但是仍然可以使用这个方
    法;Student类不需要明确地定义这个方法,除非我们想改变它。 这就叫做封装,对于所有继承自父类的方法
    ,只需要在子类中定义那些你想改变的即可。
    抽象
    抽象是允许模拟工作问题中通用部分的一种机制。这可以通过继承(具体化)或组合来实现。
    JavaScript通过继承实现具体化,通过让类的实例是其他对象的属性值来实现组合。
    JavaScript Function 类继承自Object类(这是典型的具体化) 。Function.prototype的属性是一个Object实
    例(这是典型的组合)。
    多态
    就像所有定义在原型属性内部的方法和属性一样,不同的类可以定义具有相同名称的方法;方法是作用于所在的
    类中。并且这仅在两个类不是父子关系时成立(继承链中,一个类不是继承自其他类)。
    1,JavaScript 中的类型应该包括这些:

    Number(数字)
    String(字符串)
    Boolean(布尔)
    Symbol(符号)(第六版新增)
    Object(对象)包括:
    1,Function(函数),2,Array(数组),3,Date(日期),4,RegExp(正则表达式)
    Null(空)
    Undefined(未定义)
    JavaScript 还有一种内置Error(错误)类型,这个会在之后的介绍中提到;现在我们先讨论下上面这些类型。
    1,数字:
    和其他编程语言(如 C 和 Java)不同,JavaScript 不区分整数值和浮点数值,所有数字在 JavaScript 中均用
    浮点数值表示,所以在进行数字运算的时候要特别注意。如:
    0.1 + 0.2 = 0.30000000000000004
    2,JavaScript 支持标准的算术运算符,包括加法、减法、取模(或取余)等等。还有一个之前没有提及的内
    置对象 Math(数学对象),用以处理更多的高级数学函数和常数:
    Math.sin(3.5);
    var d = Math.PI * (r + r);
    你可以使用内置函数 parseInt() 将字符串转换为整型。该函数的第二个参数表示字符串所表示数字的基(进制
    ):
    parseInt("123", 10); // 123
    parseInt("010", 10); //10
    如果调用时没有提供第二个参数(字符串所表示数字的基),2013 年以前的 JavaScript 实现会返回一个意外
    的结果:
    parseInt("010"); // 8
    parseInt("0x10"); // 16
    这是因为字符串以数字 0 开头,parseInt()函数会把这样的字符串视作八进制数字;同理,0x开头的字符串则
    视为十六进制数字。
    如果想把一个二进制数字字符串转换成整数值,只要把第二个参数设置为 2 就可以了:
    parseInt("11", 2); // 3
    JavaScript 还有一个类似的内置函数 parseFloat(),用以解析浮点数字符串,与parseInt()不同的地方是,
    parseFloat()只应用于解析十进制数字。
    单元运算符 + 也可以把数字字符串转换成数值:
    + "42"; // 42
    + "010"; // 10
    + "0x10"; // 16
    如果给定的字符串不存在数值形式,函数会返回一个特殊的值 NaN(Not a Number 的缩写):
    parseInt("hello", 10); // NaN
    要小心NaN:如果把 NaN 作为参数进行任何数学运算,结果也会是 NaN:
    NaN + 5; //NaN
    JavaScript 还有两个特殊值:Infinity(正无穷)和 -Infinity(负无穷):
    1 / 0; // Infinity
    -1 / 0; // -Infinity
    可以使用内置函数 isFinite() 来判断一个变量是否为 Infinity, -Infinity 或 NaN:
    isFinite(1/0); // false
    isFinite(-Infinity); // false
    isFinite(NaN); // false
    可以使用内置函数 isNaN() 来判断一个变量是否为 NaN:
    isNaN(NaN); // true
    JavaScript 还有两个特殊值:Infinity(正无穷)和 -Infinity(负无穷):
    1 / 0; // Infinity
    -1 / 0; // -Infinity
    可以使用内置函数 isFinite() 来判断一个变量是否为 Infinity, -Infinity 或 NaN:
    isFinite(1/0); // false
    isFinite(-Infinity); //
    false
    isFinite(NaN); // false
    字符串
    JavaScript 中的字符串是一串Unicode 字符序列。这对于那些需要和多语种网页打交道的开发者来说是个好消
    息。更准确地说,它们是一串UTF-16编码单元的序列,每一个编码单元由一个 16 位二进制数表示。每一个
    Unicode字符由一个或两个编码单元来表示。
    如果想表示一个单独的字符,只需使用长度为 1 的字符串。
    通过访问字符串的 长度(编码单元的个数)属性可以得到它的长度。
    "hello".length; // 5
    这是我们第一次碰到 JavaScript 对象。我们有没有提过你可以像 objects 一样使用字符串?是的,字符串也
    有methods(方法)能让你操作字符串和获取字符串的信息。
    "hello".charAt(0); // "h"
    "hello, world".replace("hello", "goodbye"); // "goodbye, world"
    "hello".toUpperCase(); // "HELLO"
    其他类型
    JavaScript 中 null 和 undefined 是不同的,前者表示一个空值(non-value),必须使用null关键字才能访问
    ,后者是“undefined(未定义)”类型的对象,表示一个未初始化的值,也就是还没有被分配的值。我们之
    后再具体讨论变量,但有一点可以先简单说明一下,JavaScript 允许声明变量但不对其赋值,一个未被赋值的
    变量就是 undefined 类型。还有一点需要说明的是,undefined 实际上是一个不允许修改的常量。
    JavaScript 包含布尔类型,这个类型的变量有两个可能的值,分别是 true 和 false(两者都是关键字)。根据
    具体需要,JavaScript 按照如下规则将变量转换成布尔类型:
    false、0、空字符串("")、NaN、null 和 undefined 被转换为 false
    所有其他值被转换为 true
    也可以使用 Boolean() 函数进行显式转换:
    Boolean(""); // false
    Boolean(234); // true
    变量
    在 JavaScript 中声明一个新变量的方法是使用关键字 var:
    var a;
    var name = "simon";
    如果声明了一个变量却没有对其赋值,那么这个变量的类型就是 undefined。
    JavaScript 与其他语言的(如 Java)的重要区别是在 JavaScript 中语句块(blocks)是没有作用域的,只有
    函数有作用域。因此如果在一个复合语句中(如 if 控制结构中)使用 var 声明一个变量,那么它的作用域是整
    个函数(复合语句在函数中)。但是从 ECMAScript Edition 6 开始将有所不同的, let 和 const 关键字允许
    你创建块作用域的变量。
    运算符
    JavaScript的算术操作符包括 +、-、*、/ 和 % ——求余(与模运算不同)。赋值使用 = 运算符,此外还有一
    些复合运算符,如 += 和 -=,它们等价于 x = x op y。
    相等的比较稍微复杂一些。由两个“=(等号)”组成的相等运算符有类型自适应的功能,具体例子如下:
    123 == "123" // true
    1 == true; // true
    如果在比较前不需要自动类型转换,应该使用由三个“=(等号)”组成的相等运算符:
    1 === true; //false
    123 === "123"; // false
    JavaScript 还支持 != 和 !== 两种不等运算符,具体区别与两种相等运算符的区别类似。
    2,JavaScript 还提供了 位操作符。,
    3,&& 和 || 运算符使用短路逻辑(short-circuit logic),是否会执行第二个语句(操作数)取决于第一个操
    作数的结果。在需要访问某个对象的属性时,使用这个特性可以事先检测该对象是否为空:
    var name = o && o.getName();
    或运算可以用来设置默认值:
    var name = otherName || "default";
    类似地,JavaScript 也有一个用于条件表达式的三元操作符:
    var allowed = (age > 18) ? "yes" : "no";
    4,default 语句是可选的。switch 和 case 都可以使用需要运算才能得到结果的表达式;在 switch 的表达式
    和 case 的表达式是使用 === 严格相等运算符进行比较的:
    switch(1 + 3){
    case 2 + 2:
    yay();
    break;
    default:
    neverhappens();
    }
    5,对象
    JavaScript 中的对象可以简单理解成“名称-值”对,正因为 JavaScript 中的一切(除了核心类型,core
    object)都是对象,所有 JavaScript 程序必然与大量的散列表查找操作有着千丝万缕的联系,而散列表擅长的
    正是高速查找。“名称”部分是一个 JavaScript 字符串,“值”部分可以是任何 JavaScript 的数据类型——
    包括对象。这使用户可以根据具体需求,创建出相当复杂的数据结构。
    有两种简单方法可以创建一个空对象:
    var obj = new Object();
    和:
    var obj = {};
    这两种方法在语义上是相同的。第二种更方便的方法叫作“对象字面量(object literal)”法。这种也是
    JSON 格式的核心语法,一般我们优先选择第二种方法。
    “对象字面量”也可以用来在对象实例中定义一个对象:
    var obj = {
    name: "Carrot",
    "for": "Max",
    details: {
    color: "orange",
    size: 12
    }
    }
    对象的属性可以通过链式(chain)表示方法进行访问:
    obj.details.color; // orange
    obj["details"]["size"]; // 12
    数组
    JavaScript 中的数组是一种特殊的对象。它的工作原理与普通对象类似(以数字为属性名,但只能通过[] 来访
    问),但数组还有一个特殊的属性——length(长度)属性。这个属性的值通常比数组最大索引大 1。
    创建数组的传统方法是:
    var a = new Array();
    a[0] = "dog";
    a.length; // 3
    使用数组字面量(array literal)法更加方便:
    var a = ["dog", "cat", "hen"];
    a.length; // 3
    注意,Array.length 并不总是等于数组中元素的个数,如下所示:
    var a = ["dog", "cat", "hen"];
    a[100] = "fox";
    a.length; // 101
    记住:数组的长度是比数组最大索引值多一的数。
    可以通过如下方式遍历一个数组:
    for (var i = 0; i < a.length; i++) {
    // Do something with a[i]
    }
    这么做效率不太好,因为每循环一次都要计算一次长度。改进的版本是:
    for (var i = 0, len = a.length; i < len; i++) {
    // Do something with a[i]
    }
    遍历数组的另一种方法是使用 for...in 循环。注意,如果有人向 Array.prototype 添加了新的属性,使用这样
    的循环这些属性也同样会被遍历。所以并不推荐这种方法:
    for (var i in a) {
    // Do something with a[i]
    }
    ECMAScript 5 增加了遍历数组的另一个方法 forEach():
    ["dog", "cat", "hen"].forEach(function(currentValue, index, array) {
    // Do something with currentValue or array[index]
    });
    如果想在数组后追加元素,只需要:
    a.push(item);
    函数
    学习 JavaScript 最重要的就是要理解对象和函数两个部分。最简单的函数就像下面这个这么简单:
    function add(x, y) {
    var total = x + y;
    return total;
    }
    这个例子包括你需要了解的关于基本函数的所有部分。一个 JavaScript 函数可以包含 0 个或多个已命名的变
    量。函数体中的表达式数量也没有限制。你可以声明函数自己的局部变量。return 语句在返回一个值并结束函
    数。如果没有使用 return 语句,或者一个没有值的 return 语句,JavaScript 会返回 undefined。
    已命名的参数更像是一个指示而没有其他作用。如果调用函数时没有提供足够的参数,缺少的参数会被
    undefined 替代。
    add(); // NaN
    // 不能在 undefined 对象上进行加法操作
    你还可以传入多于函数本身需要参数个数的参数:
    add(2, 3, 4); // 5
    // 将前两个值相加,4被忽略了
    这看上去有点蠢。函数实际上是访问了函数体中一个名为 arguments 的内部对象,这个对象就如同一个类似
    于数组的对象一样,包括了所有被传入的参数。让我们重写一下上面的函数,使它可以接收任意个数的参数:
    function add(){
    var sum=0;
    for(var i=0,j=arguments.length; i<j; i++){
    sum+=arguments[i];
    }
    return sum;
    }
    add(2,3,4,5); //24
    接下来创建一个求平均数的函数:
    function avg() {
    var sum = 0;
    for (var i = 0, j = arguments.length; i < j; i++) {
    sum += arguments[i];
    }
    return sum / arguments.length;
    }
    avg(2, 3, 4, 5); // 3.5
    求一个数组的的平均值:
    function avg(arr){
    var sum=0;
    for(var i=0,j=arr.length; i<j; i++){
    sum+=arr[i];
    }
    return sum/arr.length;
    }
    但如果能重用我们已经创建的那个函数不是更好吗?幸运的是 JavaScript 允许使用任意函数对象的apply() 方
    法来调用该函数,并传递给它一个包含了参数的数组。
    avg.apply(null, [2, 3, 4, 5]); // 3.5
    JavaScript 允许创建匿名函数:
    var avg = function() {
    var sum = 0;
    for (var i = 0, j = arguments.length; i < j; i++) {
    sum += arguments[i];
    }
    return sum / arguments.length;
    };
    document.write(avg(3,4,5,6,7)); //5
    JavaScript 允许以递归方式调用函数。递归在处理树形结构(比如浏览器 DOM)时非常有用。
    function countChars(elm) {
    if (elm.nodeType == 3) { // 文本节点
    return elm.nodeValue.length;
    }
    var count = 0;
    for (var i = 0, child; child = elm.childNodes[i]; i++) {
    count += countChars(child);
    }
    return count;
    }
    这里需要说明一个潜在问题——既然匿名函数没有名字,那该怎么递归调用它呢?在这一点上,JavaScript 允
    许你命名这个函数表达式。你可以命名立即调用的函数表达式(IIFES——Immediately Invoked Function
    Expressions),如下所示:
    var charsInBody = (function counter(elm) {
    if (elm.nodeType == 3) { // 文本节点
    return elm.nodeValue.length;
    }
    var count = 0;
    for (var i = 0, child; child = elm.childNodes[i]; i++) {
    count += counter(child);
    }
    return count;
    })(document.body);
    自定义对象:
    在经典的面向对象语言中,对象是指数据和在这些数据上进行的操作的集合。与 C++ 和 Java 不同,
    JavaScript 是一种基于原型的编程语言,并没有 class 语句,而是把函数用作类。那么让我们来定义一个人名
    对象,这个对象包括人的姓和名两个域(field)。名字的表示有两种方法:“名 姓(First Last)”或“姓, 名
    (Last, First)”。使用我们前面讨论过的函数和对象概念,可以像这样完成定义
    Person.prototype 是一个可以被Person的所有实例共享的对象。它是一个名叫原型链(prototype chain)的
    查询链的一部分:当你试图访问一个 Person 没有定义的属性时,解释器会首先检查这个 Person.prototype
    来判断是否存在这样一个属性。所以,任何分配给 Person.prototype 的东西对通过 this 对象构造的实例都是
    可用的。
    function Person(first, last) {
    this.first = first;
    this.last = last;
    }
    Person.prototype.fullName = function() {
    return this.first + ' ' + this.last;
    }
    Person.prototype.fullNameReversed = function() {
    return this.last + ', ' + this.first;
    }
    s = new Person("Simon", "Willison");
    Person.prototype.firstNameCaps = function() {
    return this.first.toUpperCase()
    }
    s.firstNameCaps(); // SIMON
    还可以给 JavaScript 的内置函数原型(prototype)添加东西。让我们给 String 添加一个方法用来返回逆序
    的字符串:
    var s = "Simon";
    String.prototype.reversed = function() {
    var r = "";
    for (var i = this.length - 1; i >= 0; i--) {
    r += this[i];
    }
    return r;
    }
    s.reversed(); // nomiS
    定义新方法也可以在字符串字面量上用(string literal)。
    正如我前面提到的,原型组成链的一部分。那条链的根节点是 Object.prototype,它包括 toString() 方法—
    —将对象转换成字符串时调用的方法。这对于调试我们的 Person 对象很有用:

    var s = new Person("Simon", "Willison");
    s; // [object Object]
    Person.prototype.toString = function() {
    return '<Person: ' + this.fullName() + '>';
    }
    s.toString(); // <Person: Simon Willison>
    记得之前我们说的 avg.apply() 中的第一个参数 null,现在我们可以回头看看这个东西了。apply() 的第一个
    参数应该是一个被当作 this 来看待的对象。下面是一个 new 方法的简单实现:
    function trivialNew(constructor, ...args) {
    var o = {}; // 创建一个对象
    constructor.apply(o, args);
    return o;
    }
    这并不是 new 的完整实现,因为它没有创建原型(prototype)链。想举例说明 new 的实现有些困难,因为
    你不会经常用到这个,但是适当了解一下还是很有用的。在这一小段代码里,...args(包括省略号)叫作剩余
    参数(rest arguments)
    因此调用
    var bill = trivialNew(Person, "William", "Orange");
    可认为和调用如下语句是等效的
    var bill = new Person("William", "Orange");
    apply() 有一个姐妹函数,名叫 call,它也可以允许你设置 this,但它带有一个扩展的参数列表而不是一个数组

    function lastNameCaps() {
    return this.last.toUpperCase();
    }
    var s = new Person("Simon", "Willison");
    lastNameCaps.call(s);
    // 和以下方式等价
    s.lastNameCaps = lastNameCaps;
    s.lastNameCaps();
    内部函数
    JavaScript 允许在一个函数内部定义函数,这一点我们在之前的 makePerson() 例子中也见过。关于
    JavaScript 中的嵌套函数,一个很重要的细节是它们可以访问父函数作用域中的变量:
    function betterExampleNeeded() {
    var a = 1;
    function oneMoreThanA() {
    return a + 1;
    }
    return oneMoreThanA();
    }
    如果某个函数依赖于其他的一两个函数,而这一两个函数对你其余的代码没有用处,你可以将它们嵌套在会被
    调用的那个函数内部,这样做可以减少全局作用域下的函数的数量,这有利于编写易于维护的代码。
    这也是一个减少使用全局变量的好方法。当编写复杂代码时,程序员往往试图使用全局变量,将值共享给多个
    函数,但这样做会使代码很难维护。内部函数可以共享父函数的变量,所以你可以使用这个特性把一些函数捆
    绑在一起,这样可以有效地防止“污染”你的全局命名空间——你可以称它为“局部全局(local global)”
    。虽然这种方法应该谨慎使用,但它确实很有用,应该掌握。
    闭包
    makeAdder 这个名字本身应该能说明函数是用来做什么的:它创建了一个新的 adder 函数,这个函数自身带
    有一个参数,它被调用的时候这个参数会被加在外层函数传进来的参数上。
    这里发生的事情和前面介绍过的内嵌函数十分相似:一个函数被定义在了另外一个函数的内部,内部函数可以
    访问外部函数的变量。唯一的不同是,外部函数被返回了,那么常识告诉我们局部变量“应该”不再存在。但
    是它们却仍然存在——否则 adder 函数将不能工作。也就是说,这里存在 makeAdder 的局部变量的两个不
    同的“副本”——一个是 a 等于5,另一个是 a 等于20。那些函数的运行结果就如下所示:
    x(6); // 返回 11
    y(7); // 返回 27
    下面来说说到底发生了什么。每当 JavaScript 执行一个函数时,都会创建一个作用域对象(scope object),
    用来保存在这个函数中创建的局部变量。它和被传入函数的变量一起被初始化。这与那些保存的所有全局变量
    和函数的全局对象(global object)类似,但仍有一些很重要的区别,第一,每次函数被执行的时候,就会创
    建一个新的,特定的作用域对象;第二,与全局对象(在浏览器里面是当做 window 对象来访问的)不同的是
    ,你不能从 JavaScript 代码中直接访问作用域对象,也没有可以遍历当前的作用域对象里面属性的方法。

    所以当调用 makeAdder 时,解释器创建了一个作用域对象,它带有一个属性:a,这个属性被当作参数传入
    makeAdder 函数。然后 makeAdder 返回一个新创建的函数。通常 JavaScript 的垃圾回收器会在这时回收
    makeAdder 创建的作用域对象,但是返回的函数却保留一个指向那个作用域对象的引用。结果是这个作用域
    对象不会被垃圾回收器回收,直到指向 makeAdder 返回的那个函数对象的引用计数为零。

    作用域对象组成了一个名为作用域链(scope chain)的链。它类似于原形(prototype)链一样,被
    JavaScript 的对象系统使用。

    一个闭包就是一个函数和被创建的函数中的作用域对象的组合。

    闭包允许你保存状态——所以它们通常可以代替对象来使用。
    内存泄露

    使用闭包的一个坏处是,在 IE 浏览器中它会很容易导致内存泄露。JavaScript 是一种具有垃圾回收机制的语言
    ——对象在被创建的时候分配内存,然后当指向这个对象的引用计数为零时,浏览器会回收内存。宿主环境提
    供的对象都是按照这种方法被处理的。

    浏览器主机需要处理大量的对象来描绘一个正在被展现的 HTML 页面——DOM 对象。浏览器负责管理它们的
    内存分配和回收。

    IE 浏览器有自己的一套垃圾回收机制,这套机制与 JavaScript 提供的垃圾回收机制进行交互时,可能会发生内
    存泄露。

    在 IE 中,每当在一个 JavaScript 对象和一个本地对象之间形成循环引用时,就会发生内存泄露。如下所示:

    function leakMemory() {
    var el = document.getElementById('el');
    var o = { 'el': el };
    el.o = o;
    }
    这段代码的循环引用会导致内存泄露:IE 不会释放被 el 和 o 使用的内存,直到浏览器被彻底关闭并重启后。

    这个例子往往无法引起人们的重视:一般只会在长时间运行的应用程序中,或者因为巨大的数据量和循环中导
    致内存泄露发生时,内存泄露才会引起注意。

    不过一般也很少发生如此明显的内存泄露现象——通常泄露的数据结构有多层的引用(references),往往掩盖
    了循环引用的情况。

    闭包很容易发生无意识的内存泄露。如下所示:

    function addHandler() {
    var el = document.getElementById('el');
    el.onclick = function() {
    el.style.backgroundColor = 'red';
    }
    }
    这段代码创建了一个元素,当它被点击的时候变红,但同时它也会发生内存泄露。为什么?因为对 el 的引用不
    小心被放在一个匿名内部函数中。这就在 JavaScript 对象(这个内部函数)和本地对象之间(el)创建了一个
    循环引用。

    这个问题有很多种解决方法,最简单的一种是不要使用 el 变量:

    function addHandler(){
    document.getElementById('el').onclick = function(){
    this.style.backgroundColor = 'red';
    };
    }
    有一种窍门解决因闭包而引入的循环引用,是添加另外一个闭包:

    function addHandler() {
    var clickHandler = function() {
    this.style.backgroundColor = 'red';
    };
    (function() {
    var el = document.getElementById('el');
    el.onclick = clickHandler;
    })();
    }
    内部函数被直接执行,并在 clickHandler 创建的闭包中隐藏了它的内容。

    另外一种避免闭包的好方法是在 window.onunload 事件发生期间破坏循环引用。很多事件库都能完成这项工
    作。注意这样做将使 Firefox 中的 bfcache 无法工作。所以除非有其他必要的原因,最好不要在 Firefox 中注
    册一个unload 的监听器。

    JavaScript 数据类型和数据结构
    动态类型
    JavaScript 是一种弱类型或者说动态语言。这意味着你不用提前声明变量的类型,在程序运行过程中,类型会
    被自动确定。这也意味着你可以使用同一个变量保存不同类型的数据:
    var foo = 42; // foo is a Number now
    var foo = "bar"; // foo is a String now
    var foo = true; // foo is a Boolean now
    数据类型
    最新的 ECMAScript 标准定义了 7 种数据类型:

    6 种 原始类型:
    Boolean
    Null
    Undefined
    Number
    String
    Symbol (ECMAScript 6 新定义)
    和 Object类型(function函数对象,array数组对象,date日期对象,regexp正则表达式对象)
    原始值
    除 Object 以外的所有类型都是不可变的(值本身无法被改变)。例如,与 C 语言不同,JavaScript 中字符串
    是不可变的(译注:如,JavaScript 中对字符串的操作一定返回了一个新字符串,原始字符串并没有被改变)
    。我们称这些类型的值为“原始值”。
    布尔类型

    布尔表示一个逻辑实体,可以有两个值:true 和 false。

    Null 类型

    Null 类型只有一个值: null,更多详情可查看 null 和 Null 。

    Undefined 类型

    一个没有被赋值的变量会有个默认值 undefined,更多详情可查看 undefined 和 Undefined。
    数字类型
    并没有为整数给出一种特定的类型。除了能够表示浮点数外,还有一些带符号的值:+Infinity,-Infinity 和
    NaN (非数值,Not-a-Number)。

    要检查值是否大于或小于 +/-Infinity,你可以使用常量 Number.MAX_VALUE 和 Number.MIN_VALUE。另
    外在 ECMAScript 6 中,你也可以通过 Number.isSafeInteger() 方法还有 Number.MAX_SAFE_INTEGER 和
    Number.MIN_SAFE_INTEGER 来检查值是否在双精度浮点数的取值范围内。 超出这个范围,JavaScript 中的
    数字不再安全了,也就是只有 second mathematical interger 可以在 JavaScript 数字类型中正确表现。

    数字类型只有一个整数,它有两种表示方法: 0 可表示为 -0 和 +0("0" 是 +0 的简写)。 在实践中,这也几
    乎没有影响。 例如 +0 === -0 为真。 但是,你可能要注意除以0的时候:

    42 / +0; // Infinity
    42 / -0; // -Infinity
    尽管一个数字常常仅代表它本身的值,但JavaScript提供了一些位运算符。 这些位运算符和一个单一数字通过
    位操作可以用来表现一些布尔值。但这通常被认为是一个不好的做法,虽然 JavaScript 不提供其他的方式来表
    示一组布尔值(如一个布尔值数组或一个布尔值分配给命名属性的对象)。位操作也容易使代码难以阅读,理
    解和维护, 在一些非常受限的情况下,可能需要用到这些技术,比如试图应付本地存储的存储限制。 位操作
    只应该是用来优化尺寸的最后选择。
    字符串类型

    JavaScript的字符串类型用于表示文本数据。它是一组16位的无符号整数值的“元素”。在字符串中的每个元
    素占据了字符串的位置。第一个元素的索引为0,下一个是索引1,依此类推。字符串的长度是它的元素的数量

    不同于类 C 语言,JavaScript 字符串是不可更改的。这意味着字符串一旦被创建,就不能被修改。但是,可以
    基于对原始字符串的操作来创建新的字符串。例如:

    获取一个字符串的子串可通过选择个别字母或者使用 String.substr().
    两个字符串的连接使用连接操作符 (+) 或者 String.concat().
    注意代码中的“字串符类型”!

    可以使用字串符来表达复杂的数据。以下是一些很好的性质:

    容易连接构造复杂的字串符
    字串符容易被调试(你看到的往往在字串符里)
    字串符通常是许多APIs的常见标准 (input fields, local storage values, XMLHttpRequest当使用
    responseText等的时候回应) 而且他只能与字符串一同使用。
    符号类型

    符号(Symbols)是ECMAScript 第6版新定义的。符号类型是唯一的并且是不可修改的, 并且也可以用来作为
    Object的key的值(如下). 在某些语言当中也有类似的原子类型(Atoms). 你也可以认为为它们是C里面的枚举类
    型. 更多细节请看 Symbol 和 Symbol 。

    对象
    在计算机科学中, 对象是指内存中的可以被 标识符引用的一块区域.
    详见msdn,web技术文档 ->javascript
    结构化数据: JSON

    JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,来源于 JavaScrip 同时也被多种语言所
    使用。 JSON 用于构建通用的数据结构。参见 JSON 以及 JSON 了解更多。

    标准库中更多的对象

    JavaScript 有一个内置对象的标准库。请查看参考来了解更多对象。

    1,使用 typeof 操作符判断对象类型,
    2,判断一个值是否是NaN

    等号运算符(== 和 ===) 不能被用来判断一个值是否是 NaN。必须使用 Number.isNaN() 或 isNaN() 函
    数。
    NaN === NaN; // false
    Number.NaN === NaN; // false
    isNaN(NaN); // true
    isNaN(Number.NaN); // true
    function valueIsNaN(v) { return v !== v; }
    valueIsNaN(1); // false
    valueIsNaN(NaN); // true
    valueIsNaN(Number.NaN); // true
    3,一个未初始化的变量的值为undefined,一个没有传入实参的形参变量的值为undefined,如果一个函数什么
    都不返回,则该函数默认返回undefined.
    你可以使用严格相等运算符来判断一个值是否是undefined:普通相等运算符是==,严格相等运算符是===
    var x;
    if (x === undefined) {
    // 执行到这里
    }
    else {
    // 不会执行到这里
    }
    另外,还可以使用typeof来判断:
    var x;
    if (typeof x === 'undefined') {
    // 执行到这里
    }
    有时必须使用typeof的原因是,如果一个变量根本没有被声明,只有使用typeof判断才不会报错,用相等运算符判
    断会抛出异常.
    // x没有被声明过
    if (typeof x === 'undefined') { // 不会报错
    // these statements execute
    }
    if(x === undefined){ // 抛出ReferenceError异常
    }
    不过如果要检测的变量是个全局变量,可以不使用typeof.可以通过检测全局对象的同名属性来代替:

    // x可能没有被声明过,但如果已经声明了的话,x是个全局变量
    if (window.x === undefined) { // 即使window.x不存在,也不会报错
    // 可能会执行到这里
    }
    if(x === undefined){ // 如果window.x不存在,则会抛出ReferenceError异常
    }
    4,null
    null 是一个字面量(而不是全局对象的一个属性,undefined 是)。在 APIs 中,null 常被放在期望一个对象
    ,但是不引用任何对象的参数位置。当检测 null 或 undefined 时,注意相等(==)与全等(===)两个操作
    符的区别 (前者会执行类型转换)。
    null 与 undefined 的不同点:
    typeof null // object (bug in ECMAScript, should be null)
    typeof undefined // undefined
    null === undefined // false
    null == undefined // true
    让元素移出视线的方法:
    1,display:none; 显示为无,实际存在
    2,visibility:hidden; 隐藏,不存在
    3,width,height的设置
    4,透明度,为零则是看不见
    5,改变left或是top值,移出去
    6,拿一个白色的div盖住后,慢慢移动
    7,定义margin为负值,,,,12种以上
    写一个js的步骤:
    1,实现布局
    2,了解原理
    3,学习语法

    10,使用浏览器调试代码时:
    第一次调处错误,报错后,浏览器会在缓存中记录错误,所以改正代码进行第二次调试前,应该把浏览器关掉
    ,清除缓存,再第二次调试
    11,函数不会自动执行,
    12,<script></script>脚本代码,可以不放在文档的最后面,但是可能不执行,这时就要把脚本代码封装成
    一个函数,放在文档的前面,然后在文档全部加载完后对其进行调用,如下:
    <head>
    <script>
    window.onload=abc;//注意不加括号,否则就直接执行下面的函数了,此时这段js代码就可以随便放了
    function abc(){sfsafsafaeawr}
    //或者是利用匿名函数如下:
    window.onload=function(){ }
    </script>
    </head>
    注意:也可以将window换成,body,img等,则是body.onload()和img.onload()
    13,其它函数也可以使用匿名函数,如:li.onclick=function(){}
    14,函数也可以就没有名字,就是匿名函数,
    可以以这种方式调用:元素.事件=function (){ };
    何时使用有名函数,何时使用匿名函数?
    同一个函数会被多次调用时,则将该函数命名,使用有名函数
    15,onmouseout:鼠标离开事件。
    onmousemove:鼠标抚摸事件
    onmouseover:鼠标移入,移到元素上面触发的事件
    16,随时写,随时做测试:
    利用alert();
    使用css伪类时:这些状态包括:活动状态,已被访问状态,未被访问状态,和鼠标悬停状态。
    a:link,a:visited,a:hover,a:active
    注释:在 CSS 定义中,a:hover 必须位于 a:link 和 a:visited 之后,这样才能生效!
    注释:在 CSS 定义中,a:active 必须位于 a:hover 之后,这样才能生效!
    p:first-child {font-weight: bold;}
    li:first-child {text-transform:uppercase;}
    第一个规则将作为某元素第一个子元素的所有 p 元素设置为粗体。第二个规则将作为某个元素(在 HTML 中
    ,这肯定是 ol 或 ul 元素)第一个子元素的所有 li 元素变成大写。
    提示:最常见的错误是认为 p:first-child 之类的选择器会选择 p 元素的第一个子元素。
    :lang 伪类
    :lang 伪类使你有能力为不同的语言定义特殊的规则。在下面的例子中,:lang 类为属性值为 no 的 q 元素定义
    引号的类型:
    <html>
    <head>

    <style type="text/css">
    q:lang(no)
    {
    quotes: "~" "~"
    }
    </style>

    </head>

    <body>
    <p>文字<q lang="no">段落中的引用的文字</q>文字</p>
    </body></html>
    10,读操作:
    元素.属性名
    11,写操作:
    元素.属性名=新值,
    读取元素内的内容:innerHTML
    obj.innerHTML=新值;//可以替换原来的所有内容
    12,定义文字的显示方向:
    direction:rtl,ltr,
    属性操作的注意事项:
    1,所有的相对路径都不能拿来做判断,如图片的地址(img的src是href='1.jpg',或者href='html/index.html'
    它是相对路径),而href='http://www.miaov.com/1.jpg',是绝对路径,可以用来做判断,
    2,颜色值也不要拿来做判断,
    3,innerHTML的值不要拿来做判断
    4,有些属性不兼容时,可以利用隐藏和显示,来回避不兼容的问题
    5,兼容性问题的解决方案:如,float值进行修改时有些浏览器不兼容,:如object.style.float="left";这种写
    法对IE浏览器就不兼容,可以使用下面这种写法:IE(styleFloat),非IE(cssFloat);也可以通过定义类选
    择器,然后修改类选择器,如:
    .left{float:left;}
    .right{float:right;},需要时,修改元素本身的选择器即可
    6,中括号[]和点 . 的使用和区别:
    点后面的是固定的,不能修改,如:object.style.width="100px"
    中括号后的可以随便写,如:object.style[oAttr.value]=oVal.value;
    oBtn.onclick=function(){
    oAttr.value
    oVal.value
    oDiv.style[oAttr.value]=oVal.value;
    }
    20,当对同一个事物进行重复点击时(或者点击一次,执行两件事中的一件事),可以利用开关来进行判断,
    onoff是开关,布尔值true则为真,
    var onOff=true;
    if(onOff){
    this.style.background=url(images/aa.jpg);
    onOff=false;
    }else{
    this.style.background=url(images/bb.jpg);
    onOff=true;
    }
    21,数组的最后一句:arr[arr.length-1]
    往数组的最后添加元素:arr.push();
    22,先写css样式,再写js代码
    23,left,top,right,bottom:相对与容器左端,顶端,有段,底端的偏移量,也可以为负值
    24,调节背景颜色透明度的是:filter:alpha(opacity:80);//IE浏览器
    opacity:0.6//非IE浏览器
    25,将一个div块元素放到底部时,要让父元素有一个固定的定位,position:relative或是absolute,子元素必
    须是绝对定位:position:absolute,padding-bottom:0px;
    26,document.getElementById()是静态方法,前边只能是document,找到的是一个元素,
    document.getElementsByTagName()是动态方法,前边可以不是document,找到的 是元素的集合
    党同一个页面中含有多个相同标签元素时,可以不利用document来获取,而改用父元
    素.getElementsByTagName();
    28,对于页面中只含有一个的元素,可以利用 document.body.innerHTML='DSD';
    document.title='';
    document.body.innerHTML="<input type=""><input type=""><input type="">";
    29,for循环的另一种格式:
    for(;i<3;){ alert(i); i++; }
    alert(i);//注意此时i的值为3
    30,for(var i=0;i<3;i++){
    arr[i].onclick=function(){
    //此时i的值就是3,不是0等
    }
    }
    30,innerHTML使用时注意:默认是替换当前内容,若要使其内容添加,则要使用
    document.body.innerHTML+='<input type="text" value="hhhhh">';
    31,考虑性能问题:
    使用数组 时,先把数组的长度存起来,在使用它的长度;
    当给页面添加较多的内容时,可以不直接添加到body上,而是先把内容添加到某个变量上,最后再将变量添加
    到body里,
    var str=‘’;
    for(var i=0;i<1000;i++){
    str+=‘<input type="button" value=''>’;
    }
    document.body.innerHTML=str;
    32,使用for循环,生成坐标:
    33,改变样式的方法:
    1),使用style属性:style.width;style.heigth;等
    2),使用cssText:obj.style.cssText='100px;height:100px';
    34,防止重复执行循环:
    1)在按钮身上找原因(用户体验不好),obj.disabled=true;
    2)先清空,再生成,obj.innerHTML='';性能较差
    3)使用判断,利用开关onoff。设置成true,false,
    36,html标签属性,自定义属性:
    var aBtn=document.getElementsByTagName("input");
    aBtn[0].abc=456; //自定义属性abc, 值为456
    相当于是给input标签添加了属性abc:
    <input type="button" abc=456 value="按钮">
    35,js可以为任意个html元素添加自定义属性:
    格式:对象.属性名:
    var aBtn=document.getElementByTagName("input");
    for(var i=0;i<aBtn.length;i++){
    aBtn[i].abc=123;//为每个input元素添加abc属性,值为123,
    aBtn[i].xyz=true;//为每个input元素添加xyz属性,值为true,
    }
    <input type="text" value=""/>
    <input type="text" value=""/>
    <input type="text" value=""/>
    36,for循环里若包含其他函数,函数里尽量不要用for循环里的变量:如:
    for(var i=0;i<aBtn.length;i++){

    aBtn[i].index=i;//使用自定义属性(自定义索引),将i值赋给自定义属性;
    aBtn[i].onclick=function(){
    //不要直接用这种形式,alert(i);而是要添加上面的自定义属性,
    alert(this.index);
    }
    }
    37,想建立“匹配”,“对应”关系,就用自定义索引:
    var arr=["李四","张三","王五"];
    var aBtn=document.getElementByTagName("input");
    var aP=document.getElementByTagName("p");
    for(var i=0;i<aBtn.length;i++){
    aBtn[i].index=i;
    aBtn[i].onclick=function(){
    this.value=arr[this.index]; //this指的是aBtn[i]
    aP[this.index].innerHTML=arr[this.index];
    }
    }
    37,对于单一元素,可以通过document.getElementsByTagName("")[0];获取元素
    38,对于图片切换时的列表选项li:若想在点击图片时,切换每个li选项及样式:有两种方法:
    1)全部清空,当前添加
    for(var i=0;i<aLi.length;i++){
    aLi[i].className='';//全部清空
    }
    this.className='active'; //当前添加
    2)清空上个,当前添加
    var num=0;
    var oldLi=null;
    oldLi=aLi[num];
    oldLi.className='';
    oldLi=this;
    this.className='active';
    38,存在两层或两层以上的for循环时,尽量先不要在里面写事件,如点击事件等,先将要操作的对象拿出来,
    放在外面定义,例如声明一个数组,再利用数组对象,调用push函数,进行添加其他元素,
    var aLi=null;
    var arrLi=[];
    for(var i=0;i<aUl.length;i++){
    aLi=aUl[i].getElementsByTagName("li");
    for(var j=0;j<aLi.length;j++){
    arrLi.push(aLi[j]); //先不写点击事件,//只是为了找元素
    }
    }
    for(var i=0;i<arrLi.length;i++){ //添加事件
    arrLi[i].onclick=function(){
    //注意此处两个for之间有函数包裹,所以可以用重复的i,若没有函数,则不可以用重复的i,而是j
    for(var i=0;i<arrLi.length;i++){
    arrLi[i].className='';
    }
    this.className="hover"; //先清空再添加
    }
    }
    39,任何一个非空对象object,都可以添加自定义属性,自定义属性的后面的值可以任意为任何东西
    也可以添加函数:但是调用时要注意加括号;
    var obj=document;
    obj.fn1=function(){alert(123);}
    obj.fn1();
    var arr=[1,2,3,5];
    alert(arr.length);
    arr[2]=345;
    alert(arr);//此时弹出的结果为1,2,345,5
    向数组里添加东西的函数:push();如arr.push();
    var json={ name:'hjhhh',age:5 };//json也是对象,用于存放数据等,不仅仅是数字
    alert(json.name+'今年'+json.age+'岁');
    var n=null;
    n.abc=123;
    alert(n.abc);//回报错,因为n是空的对象,不存在,
    35,类型转换:
    1)将看起来像数字的字符串转换为数字:Number();
    //Number()可以将空字符串转换为0,将true装换为1,将空数组转化为0,将数组里的字符串也转化为数字,
    json的则转不了,空类型也可以转化为0;未定义类型的则转不了,若数组里的元素太多了,也转不了
    36,parseInt和number():
    不是整体转换,一个一个字符转换,碰到空格向后继续找,
    parseInt(b,10)//10代表十进制
    36,parseFloat:认得小数点,
    37,parseInt和parseFloat合作使用:
    if(parseInt(num)==parseFloat(num)){
    alert(num+'是整数');
    }else{
    alert(num+'是小数');
    }
    38,显示类型转换(强制类型转换)
    Number();
    parseInt();
    parseFloat();
    39,隐式类型转换:
    -*/%,++,--:将字符串进行转换然后变为数字
    +:变成字符串,和-*/相反
    >,<:也会转换成数字
    数字之间的比较和字符串都比较是不同的:
    数字之间的比较:指的比较,
    字符串的比较:一位一位的比较,比较每一位的大小,若第一位比较后分出了大小,后面就不用看了
    !取反:,感叹号后面的不论是数字还是字符串,都转化成布尔值,把右边的数据类型转换成布尔值
    ==:判断值,不论数据类型是什么,最后比较的结果转换成布尔值,
    ===:判断值和数据类型,先判断类型,再判断值,
    无论是强制还是隐形,转换不了时,都会出现NaN,
    出现非法运算时,也会出现NaN
    NaN:表示不是数字的数字类型
    isNaN:是不是不是一个数字(不是数字)
    NaN的特性,:
    1)代表的布尔值是false
    2)所有的东西自己和自己都是相等的,但是NaN除外,它自己和自己不相等,
    3)是数字类型,但不是数字,
    isNaN():
    参数不是数字,讨厌数字,参数也不可为布尔值,因为布尔值的返回结果是1或0,其他均可,值为true,false

    若参数是包含数字的字符串,isNaN默认使用Number()来进行数字类型转换,
    41,函数传递的参数:就是js的 数据类型,包括数字,字符串,布尔,函数,对象,未定义等类型
    42,函数传参数时:
    当参数为匿名函数时
    43,,调用函数时,加括号:
    fn3( function(a){alert(a)})
    function fn3(fn){ fn(100); }
    当参数为有名参数时,不加括号:
    function fn4(){
    alert(4);
    }
    fn3(fn4);//不加括号
    function fn3(fn){
    fn();
    }
    44,利用函数传参(重用代码)时,
    1,尽量保证html代码结构一致,可以通过父级元素选取子元素
    2,把核心程序实现,用函数包起来
    3,把每组不同的值找出来,通过传参实现
    44,从html里获取的任何内容的值都是字符串形式,不能用+=。而要用++;或者将字符串先转换为number
    类型,再计算,
    45,边框颜色:burlywood,border:burlywood solid 1px;
    46,段落缩进:text-indent:20px;
    text-indent,可以应用在段落p上,也可以应用在li标签的缩进上
    46,作用域:
    作用:读,写
    域:空间,范围,区域,
    一个script就是一个域,在script里声明的都是全局变量,全局函数,只要是域,就会发生预解析和逐行解读,
    浏览器:
    js解析器:
    1)预解析:先找一些东西存在仓库里:var, function,参数,一开始读的所有变量都是未定义,在正式运行
    代码之前,都提前顾了一个值,就是未定义,所有的函数,在正式运行之前,都是整个函数块,一个整体,,
    预解析该函数得到的就是整个代码块,
    预解析就是对var,function,参数进行筛选,得到最终的存在库里的东西
    2)再逐行读代码:
    每次读取时,都是先看预解析时的仓库里的对应的值,然后通过表达式修改相应变量的值
    表达式:如,等号=,+,-,*,%,/,++,--,!,参数,.....Number(),这些都可以改写变量的都叫表达式
    表达式可以修改预解析的值,
    47,预解析时,遇到重复定义的变量和函数,留下函数(不论声明顺序如何),
    若是重复定义的是级别相同的,如函数,则遵循优先级,留下后声明的,
    例如:
    alert(a);//弹出弹出函数function a(){alert(4)},原因如上
    var a=1;
    alert(a); //弹出1,
    function a(){alert(2);}
    alert(a);//弹出1
    var a=3;
    alert(a); //弹出3
    function a(){alert(4)}
    alert(a); //弹出3
    alert(typeof(a));//弹出number
    //执行结果是,弹出函数function a(){alert(4)},弹出1,弹出1,弹出3,/弹出3,弹出number
    执行过程:
    1)预解析:
    a=1是未定义值; //根据var关键字
    a=function a(){alert(2);} //根据function
    但是由于未定义值1和函数function a(){alert(2);}相比,留下函数function a(){alert(2);},因为变量和函数重名
    ,留下函数,
    a=3也是未定义值 //根据var关键字
    所以留下函数function a(){alert(2);}
    a=function a(){alert(4);} //根据function
    函数function a(){alert(2);}和函数function a(){alert(4);}相比,留下最后声明的function a(){alert(4);},
    所以预解析筛选完后最终得到a=function a(){alert(4);},
    所以第一个alert(a)得到的就是function a(){alert(4);},
    2)逐行读代码:
    第一个alert(a)就弹出function a(){alert(4);}
    然后var a=1修改了未定义的a值,使其变成1,所以第二个和第三个alert(a)也弹出1,
    后面又有var a=3,将a修改成3,所以第四个和第五个alert()弹出3,
    48,js页面中,可以有多个script代码块,但执行时是分块执行的,先处理一个script里的代码再执行另外的
    script代码块
    49,域:自上而下的,上面声明的东西就会先存到库里
    函数:由里向外,若函数内部(子级)没有var等关键字,就向上找父级里的内容看有无,称之为作用域链。
    50,函数也是域,
    1)也会先预解析:var,function,参数,a=,,,,,,
    2)逐行读代码:函数内部的变量和函数外部的变量无关,
    例如:
    var a=1;
    function fn1(){
    alert(a); //未定义
    var a=2;
    } //弹出的是undefined和1
    fn1(); //弹出的是undefined
    alert(a); /弹出的是1
    函数内部的变量前面的var有很大影响:
    例如:
    var a=1;
    function fn1(){
    alert(a); //弹出1
    a=2; //没有var的情况,此处,局部变量a将全局变量a改成了2,
    }
    fn1();//弹出1
    alert(a); //弹出2,因为全局变量改变了
    过程:
    1)预解析:var ,function,参数.....,得到:
    a=未定义
    fn1=function fn1(){
    alert(a);
    a=2;
    }
    2)逐行读代码:
    表达式
    函数调用(函数也是域,所以又开始预解析,读代码)
    1)预解析:var,function,参数,得到:
    由于内部没有var,function,参数等,所以向上找,得a=1,并且将外部的a改成2
    2)逐行读代码:
    例如:
    var a=1;
    function fn1(a){
    alert(a); //弹出未定义undefined
    a=2; //因为函数内部有就近的a,所以改变的是函数内部的局部变量a,函数外部的没变
    }
    fn1(); //弹出未定义undefined,因为没有参数,所以上边的参数a相当于就还是未定义
    alert(a); //弹出1
    例如:
    var a=1;
    function fn1(a){
    alert(a);
    a=2;
    }
    fn1(a); //弹出1,因为此处有参数,并且传的是第一行的全局变量a,值为1
    alert(a); //弹出1
    1)预解析:
    a=1;
    function fn1(a){
    alert(a);
    a=2;
    }
    2)逐行解读代码:
    碰到函数调用,再继续解析,读代码:
    1)预解析:此处可以解析到一个参数a,值是未定义,
    2)逐行读代码:从参数开始执行,参数a是从全局变量传来的,所以alert(1);同时a=2改变的是内部
    的局部变量(参数a)的值,所以alert(a)弹出的是全局变量1;,所以两次弹出的都是1
    50,全局变量,任何函数都可以改变它,因为在函数内部找不到,所以通过作用域链,有里向外查找到全局变
    量,对其修改,
    51,外部的变量对应外部,找不到内部的东西,
    52,从外部获取函数内部的变量,1)可以通过全局变量来获取:
    var str='';
    function fn1(){
    var a='哈哈哈';
    str=a;
    }
    alert(str);
    2)function fn2(){
    var a='钻石';
    fn3(a);
    }
    function fn3(b){
    alert(b);
    }
    53,并非所有的大括号都是作用域,只有函数的大括号才是作用域,if,for,dowhile等的括号不是作用域,
    可以接受解析,但因火狐浏览器不同,有不同结果,火狐不能对他们预解析,
    54,尽量不在if,for,等的循环中,进行全局变量或全局函数的定义,否则容易不被解析。
    55,for循环下有click等事件并且有函数,在函数里面不能直接用for循环里的i,因为for循环执行速度非常快
    ,例如:for(i=0;i<aBtn.length;i++)执行到函数里边时,i已经变成aBtn.length了,不存在而数组里的元素的
    下标最大是aBtn.length-1,所以会报错,未定义,所以往往需要加双重循环,而不是直接写相应操作,如:
    for(var i=0;i<aBtn.length;i++){
    aBtn.onclick=function(){
    //不能在此处直接写aBtn.style.background='yellow';
    for(var i=0;i<aBtn.length;i++){
    //此处有无var进行声明,也有影响,若没有就向外查找,有则是undefine,否则是3
    aBtn.style.background='yellow';
    }
    }
    }

    56,运算符 :
    取模%:有时在播放5张图片时,会用到 var i=0;i++;if(i ===5 ){ i=0;},播放完再回到第一张,此时可以
    利用取模运算符,将if语句块替换成i%=5,或者是i=i%5;这样也可以依次轮流播放5张图片;
    57,在平铺颜色时,可以利用取模运算来使有限几个的颜色,重复显示,
    var aLi=document.getElementsByTagName("li");
    var arr=['red','yellow','blue'];
    for(var i=0;i<aLi.length;i++){
    aLi[i].style.background=arr[i%arr.length];
    }
    58,利用取模运算符,实现鼠标移入,移开时的颜色变化:
    for(var i=0;i<aLi.length;i++){
    aLi[i].index=i; //注意要想在下面的函数内部使用i,不能直接使用,而是要添加索引,
    aLi[i].style.background=arr[i%arr.length];
    aLi[i].onmouseover=function(){
    this.style.background='gray';

    1. }

    aLi[i].onmouseout=function(){
    this.style.background=arr[this.index%arr.length];
    }
    58,可以利用暂存的方法来更改颜色值:
    var str='';//先声明一个空值变量,用于以后暂存颜色值
    for(var i=0;i<aLi.length;i++){
    aLi[i].index=i; //注意要想在下面的函数内部使用i,不能直接使用,而是要添加索引,
    aLi[i].style.background=arr[i%arr.length];
    aLi[i].onmouseover=function(){
    str=this.style.background;//暂存颜色值
    this.style.background='gray';
    }
    aLi[i].onmouseout=function(){
    //this.style.background=arr[this.index%arr.length];
    this.style.background=str;
    }
    60,checkbox的写法:
    <input type='checkbox' checked/>//checked是默认代表选中的,
    61,js控制checkbox的选中和取消:
    var aInp=document.getElementsByTagName('input');
    aInp[[0].onclick=function(){
    for(var i=1;i<aInp.length;i++){
    if(aInp[i].checked){
    aInp[i].checked=false;
    }else{
    aInp[i].checked=true;
    }
    //上面的if语句块,可以用下面的一句布尔值来替换
    aInp[i].checked=!aInp[i].checked;//若是真则变为假,若是假则变为真
    }
    }
    61,流程控制:
    1)if(){}else if(){}else{}语句有时可以通过switch语句来替换;
    2)简单的if()else()语句可以利用三元运算符来替换,?:
    3)while循环有时等同于for循环;
    4)break:跳出循环;
    continue:跳过本次循环,继续下次循环,
    for(var i=0;i<6;i++){
    if(i==4){
    //break; //跳出
    continue; //跳过
    }
    alert(i);
    }
    62,真假问题:数据类型,数字(NaN),字符串,布尔,函数,对象(元素,数组[],null,json{},)
    真:所有数字除0之外的数字都是真的即非0 的数字,非空字符串(空格),true,函数,能找到的元素,数组
    [],json{},
    假:0, NaN,空字符串,false,不能找到的元素,null,未定义
    63,函数返回值return详解:
    所有函数的默认返回值都是未定义,不加return或是return后没有东西,都是未定义,
    return 后的东西就是数据类型:数字,字符串,布尔,函数,对象,,未定义,
    return后的值就等于函数名称+()
    functon fn(){
    return ‘hhh’; }
    hhh=fn();//return后的值就等于函数名称+();
    alert( typeof(fn()) ); //弹出的就是string
    return 一个函数:
    function fn2(){
    return function(){
    alert(1);
    }
    }
    alert(fn2());//注意此处会弹出function(){alert(1);},不是1,
    要想弹出1:fn2()();//fn2()是匿名函数的名称,再加个括号才是调用
    若利用函数传参:
    function fn2(a){
    return function(b){
    alert(a+b);
    }
    }
    fn(20)(10);//弹出30
    function fn3(){
    return window;
    }
    fn3.onload=function(){ document.body.innerHTML=123;}
    65,return和函数结合,获取元素ID:
    window.onload=function(){
    getId('btn1').onclick=function(){
    alert( getId('div1').innerHTML);
    }
    }
    function getId( id ){
    return document.getElementById( id );
    }
    66,return和数组结合使用:
    alert( fn1(5) );
    alert( fn1(7) );
    function fn1(n){
    var arr=[];
    for(var i=1;i<=n;i++){
    arr.push(i);
    }
    return arr;
    }
    67,arguments实参集合与局部变量,局部参数,作用域:
    实参:实际传递的参数,
    形参:形式上,代表实际参数的参数
    arguments:实参的集合,ByTagName也是集合,
    当函数的参数个数无法确定时,用arguments参数集合;
    alert(sum(1,2,3));
    alert(sum(1,2,3,4));
    function sum(){//函数参数个数不确定,
    var n=0;
    for (var i = 0; i < arguments.length; i++) {
    n+=arguments[i];
    }
    return n;//注意返回值别忘写
    }
    var a=1;
    function fn2( a ){ //此处的a和arguments[0],alert( a)中的a等同,;
    arguments[0]=3; //此处arguments集合对其进行改写为3,其既可以读也可以写
    alert( a); //弹出3
    var a=2;
    alert( arguments[0] ); //弹出2
    }
    fn2(a);
    alert(a); //弹出1
    css样式表里的样式和行间样式(元素标签内部写的style样式),两者相比之下,获取时获取到的是行间样式。
    68,currentStyle与ComputedStyle
    getComputedStyle().width函数获得的是计算机(浏览器)计算之后的样式; //IE6,7,8低版本不支持
    currentStyle.width 也可以得到样式但是也有兼容性问题 //标准浏览器不兼容
    68,不要通过以上两个方法去获取未设置的样式
    69,复合样式:如background:url(),red.......属性值有多种的,就是复合样式
    使用getStyle函数获取该类复合样式时,注意要转换为单一样式的写法,如:backgroundColor,也不要写成
    background-color,js不喜欢这种。
    function $(v){
    if (typeof(v)=== 'function') {
    window.onload=v;
    }else if (typeof(v)==='string') {
    return document.getElementById(v);
    }
    }
    $(function(){
    $('btn1').onclick=function(){
    alert(getStyle($('div1'),'backgroundColor'));
    //注意此处的实参的写法,带引号,注意引号和属性之间不能有空格
    //否则是undefined
    /*注意火狐4.4版本之前的,此处应该写一个参数(任意值均可),alert(getStyle
    ($('div1'),250).width);可以为任意值,可以不是250*/
    }
    })

    function getStyle(obj,attr){
    if (obj.currentStyle) {
    return obj.currentStyle[attr];
    }else{
    return getComputedStyle(obj)[attr];
    }
    }
    68,定时器基础:
    for(var i=0;i<3;i++){}//瞬间完成,没有时间根据,
    定时器:
    var timer=setInterval(函数,毫秒);
    clearInterval(timer);//清除定时器,就是让定时器停止
    setTimeout()常用于页面广告,打开页面后过几秒后弹出广告
    var timer1=setTimeout(函数,毫秒),只执行一次的,
    clearTimeout(timer1);
    例:
    <style>
    img{display:none;}
    </style>
    window.onload=function(){
    var miaov=document.getElementById('miaov');


    setTimeOut(function(){
    miaov.style.display='inline-block';//注意图片的显示方式是inline-block;
    setTimeOut(function(){
    miaov.style.display='none';
    },3000); //广告图片展示3秒后消失
    },2000);//页面打开2秒后弹出广告图片
    }
    <body>
    <img id='miaov' src='img/miaov.jpg'/>
    </body>
    两种定时器可以互换,只要将setInterval设置开关,就可以控制实现setTimeout的功能。
    setInterval(fn,1000);//注意setInterval中的函数fn后边不加括号,否则就和直接调用没区别了
    函数调用:
    1)fn(); //直接调用
    2)document.onclick=fn; //事件调用
    例:
    var i=0;
    var timer=null; //注意先声明一个变量,为空
    function fn(){
    i++;
    document.title=i;
    //i++,注意顺序,顺序不同,结果不同
    if (i===3) {
    clearInterval(timer);
    }
    }
    timer=setInterval(fn,1000);// 调用定时器,此时调用函数,
    70,使用定时器时,注意,1)有时若连续触发定时器事件后,容易产生定时器乱套或重复点击速度加快的的
    情况,即事件发生的时间频率变的越来越短,解决办法是,在事件发生的开头就先利用clearInterval清除一次
    定时器,
    2)初次之外,有时到达位置后再点击还会运动,是因为定时器所在位置附近还有别的语句,则连续点击定时
    器时,虽然定时器清空看,但别的语句还会执行,此时可以利用if{}else{}语句,将定时器和其他语句分别封装
    起来,分开执行。
    3)有时当速度设置成等于某些值时,不会停止,此时可将速度设置成大于等于某些值即可
    运动框架:
    1)在开始运动前,关闭已有定时器
    2)把运动和停止隔开(if {}else{}语句)
    var arrUrl=[‘1.jpg’,‘2.jpg’,‘3.jpg’,‘4.jpg’];
    var timer=null;
    var num=0;
    var oBody=document.body;
    aBtn[0].onclick=function(){
    clearInterval(timer);
    //注意此处先清除定时器,若没有这句,狂点按钮后会造成图片快速变化的乱套情况
    timer=setInterval(function(){
    oBody.style.background='url('arrUrl[num]+')';
    num++;
    num%=arrUrl.length; //可以使图片重复循环
    },1000);
    }
    注意:如果定时器是由用户控制的,要先关后开,即如上面的例子先清除,再开始
    70,注意利用数组,存放图片;
    72,使用定时器循环显示图片时可能会和鼠标移入事件冲突:此时利用清除定时器操作,
    并且注意是在整个页面上使用定时器:若oDiv代表页面,则
    oDiv.onmouseover=function(){clearInterval(timer);}
    鼠标离开时,再继续定时器的循环操作,可以将定时器的操作封装成一个函数如function autoPlay()={},
    省的再重复编写调用定时器函数,如oDiv.onmouseout=autoPlay;
    71, 事件调用时,函数不加括号:
    function autoPlay(){}
    72,QQ面板及旁边的title,并列div:
    使用定时器,定时显示和隐藏即可,
    也可以应用到淘宝,天猫等网站上方的导航处,鼠标移入时下方出现并列的介绍细节的div
    如:oDiv.onmouseout=autoPlay; //函数名称+括号=返回值,若没定义返回值,就是undefine,
    73,变量放到外面的问题:
    写函数时,外边尽量不放变量,如定时器,通常会在外面设置timer为null,有时可以将其甚至为某个元素的属
    性,如oDiv.timer=null;清除时,清除的就是div身上的属性,clearInterval(oDiv.timer)
    74,函数封装的传参,判断:
    当有相同部分代码出现时,可以将其封装成函数,找到不同的点,将其进行传参或判断处理,数字是可以作为
    传递的参数,但是符号则不可以,
    75,两个相同执行语句的if语句可以进行合并,如下:
    if(speed>target && dir >0){
    speed=targe;
    }
    if(speed<target && dir <0){
    speed=targe;
    }
    可以合并成:
    if(speed>target && dir >0 || speed<target && dir <0){
    speed=targe;
    }
    76,判断方向时:
    如果当前位置大小小于目标点位置,则移动的方向应该是正方向,否则就是负方向。
    77,回调函数:
    调用函数时,当所有都执行完后,再让它做别的动作,就是回调函数,将回调函数写在参数位置处。
    78,当某个函数,存在的时候就执行,不存在就不执行,的写法:
    if(endFn){endFn();}
    或者:endFn&&endFn();
    79,点击页面上任意位置的对象是document:document.onclick=........
    80,函数内部的this指的是window,若让其指向指定对象 ,需要对其进行传递,var _this=this;
    81,控制台语句:(可用于调试js代码)
    1)console.log('控制台输出信息'); //并非弹出,而是在控制台输出信息;
    alert();会阻止后面的运行,还要点确定
    2)console.warn('警告信息提示');
    3)console.error('错误信息提示'); //try catch 语句可用利用到
    4)分组调试:console.group(‘第一组’);//双引号内为分组的名字
    console.log(123456);
    console.groupEnd();//分组有开始,也有结束
    例如:
    <script>
    console.group(‘第一组’);//双引号内为分组的名字
    console.log(123456);
    console.groupEnd();//分组有开始,也有结束
    </script>
    5)console.dir(名称);//显示该对象的所有信息,
    console.log(名称);//可能会有一部分信息显示不出来
    6)console.dirxml(oDiv);//显示oDiv当前元素的包含的所有结构内容
    7)断言:
    console.assert(a);//若a的值为真,则表示断言成功,若a的值为假,表示断言失败,会显示失败
    8)查看函数执行过程,console.trace()
    例如:
    function a(){
    return b();
    }
    function b() {
    return c();
    }
    function c(){
    console.trace();
    return 1;
    }
    a();
    9)计算执行时间console.time('')
    console.time('计时器')//注意括号内必须写标题
    console.timeEnd('计时器')//有开始有结束
    例如:
    console.time('计时器')
    for(var i=0;i<1000000;i++){}
    console.timeEnd('计时器')
    10)显示概况,console.profit(); 作用和FireBug里的概况是相同的,显示也相同
    例如:
    console.profile();
    for(){}//代码
    console.profileEnd();
    11)在其他浏览器下(如IE,等)也可以使用FireBug,不过应该是FireBug-Lite.,可以在线引用,将其网址
    复制到script代码中,也可以将其下载下来,
    <script type="text/javascript" src="https://getfirebug.com/firebug-lite.js"></script>
    80,offsetLeft:就是该元素当前所处的位置,
    81,让一个物体从左到右跑,就是不断加大它的left值,首先将定位,设置为绝对定位,
    82,当想要获取一个图片的透明度时,没有特定的属性可以利用,不像left,top,width等可用offsetLeft,
    offsetWidth,没有offsetOpacity和offsetAlpha,此时可以先在style样式里将其透明度设置成一个值,然后再
    声明一个变量,值为和style样式里相同的透明度值,对这个变量进行操作
    83,“分享到”侧边栏,原理:通过目标点计算速度值,offsetLeft和target比较,得到speed的正负
    83,缓冲运动:
    逐渐变慢,越接近终点,速度越小,
    var speed=(target-oDiv.offsetLeft)/8;
    target-oDiv.offsetLeft,表示目标点到当前位置的距离,除以8之前速度的大小就是距离这么长,除以8后有了
    缓冲的效果,速度由大变小,
    缓冲运动时,有时物体到达的位置不是正好的所要求的像素值,利用取整方法
    if(speed >0){
    speed=Math.ceil(speed);
    }else { speed = Math.floor(speed);}
    或者是三目写法:
    speed=speed>0?Math.ceil(speed):Math.floor(speed);
    83,任何的if else 语句都可以写成三目运算的写法
    84,向上取整,向下取整:Math.ceil(),Math.floor();
    Math.ceil(0.00001);//结果是1
    Math.floor(0.999999);//结果是0
    Math.ceil(-12.5);//结果是-12
    84,小数的问题:如在透明度变换的定时器中,会由于反复执行定时器而产生透明度闪烁的问题,原因就是透
    明度是小数的问题,计算机,手机,服务器等内存是有限的,不能真正的存储小数,模拟地存储小数。
    编程时,尽量避免写小数。
    如:iOpacity=parseFloat(getStyle(obj,attr)*100);//这样写会产生闪烁情况,因为透明度的值是小数,只要
    将其转换成整数即可,如下:
    iOpacity=parseInt(parseFloat(getStyle(obj,attr)*100));
    85,运动框架:
    window.onload=function(){
    var oDiv=document.getElementById('div1');

    oDiv.onmouseover=function(){
    over(300);
    }
    oDiv.onmouseout=function(){
    over(100);
    }

    }
    var timer=null;
    function over(target){
    var oDiv=document.getElementById('div1');
    clearInterval(timer);
    timer=setInterval(function(){
    var speed=(target-oDiv.offsetWidth)/8;
    speed=speed>0?Math.ceil(speed):Math.floor(speed);
    //利用取整函数是为了达到缓冲运动的效果
    if (oDiv.offsetWidth==target) {

    clearInterval(timer);
    }else{
    oDiv.style.width=oDiv.offsetWidth+speed+'px';
    //注意此处是odiv.style.width
    };
    },30);
    }
    86,多物体及任意值(包含透明度opacity)运动框架:
    <script type="text/javascript">
    window.onload=function(){
    var aDiv=document.getElementsByTagName('div');

    //aDiv[i].timer=null;//在每个div身上都加一个定时器
    aDiv[0].onmouseover=function(){
    move(this,'width',300);
    //此处添加参数表明是哪个div运动
    }
    aDiv[1].onmouseover=function(){
    move(this,'height',200);
    }
    aDiv[2].onmouseover=function(){
    move(this,'font-size',100);
    }
    aDiv[0].onmouseout=function(){
    move(this,'width',100);//恢复到原来
    }
    aDiv[1].onmouseout=function(){
    move(this,'height',50);//恢复到原来
    }
    aDiv[2].onmouseout=function(){
    move(this,'font-size',20);//恢复到原来
    }

    }
    //var timer=null;为了解决多个物体同时运动时出现定时器卡的问题,在每个div身上都加一个定时
    器,在上面添加一个aDiv[i].timer=null;
    function getStyle(obj,attr){
    if (obj.currentStlye) {
    return obj.currentStlye[attr];
    }else{
    return getComputedStyle(obj,false)[attr];
    }
    }
    function move(obj,attr,target){
    clearInterval(obj.timer);
    obj.timer=setInterval(function(){
    //注意对速度的声明赋值等操作要在定时器函数里面,否则缓冲效果不会实现
    var iCur=0;
    if (attr == 'opacity') {
    iCur=parseInt(parseFloat(getStyle(obj,attr))*100);
    }else{
    iCur = parseInt(getStyle(obj,attr));
    }
    var speed=(target-iCur)/8;
    speed=speed>0?Math.ceil(speed):Math.floor(speed);
    if (iCur==target) {//注意此处
    clearInterval(obj.timer);
    }else{
    if (attr =='opacity') {
    obj.style.opacity=(iCur+speed)/100;
    }else{
    obj.style[attr]=iCur+speed+'px';
    }
    //注意此处是obj.style[attr]
    }
    },30);

    }
    </script>
    87,多个物体淡入淡出:
    window.onload=function(){
    var aDiv=document.getElementsByTagName('div');
    var i = 0;
    for (i = 0; i < aDiv.length; i++) {
    //var aDiv.timer=null;
    aDiv[i].alpha=30;//将透明度绑定为物体的属性
    aDiv[i].onmouseover=function(){
    move(this,100);
    }
    aDiv[i].onmouseout=function(){
    move(this,30);
    }
    };

    //var alpha=30;定时器可以单独定义,透明度alpha也可以,所以此处的透明度定义省
    略,放在for循环里定义
    function move(obj,target){
    clearInterval(obj.timer);
    obj.timer=setInterval(function(){
    var speed=(target-obj.alpha)/8;
    speed=speed>0?Math.ceil(speed):Math.floor(speed);
    //缓冲运动
    if (obj.alpha==target) {
    clearInterval(obj.timer);
    }else{
    obj.alpha+=speed;
    //obj.style.filter='alpha(opacity:'+alpha')';
    obj.style.opacity=obj.alpha/100;
    }
    },30);
    }
    }
    88,多个对象同时执行一个鼠标移入移出事件:
    oBtnPrev.onmouseover=oMarkLeft.onmouseover=function(){..............};
    oBtnPrev.onmouseout=oMarkLeft.onmouseout=function(){..............};
    89,封装getByClass(oParent,sClass)函数:该函数可通过父元素来获取子元素,
    function getByClass(oParent,sClass){
    var aEle=document.getElementByTagName('*');
    var i=0;
    var aResult=[];
    for(i=0;i<aEle.length;i++){
    if(aEle[i].className==sClass){
    aResult.push(aEle[i]);
    }
    }
    return aResult;
    }
    如:var oSmallUl=getByClass(oDiv,'small_pic')[0];//第0个是因为只有一个
    89,调试程序时,如果程序没反应,甚至页面都没反应,
    1)先看事件加没加上去,利用alert()进行调试,若有反应,则可能是元素选错了
    2)将相应元素加个边框
    90,制作透明度可以变化的选项卡时:
    例如:在执行鼠标点击事件时,只有当前的图片显示,其他图片模糊,则可以这样操作透明度:
    aImg[i].onclick=function(){
    for(var i=0;i<aImg[i].length;i++){
    startMove(aImg[i],'opacity',60); //其他图片模糊
    }
    startMove(this,'opacity',100); //当前的图片显示
    }
    91,图片进行切换(下拉切换)时,注意层级关系,否则其他图片都会被第一张图片(层级最高)挡住,通过改变
    索引值来改变解决层级问题:
    aBigLi[this.index].style.zIndex=iMinZindex++;//aBigLi是当前小图片对应的大图片,iMinZindex是开始图片
    的索引值
    aBigLi[this.index].style.height=0;//先将其高度定义为0,然后才能利用定时器有下拉的动作;
    startMove(aBigLi[this.index],'height',oBigUl.offsetHeight);//另其下拉到oBigUl.offsetHeight的高度;
    92,当重复执行某个动作时,不想让它重复执行事件,可利用return;
    如:if(this.index==iNow)return;//直接return就行,不用加别的;
    93,链式运动框架(一环扣一环):
    <script type="text/javascript">
    window.onload=function(){
    var oDiv=document.getElementsByTagName('div')[0];
    oDiv.onmouseover=function(){
    move(oDiv,'width',200,function(){
    move(oDiv,'height',200,function(){
    move(oDiv,'opacity',100);
    });
    });
    }
    oDiv.onmouseout=function(){
    move(oDiv,'opacity',30,function(){
    move(oDiv,'height',100,function(){
    move(oDiv,'width',100);
    });
    });
    }
    }
    function getStyle(obj,attr){
    if (obj.currentStyle) {
    return obj.currentStyle[attr];
    }else{
    return getComputedStyle(obj,false)[attr];
    }
    }
    function move(obj,attr,target,fn){
    clearInterval(obj.timer);
    obj.timer = setInterval(function(){
    var iCur=0;
    if (attr == 'opacity') {
    iCur=parseInt(parseFloat(getStyle(obj,attr))*100);
    }else{
    iCur = parseInt(getStyle(obj,attr));
    }
    var speed = (target-iCur)/8
    speed = speed>0?Math.ceil(speed):Math.floor(speed);
    if (iCur == target) {
    clearInterval(obj.timer);
    fn&&fn();//注意位置,要放在这里
    }
    else{
    if (attr =='opacity') {
    obj.style.opacity=(iCur+speed)/100;
    }else{
    obj.style[attr]=iCur+speed+'px';
    }
    }

    },30);
    }
    </script>

     93,数组循环方法:

    1)普通的循环方法:

    var i=0;

    for(i=0;i<arr.length;i++){。。。。。。}

    2)利用  in

    for(i in arr){。。。。。。。}

  • 相关阅读:
    AngularJS $http模块POST请求
    thinkphp整合系列之融云即时通讯在线聊天
    Linux 常用命令
    Linux Shell脚本编写规范、例子
    Linux crontab定时执行任务 命令格式与详细例子
    Linux目录详细说明大全, 方便你以后合理规划及管理
    Linux 操作MySQL常用命令行
    SVN服务器搭建和使用(三)
    Linux下的SVN服务器搭建
    python 根据染色体起始终止点坐标来获取碱基序列
  • 原文地址:https://www.cnblogs.com/RitaLee/p/5561222.html
Copyright © 2020-2023  润新知