【JS】 Javascript 入门

时间:2023-03-08 17:20:26
【JS】 Javascript 入门

javascript

**********本章大量示例和内容引用自w3cschool的javascript教程**************

本来已经快写完90%左右了,结果不小心跑了个js,不小心把浏览器弄死,不小心没保存草稿T-T一切都要从头开始写过了orz。好吧再写一遍!

■  概述

  js是一种轻量级的浏览器脚本语言,其兼容性很好(几乎可以用在所有的浏览器上)这也就意味着从PC到智能手机所有可以用浏览器的设备都可以运行js脚本了。所以说js是互联网上最受欢迎&最常用的脚本语言不为过。
  js被互联网所青睐的原因在于它可以嵌入html文件中,并且可以和html中的各种元素进行互动。在html文件的<head>或者<body>中,可以加入<script>标签,而<script></script>里面就可以写js脚本的内容了。如果想引用外部脚本的话可以在script中加上src属性指向一个外部脚本,这样<script>里面就不用写任何内容直接</script>就好了
  由于js没有一个专门的编译器或者集成较好的IDE之类的工具,测试js略显麻烦一点,在下面的大部分实例中,为了看到js的效果我们暂时会用document.write(...)这个js里的方法,它牵扯到HTML
DOM,意思是网一个网页上写html代码,暂时把它当成是其他语言里的print语句,用来打印出结果就好了。

■  基本语法

●  注释

  js和其他语言一样可以注释,其注释的形式和C或者java很像。注释内容用/*comment*/的形式表现,另外也可以用//comment的形式来进行一整行的注释

●  语句规则

  浏览器等软件会对js语句进行解释。js是一种解释型语言,解释器对语句逐条进行解释而不是事先编译再运行。

  js的语句后面可以加上分号。但是这不是语法要求而是很多程序员的习惯(像我这种写惯了python的话就经常不加分号。。)。

  当然不用多说,js的语句是对大小写敏感的,不像sql一样大小写一样。

  此外和C以及java一样,js用大括号来括起一些语句组成一个代码块。在函数,循环,条件语句中就要用到这些代码块了。

  和python一样js可以用"\"进行代码的折行,即用这个符号跟在一行最后面,解释时下一行代码会紧跟着这一行进行解释。

  在js的语句中,多余的空格都不会被解释,和python一样。所以在书写的时候可以适当地加入些空格来美化代码,比如var = 1和var=1效果是一样的。

●  变量赋值和初始化

  js中有各种内建的数据类型,包括Number(包括传统意义上的int型,float型等),Boolean(true和false),String(双引号或单引号都可以表示字符串), Null(空值),Array(数组),Object(对象)

  变量声明时用var关键字,声明时不必特地指出变量的类型,当声明却不赋值时(如var x)默认变量的值为undefined,即变量没有值(注意undefined和null的区别,undefined是说变量根本就没有赋过值,而null说的是变量的值是空值)。js支持在一行里声明多个变量并赋值:

var city = "北京";
var count = 100
var name
var firstname = "Frank", lastname = "Takanashi"

  对于Array和Object这两种类型稍微有点不同。

  Array是类似于python的list,有下列几种初始化的方法:

var cars=new Array("Audi","BMW","Volvo");

var cars=new Array();
cars[0]="Audi";
cars[1]="BMW";
cars[2]="Volvo"; var cars=["Audi","BMW","Volvo"];

  而Object类似于python的dict,可以如下初始化:

  *可以看到,object的key不用打引号,这点和python是不一样的。另外访问属性时可以采用obj['key']和obj.key两种形式,注意引号用法

var person={firstname:"Bill", lastname:"Gates", id:5566};

/*初始化时可以换行,让格式更清晰*/
var person={
firstname : "Bill",
lastname : "Gates",
id : 5566
};

   *关于JSON和JS对象:

  其实JSON全称就是javascript object notation,表名JSON格式和JS是有千丝万缕的联系的。在JS中可以调用JSON.parse('xxx')或者eval('('+'xxx'+')')来把一个JSON字符串转化为一个JS对象,而一个对象则可以调用obj.toString()之类的办法转化为JSON格式字符串。

  如果想要清空变量的值,可以把null赋值给变量。再次强调,null值和undefined不一样,null是空值,而undefined是没有值。

  声明变量时如果不想赋值可以用new关键字+类型名字:

var carname=new String;
var x= new Number;
var y= new Boolean;
var cars= new Array;
var person= new Object;

  这样声明出来的变量其值是null

  * 赋值过程的深浅拷贝

  和Python中一样,Javascript中直接进行赋值的时候会涉及到深浅拷贝的问题。在讨论Javascript的时候,其实可以认为浅复制就是赋值,而深复制是深复制,这一点和Python是不太一样的(Python中明确浅复制和赋值之间的区别)。

  比如令d = {'a': 1},如果令 b = d,那么在通过d.a = 2对数据做出修改后b.a也会变成2。

  但是如果令 c = JSON.parse(JSON.stringify(d)) 的话,那么做出同样的修改并不会影响源数据,因为通过JSON序列化再反序列化的过程是一个深复制的过程。

●  对象的方法和属性

  这个对象是广义上的对象,在js里面,和python一样,一切皆对象,然后对象有方法和属性可供调用。调用方式是用符号"."。我们可以自定义对象,js中也有很多内建的对象。总而言之,对象有点像一个类,但是js中没有类这个概念,所以我们用对象来指代这么一种实体。下文中有些时候我可能会说类怎么样怎么样,那其实是在说对象的事情。更多内建对象的详细方法和属性也会在下面讲到。

  关于this:this是JS中常用的一个关键字,其指代一个对象,具体什么对象要看具体情况。比如

  1.一般情况下函数中的this指向调用这个函数的对象

  2.当函数没有所属对象的时候this指向顶层的全局对象

  3.当函数是一个构造器时,this指向将被构造出来的新对象

  ……

●  函数

  js中可以定义函数

function funcName(para1,para2){
//some code
}

  定义函数时不必特地指出返回值的类型,函数中用return语句来规定函数的返回值。

  js可以在函数中声明变量,在函数中声明的变量当然是个函数内部的局部变量。在函数外声明的一般就是全局变量了

  * 在声明变量时,前面不加var关键字也可以声明,这么声明的变量默认是个全局变量,整个文件都可以访问它。

  js中支持匿名函数的设置,也就是说上面格式中的funcName不是必须的。可以直接function(){...}。就像python中的lambda一样,匿名函数只能用一次,可以作为一种临时性整合语句块的手段

  

●  运算符

  js中大多数运算符都和我们所知道的经典编程中的运算符是一致的,下面我把一些我不太熟悉,看到之后觉得是js中比较特殊的运算符相关的东西写一下:

  等性运算:

    js中的"=="不是经典意义上的等于。js中用==会把比较的两个对象做一个自动的类型转换,比如5 == "5"在js中是true因为它会把Number类型的5转化成String类型的"5"再和右边比较,自然对比出的结果是真。另一方面,如果不想让它自动转换类型,可以用"===",三个等号在js中指完全相等。

  加减运算:

    和上面等性中提到的类似,js中会把和字符串相加的类型自动转化成字符串再来相加,比如5 + "5"不会报错而得到结果"55",5 + 5得到10。

  条件运算:

    js中支持类似于(condition)?value1:value2这样的三元条件运算。

  逻辑运算:

    js中的逻辑运算用的是经典的&& ; || ; !而不是and ; or ; not

■  常用语句

●  if/else语句

if (条件 1)
{
当条件 1 为 true 时执行的代码
}
else if (条件 2)
{
当条件 2 为 true 时执行的代码
}
else
{
当条件 1 和 条件 2 都不为 true 时执行的代码
}

●  switch语句

switch(n)
{
case 1:
执行代码块 1
break;
case 2:
执行代码块 2
break;
default:
n 与 case 1 和 case 2 不同时执行的代码
}

●  for循环

  js中可以用两种形式的for循环,第一种是比较经典的java和C里面那样的三条件语句的for循环:

for (var i=0; i<5; i++)
{
x=x + "The number is " + i + "<br>";
}

  可以看到在第一个条件语句里面我们可以进行变量的声明,声明出的变量可以用于这个循环当中

  第二种形式是像python中的for/in循环。但是需要注意的是,js中的for/in循环和python中的for/in循环是有很大区别的。也别忘了js中的for/in是有个小括号的。

  当for/in遍历一个Object(类似dict)的时候,和python中类似,key是代表了Object中各个key的内容:

var person={fname:"John",lname:"Doe",age:25};

for (key in person)
{
txt=txt + person[key];
}

  当用for/in遍历一个Array的时候就不一样了:

var list = ["a","b","c"]

for (index in list){
document.write(list[index])
}

  这里for/in中写的index不是list中各个成员的内容"a","b"和"c",而是指代这个list的index 0,1和2。换句话说,js中for/in处理一个数组的时候,实际上是先获取数组的长度,然后把这个长度从0到最后一次次赋给index,用这样的一个index进入循环执行的语句。所以在访问list中各个成员的时候,我们不是直接用index而是用list[index]

●  while循环

  js中有while循环和do/while循环两种:

while (条件)
{
需要执行的代码
}

  do/while循环的执行体一定被执行一遍:

do
{
需要执行的代码
}
while (条件);

  

  以上两种,for循环和while循环都可以再循环体中用break语句跳出循环,continue语句跳过循环

●  异常处理

  js中可以进行异常处理如:

try
{
//在这里运行代码
}
catch(err)
{
//在这里处理错误
}

  在合适的地方,可以用throw语句来抛出异常:

throw "some exception message"

■  对象的说明&内建对象

  正如上面所说,对象是一个类似于别的语言中的类的一个存在。因为js中一切皆对象,包括函数和各种复杂的数据结构,所以构造一个对象时可以像下面这个函数一样。这个函数也被称为一个对象构造器(有点像一个类的构造方法)

function person(firstname,lastname,age,eyecolor)
{
this.firstname=firstname;
this.lastname=lastname;
this.age=age;
this.eyecolor=eyecolor; function changeName(name)
{
this.lastname=name;
}
this.changeName=changeName;
}

●  全局对象&属性

  全局属性和函数可用于所有内建的 JavaScript 对象。常用的有:

    escape(...)  对字符串进行编码,这样就可以在所有的计算机上读取该字符串。比如Visit W3School!被escape之后变成Visit%20W3School%21(这种编码格式我还不是很懂。。这是什么用的编码额)

    unescape(..)  escape的反操作。

    eval(string)  和python的eval函数一样,将一些javascript字符串解析并执行

    isNaN(...)  检查某个对象是否是数字

    parseInt(...)  把一个字符串解析成一个整数对象

    parseFloat(...)  把一个字符串解析成浮点数对象

    Number(...)  把对象的值转换为数字

  下面详细说明一下各个内建类型对象的属性和方法。直属于该种类型方法或属性,其调用方法是类型名.属性或方法名,下面说明中前缀是其类型名字(事实上也是实际调用时候的写法)。如果是这种类型对象的一个实例的属性或方法的话,就用类型对象首字母小写来代表一个实例

●  Number类型对象

  属性:

    Number.MAX_VALUE  js所能表示的最大数,大约是1.7976931348623157 x 10308

    Numebr.MIN_VALUE  js所能表示的最小数

    Number.NaN  表示一个非数字对象,在调用Number(...)初始化一个对象的时候如果失败了就会返回这个值

    Number.NEGATIVE_INFINITY  负无穷大,溢出时会返回此值

    Numebr.POSITIVE_INFINITY  正无穷大,溢出时返回此值

  方法:

    n.toString(r)  返回数字以r进制表示的字符串,比如2.toString(2)是10

    n.toFixed(p)  返回数字的字符串,取小数点后p位

    n.valueOf()  返回数字值

●  String类型对象  http://www.w3school.com.cn/jsref/jsref_obj_string.asp

  属性:

    s.length  返回字符串的长度

  方法:(String类的方法较多,可以参见上面的网址,下面列出几个常用的)

    s.indexOf(...)  检索字符串,返回找到第一个字串的位置,没找到返回-1

    s.split(sep)  以sep为分隔符分割字符串,返回得到的数组。和python的split不同的是sep是必须的,而且当sep写""的时候不会报错,而是把字符串所有字符都分割开

    s.match(pattern)  检索字符串,支持正则表达式pattern。返回的不是索引而是匹配到的内容,另外pattern也可以是个RegExp对象。同时match的行为和pattern的具体形式(比如带不带g属性)有关,下面的RegExp对象中会详细说到。*当写正则表达式的时候不能加引号,比如match("/\d/g")是不会按照你的预期匹配数字的,而应该写match(/\d/g),而匹配子字符串的时候要加引号,如match("123")。

    s.search(pattern)  search方法专门用来做正则匹配,而且忽略属性g,不管你有多少个匹配项我只返回发现的第一个。并且返回的是索引不是内容。

    s.replace(pattern,replacement)  替换指定的子字符串或者正则式匹配到的内容。

    此外,因为js要和浏览器界面互动,所以String类还有一大票修饰输出字符串的方法比如bold(),italics(),strike()(删除线输出),toLowerCase(),toUpperCase(),link()(超链接样式输出),fontSize(size),fontColor(color)等等。

●  Date类型对象  http://www.w3school.com.cn/jsref/jsref_obj_date.asp

  Date类型的属性全部都封装在对象里面不允许直接调用,可以通过调用相关的方法来获取和设置属性。很多方法都是顾名思义的,不详述

  另外,Date类的属性是可以直接和数字相加减的。比如one_year_later = d.getDate() + 365,然后再one_year_later.getDate()的话得到的就是一年(365天)后的那一天同一时刻的Date对象了(有点像python的datetime模块里的datetime类可以比大小,可以相减得到timedelta类型)

  方法:

    Date()  (不需要前缀加类名或实例)返回当前的Date对象

    d.toString()  返回时间字符串,格式如Fri Apr 07 2017 17:18:47 GMT+0800

    d.getTime()  返回时间戳(毫秒为单位)

    d.getDate()  返回日期 1~31

    d.getMonth()  0~11

    d.getDay()  0~6

    d.getFullYear()  返回四位年份

    d.getHours()  0~23

    d.getMinutes()  0~59

    d.getSeconds()  0~59

    以上所有get方法都有相对应的set方法来设置一个Date类型对象的属性的值

●  Array类型对象  http://www.w3school.com.cn/jsref/jsref_obj_array.asp

  属性:

    a.length  返回数组的长度

  方法:

    a.pop()  从数组末尾删除并返回一个值

    a.push(...)  在数组末尾加上一个值(注意,不是append哦)

    a.shift()  从数组开头删除并返回一个值

    a.unshift(...)  在数组开头加上一个或多个值(以逗号隔开即可)

    a.sort()  返回一个排序好的数组(注意和python里不一样,这里是返回而不是在a本身上排序哦,reverse也是这样)

    a.join([sep])  以sep为分隔符连接起数组成员,返回连接后的字符串。当sep未指定时默认用逗号

    a.reverse()  返回一个倒序的数组

●  Math类型对象  http://www.w3school.com.cn/jsref/jsref_obj_math.asp

  之前基本上没怎么提到过Math类型,因为与其说Math是一个类型对象,不如说它是个模块或库。它的属性和方法都由类直接调用:

  属性:

    Math.PI  圆周率
    Math.SQRT2  根号2
    Math.SQRT1_2  根号1/2
    Math.LN2  2的自然对数
    Math.LN10  10的自然对数

  方法:

    Math.abs(x)  求绝对值

    Math.ceil(x)  对数字x上舍入(返回比x大的最小整数)

    Math.floor(x)  对x下舍入

    Math.Max(x,y)  返回x和y中的大者(自然Min也有)

    Math.random()  返回0~1间随机一个实数

    Math.round(x)  对x四舍五入

    Math.sqrt(x)  求x方根

    此外还有一大票的三角函数方法

●  RegExp类型对象  http://www.w3school.com.cn/jsref/jsref_obj_regexp.asp

  RegExp是Regular Expression的缩写,即正则表达式。关于正则,之前也说到过了,但是这里说的是正则表达式对象。就好比是python里re.compile返回的对象一样。

  首先关于js中的正则表达式,其基本格式是/pattern/attribute。pattern就是个和python等里面一样的正则表达式,规则譬如.(通配符){}(重复次数规定)\d(数字字符)等一样的。而后面的attribute是js中特有的一个属性,其可选项有i,g,m三种。

  i表示ignore case,即匹配的时候忽略大小写的区别

  g表示global,默认情况下,正则表达式总是只匹配到第一个就完了,但是设置属性g之后,它就会把所有的都匹配出来。具体怎么匹配请看下面具体方法的说明。

  m表示multiline,具体什么意思不知道。。

  属性:

    r.ignoreCase  判断这个正则对象是否设置了i属性,下面两个也是类似的。

    r.global

    r.multiline

    r.lastIndex  和设置g属性时匹配的方式有关,下面会讲到

  方法:

    RegExp(pattern,attribute)  正则对象的构造方法,和String.match方法不同,这里的pattern应该用引号引起来,attribute则是写"g","i"这种。

    r.test(str)  用正则对象匹配str,如果匹配到了内容就返回true,否则false

    r.compile("new pattern","new attribute")  编译正则对象,通常用于更新一个正则对象的表达式或属性

    r.exec(str)  exec方法分成两种情况,加入r对象没有设置g属性,那么exec返回一个数组array,array[0]是第一次匹配得到的内容,array[1],array[2]这些是这个内容里对应正则表达式的第一、二子模式,以此类推。如果r对象设置了g属性,那么exec会返回匹配到的内容数组(如没有设置g属性时一样),并且将r.lastIndex设置为当前匹配内容结束时的索引位置,然后下一次再调用exec的时候,就从这个lastIndex开始继续匹配,如此一直匹配到尾巴上如果没有匹配到就返回一个null并重置lastIndex为0。所以我们可以手动设置一个循环,让r.exec一口气输出所有可匹配的内容。比如:

var str = "Visit W3School, W3School is a place to study web technology.";
var patt = new RegExp("W3Sc(.*)ool","g");
var result; while ((result = patt.exec(str)) != null) {
document.write(result);
document.write("<br />");
document.write(patt.lastIndex);
document.write("<br />");
} /****结果*****
W3School,h
14
W3School,h
24
*/