【JavaScript从入门到精通】第六课 javascript基础-01

此内容来自开课吧石川微信公众号

从这节课起,我们开始学习JavaScript的一些基础知识。前面的课我们用一些示例向大家展示了JS的世界,从这节课起,将为大家补充一些JS的基础知识,以便大家在接下来的课程中可以更好地去理解。

JavaScript的组成

JavaScript主要由以下部分组成:

  • ECMAScript:解释器、翻译
  • DOM:Document Object Model(文档对象模型)
  • BOM:Browser Object Model(浏览器对象模型)

其中,ECMAScript扮演了翻译角色,将我们写好的可读性高的代码翻译成计算机能识别的二进制代码,并将计算机反馈回来的信息翻译给我们。ECMAScript是JS的核心,我们一般把它叫做解释器。

ECMAScript为JS提供了最基本的功能,但这样的功能十分有限,为了让JS具有编写网页代码的能力就要用到DOM。DOM中的Document(文档)指的其实就是HTML文档,而DOM则赋予了JS操作HTML的能力。在JS里DOM是以document的形式出现的。

BOM使得JS拥有了操作浏览器的权利,在JS里BOM以window的形式存在,有了BOM,JS就具备了例如弹窗,关闭窗口,复制到剪切板等与浏览器相关的功能。

在兼容性问题上,ECMAScript(简称ECMA)几乎没有兼容性问题,DOM存在一些操作上的不兼容,而BOM没有兼容问题(完全不兼容),因此我们尽量避免使用BOM。

变量类型

前面我们已经讲过变量,而在JS里变量分为了不同的类型。

var a = 12;
var a = 'asdfasd';
var a = true;
var a = function (){
  alert('abca');
}
var a = document;
alert(typeof a);

通过typeof可以返回变量类型,从上到下,输出的结果依次为:number(数值),string(字符串),boolean(布尔),function(函数),object(对象)。 除了这5种基本的类型,JS还存在一种叫undefined的类型,一般存在于如下两种情况:

alert(typeof b);

变量b没有进行过定义,所以JS返回的数值类型为undefined(未定义的)。

var b;
alert(typeof b);

这种情况下,虽然我们定义了变量b,但在JS里,变量的类型仅仅取决于变量内存的值,而变量b内没有值,所以它的数据类型依然是undefined。

相对于其他一些语言,JS没有限制变量的数据类型,显得更加灵活,但相应的,如果一个变量不停地更改类型,会显得非常的混乱。因此,同一个变量,最好只存放一种类型的数据。

变量类型的转换

变量不仅有类型,还可以进行类型的转换。当使用数据的类型不符合我们要求的时候,我们就需要用到类型转换。现在我们来看这么一个例子。

我们在网页中添加两个文本框和一个按钮,并希望点击按钮后文本框中的数字可以相加。虽然这个功能很简单,但我们直接写的话,由于textbox的value属性是以字符串形式返回给JS的,所以我们输入的两个数字最后会被当做字符串相加而不是数值。因此,我们需要用一定的方法将字符串转换为数字。

将字符串转化为数字的方法为parseInt(),下面是关于parseInt()的一个简单例子。

var a = '12';
alert(parseInt(a)+1);

虽然我们将a定义为了字符串,但通过parseInt转化为了数值类型,因此输出结果为13。值得一提的是,parseInt也是从左到右依次扫描字符串,一旦发现不是数字的字符,就会停止工作并将前面的字符返回为数值类型,因此下面三种情况的返回结果依次为12,12,NaN:

var a = '12px';
var b = '12px34';
var c = 'abc';
alert(parseInt(a));
alert(parseInt(b));
alert(parseInt(c));

其中NaN是Not a Number的简称,简单来说就是JS解析不出数字时会返回这个结果。

所以,我们这个案例可以通过如下代码完成:

<html>
<head>
    <meta charset="utf-8">
    <title>无标题文档</title>
</head>
<body>
    <input id="txt1" type="text"/>
    <input id="txt2" type="text"/>
    <input id="btn1" type="button" value="求和"/>
</body>
</html>
window.onload = function () {
    var oTxt1 = document.getElementById('txt1');
    var oTxt2 = document.getElementById('txt2');
    var oBtn = document.getElementById('btn1');
    oBtn.onclick = function () {
        alert(parseInt(oTxt1.value) + parseInt(oTxt2.value));
    };
};

效果如下:

【JavaScript从入门到精通】第六课  javascript基础-01

这里依然存在一个小问题,由于没有对文本框进行任何限制,如果向文本框输入的是字母而不是数字,程序是无法正常进行的。因此,在这个程序里我们应该给输入者一些提示,或者说我们需要判断一下对文本框输入值采用parseInt方法转换出来的结果是否为NaN,如果为NaN,说明用户输入某个值并不是数字,从而返回给用户一个警告。

或许你已经想到应该怎么做了,但实际上在JS里,NaN有一个很奇怪的特性,通过下面一个例子可以反映出来:

var a=parseInt('abc');
var b=parseInt('def');
alert(a==b);

很明显a和b的值都是NaN,但这个程序的结果竟然是false,也就是说在JS里NaN和NaN是不相等的。换句话说,我们判断结果是否为NaN,是无法通过==来进行比较的。好在JS提供了一个函数:isNaN(),用于检测一个变量是否为NaN。

有了这些准备,你应该知道如何解决刚才的问题了吧~?

<html>
<head>
    <meta charset="utf-8">
    <title>无标题文档</title>
</head>
<body>
    <input id="txt1" type="text"/>
    <input id="txt2" type="text"/>
    <input id="btn1" type="button" value="求和"/>
</body>
</html>
window.onload = function () {
    var oTxt1 = document.getElementById('txt1');
    var oTxt2 = document.getElementById('txt2');
    var oBtn = document.getElementById('btn1');

    oBtn.onclick = function () {
        var n1 = parseInt(oTxt1.value);
        var n2 = parseInt(oTxt2.value);

        if (isNaN(n1)) {
            alert('您输入的第一个数字有误');
        }
        else if (isNaN(n2)) {
            alert('您输入的第二个数字有误');
        }
        else {
            alert(n1 + n2);
        }
    };
};

输入字母的时候效果如下:

【JavaScript从入门到精通】第六课  javascript基础-01

用if进行判断,如果用户有输入的不是数字,就会出现相应的错误提示框;如果两个输入的值都没有错误,就弹出正确答案。这里用到了一个else if语句,具体怎么用稍后再讲。

如果我们使用parseInt转换小数,会发生什么呢?

var a='3.5';
alert(parseInt(a));

弹出的结果为3。对于parseInt来说,转换出来的数字如果是小数,会舍去小数部分保留整数部分。但如果我们需要用到小数的话,就应该使用parseInt的兄弟——parseFloat了,二者在使用方法上没有任何区别,这里就不再细讲。当你你不知道转换出来的数值是整数还是小数的时候,可以优先选择使用parseFloat,这样即使转换前的变量为整数也不会出现数值缺损。

在上述的类型转换中,我们明确地告知了计算机我们想要对数据类型进行转换,我们将这种方法称为显式类型转换(强制转换)。相对的,还有一种转换类型叫隐式类型转换。隐式类型转换最简单的例子如下:

var a=5;
var b='5';
alert(a==b);

理论上来说,二者数据类型不相同,输出结果应该为flase。然而,浏览器给出的答案是true。对比以下这个例子:

var a=5;
var b='5';
alert(a===b);

这里,弹出来的答案又变成了false。那么,==和===二者之间存在什么区别?

对于==运算符来说,它在比较之前会先把二者的数据类型转换一致;而===运算符(也叫全等运算符)不转换类型,直接比较。在不转换类型的情况下,a和b自然是不相等了。可以看得出,在比较a==b时,我们并没有明确告诉计算机我们想对a或b的类型进行转换,但计算机自己却偷偷进行了转换,这就叫做隐式转换。除去这个例子外,还存在另一种隐式转换的情况:

var a='12';
var b='5';
alert(a-b);

如果这里是a+b,根据我们前面所讲,计算机会默认是字符串相加而弹出125。但如果是a-b的话,计算机会在做减法之前,同样进行隐式转换成数值类型,从而得到答案7。为什么加法不会进行隐式转换而减法会?因为+运算符本身在JS里就具备字符串连接和数字相加两个功能,在本例中,如果+识别为字符串连接,那么只需要一步即可完成(直接拼接即可),而如果识别为数字相加,则需要两步(先转换类型,再相加)。对于计算机来说,一定会选择步骤更少的路径,因此加法不会进行隐式转换。而-运算符在JS只有数字相减的功能,所以JS不得不进行隐式转换了。

变量作用域

变量作用域即变量可以起作用的范围。

function aaa(){
  var a=12;
}
function bbb(){
  alert(a);
}
aaa();
bbb();

运行这个程序,在bbb函数内会出现变量a没有被定义的报错。实际上,a确实没有被定义,因为在aaa中定义的a是局部变量,而局部变量,只能在定义它的函数里面使用。和局部变量相对的一个概念是全局变量

var a;
function aaa(){
  a=12;
}
function bbb(){
  alert(a);
}
aaa();
bbb();

这个例子里,a被声明在所有函数的外面,这样的变量就是全局变量,可以在任何地方使用,因此能够正常地弹出12。

闭包

关于闭包的概念,大家可以不去深究,感兴趣的可以百度一下看看。我们刚才说过,局部变量只能在定义它的函数内使用。实际上,有一种情况是例外的。

function aaa(){
  var a=12;
  function bbb()
  {
    alert(a);
  }
  bbb();
}
aaa();

当函数bbb被包含在函数aaa内时,程序可以成功运行。这种写法就被叫做闭包。闭包有一些高级的应用,这些内容我们以后都会讲到。在这个闭包结构里,aaa被叫做父函数,bbb被叫做子函数。对于闭包来说,子函数可以使用父函数的局部变量。如果你足够细心,回去看看我们之前写过的代码,就会发现我们已经有意无意用到过闭包了(例如上面的求和函数)。

命名规范

所谓命名规范,就是如何给函数和变量取名字。实际上,给函数和变量取名字和给孩子取名字差不多,理论上可以随便取,但实际应用中又不能显得太过随意,否则可能会引起一些误会。

在命名规范上,一般遵循两个特性:

  • 可读性——能看懂
  • 规范性——符合规则

可读性代表取名尽可能让人能看懂,如果代码通篇都是aaa,bbb,ccc这样的取名,而程序本身又比较庞大,那么阅读将是一件非常痛苦的事情。规范性表示JS有一个较为约定俗称的命名规则,大部分情况下采用匈牙利命名法或者类似方法,其原则为:

  • 类型前缀
  • 首字母大写

JS常用类型前缀如下:

【JavaScript从入门到精通】第六课  javascript基础-01

前缀通常表明了变量存储的类型,让人一眼就能看出来变量里面存的是什么,他人拿到代码的时候也不会随意修改数据类型,使得代码更加规范。通常只有变量遵循前缀的规范,而函数没有必要。

当一个变量或者函数名是由多个英文单词组成的时候,每个单词的首字母使用大写,例如oDivUserLogin,这样可以更清晰地判断变量的含义。

如需转载,烦请注明出处:https://www.qdskill.com/javascript/472.html

发表评论

登录后才能评论