【JavaScript从入门到放弃】JS基础-01

  作为一个前端开发人员,JS是我们行走江湖吃饭的家伙。基本上一个前端人员能值多少大洋,就看JS了。虽然各种框架层出不穷,但是归根结底学好原生JS才是硬道理。

  学习任何新东西其实都遵循 10000 小时成才定律,只要付出时间,就会有收获。人与人的不同只是收获的多少不同。关于天赋问题,我们确实要承认某些人在某些领域确实比其他人厉害。但大部分人其实都是普通人,不需要天赋,只需要通过时间的简单堆积就可以混口饭吃。

  弹钢琴能到郎朗那个级别的人是少数了,多数艺术生都普普通通,毕业出来混个钢琴老师当当,办个培训学校赚点钱娶媳妇儿生孩子,最多写本书什么的。只有投入足够多的时间,你发现某些人确实比你厉害,这个时候才适合讨论天赋问题。所以,不要自我否定,才是真正的成长的开始。

  咱们言归正传吧。

  一,JavaScript的组成

  JavaScript主要由以下3部分组成:

  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拥有了操作浏览器的能力,在JavaScript当中BOM以window的形式存在,有了BOM,JS就拥有了类似弹窗,关闭窗口,复制内容到剪贴板等与浏览器相关的功能。

  从兼容性的角度来看的话,ES(ECMAScript)基本上不存在兼容性问题,DOM有一些操作上的不兼容,而BOM完全不兼容,所以尽可能避免使用BOM,这样可以省去很多的麻烦。

  二,变量类型

  首先说变量,从字面上理解就是可以变化的量,放到编程语言里面,就是可以被赋值改变的量。和变量对应的就是常量,我们经常遇到的比如,10,20这样的不能改变的数字,就是常量,一个确定的值。不能被赋值也不能被改变。

  在JS中我们把变量分为了多种类型。

var a = 1024; 
alert(typeof a); 

var a = 'cos'; 
alert(typeof a);
 
var a = true; 
alert(typeof a);
 
var a = function (){   alert('cos'); } 
alert(typeof a); 

var a = document; 
alert(typeof a);

  typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型。它返回值是一个字符串,该字符串说明运算数的类型。

  我们可以通过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 = '1024'; alert(parseInt(a)+1);

  这里我们将a定义为了字符串,但是通过parseInt转化后得到了数值类型的数据,所以输出结果为1025。需要注意的是,parseInt是从左到右依次扫描字符串,一旦发现不是数字的字符,就立即停止工作,并将前面的字符通过数值类型返回,所以下面三种情况的返回结果依次为1024,1024,NaN:

var a = '1024px';
var b = '1024px24';
var c = 'abc';
alert(parseInt(a));
alert(parseInt(b));
alert(parseInt(c));

  这里的 NaN 是Not a Number的简写,简言之就是JS解析不出数字时会返回这个结果。

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

<script>
     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));       };       }; </script> <body>     <input id="txt1" type="text" />     <input id="txt2" type="text" />     <input id="btn1" type="button" value="求和" /> </body>

  运行结果:

  这里有一个问题,我们并没有对文本框进行任何限制,当用户向文本框输入的是字母而不是数字的时候,程序是不能正常执行的。所以,这时候需要判断一下对文本框输入值通过 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。

  现在我们来看:

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

  通过 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。

  五,闭包

  关于闭包的概念,我建议你现阶段先不用深究,如果很感兴趣的话可以Google一下。咱们说过,局部变量只能在定义它的函数内使用。那么,有一种情况例外:

  function aaa(){

  var a=12;

  function bbb()

  {

  alert(a);

  }

  bbb();

  }

  aaa();

  当函数bbb被包含在函数aaa内时,程序可以成功运行。此种写法就被称为闭包。闭包有很多高级的应用,当然这些都是后话,我们慢慢学习。在闭包结构中,aaa称为父函数,bbb称为子函数。对于闭包而言,子函数可以使用父函数的局部变量。事实上,刚刚我们已经使用过闭包了,例如上面的求和函数。

  六,命名规范

  命名规范,即怎样给函数以及变量取名字。

  给函数和变量取名字和给你孩子取名字差不多,理论而言是可以随便取的,但实际应用中又不能显得太俗太low,否则可能会引起隔壁老王的不满。

  关于命名规范:

  可读性——容易看懂

  规范性——合乎规则

  可读性代表取名尽可能让人能看懂。要是代码通篇都是aaa,bbb,ccc这样的取名,又正好碰到程序比较庞大,此时阅读将是一件非常痛苦的事情。

  规范性表示JS有一个较为约定俗称的命名规则,大部分情况下采用匈牙利命名法或者类似方法,其原则为:

  类型前缀

  首字母大写

  JS中常见类型前缀:

  类型前缀一般表明了变量存储的类型,使我们一眼就能辨识变量当中存的是什么,其他人拿到代码的时候就不会胡乱更改数据类型,这样保证了代码的规范和更好的可读性。一般而言只有变量遵循前缀的规范,而函数则没有这个必要。

  当一个变量或者函数名由多个英文单词组成的时候,我们通常使用驼峰法命名,每个单词的首字母使用大写,例如oBtnUserLogin,这种命名方式可以更清晰地判断变量的含义。

posted @ 2018-01-14 15:53  博客趣  阅读(11681)  评论(0编辑  收藏  举报