W3C标准规定:结构、样式、行为相分离,html负责结构、css负责样式、javascript负责行为;其可以动态的操作html结构,增删改查(样式的变化、逻辑行为的变化等)
关于javascript,我们还是要了解一些其的发展历程;
【NCSA Mosaic,或简称Mosaic,是互联网历史上第一个获普遍使用和能够显示图片的网页浏览器,后来网景导航者浏览器的开发工作,聘用了许多原有的Mosaic浏览器工程师,但是没有采用Mosaic网页浏览器的任何代码。传承网景浏览器代码的后裔为Firefox浏览器。】
1、javascript的历程:1995年,网景公司(Netscape)正凭借Navigator浏览器成为Web时代很瞩目的互联网公司,当时的网页还皆是静态,网景公司希望可以在静态网页中添加一些动态效果,于是公司内部一哥们两周左右的时间设计出了javascript语言,其与Java语言没什么必然的联系(因为Netscape与Sun合作,Netscape管理层希望它外观看起来像Java,同时也希望借Java进行市场宣传,因此取名为JavaScript)一年后Microsoft开发出了JScript,微软强大的桌面系统最终干掉了网景公司,几个公司联合ECMA组织定制了javascript语言的标准,被称为ECMAScript,现在所提到的Javascript的标准就是ECMAScript标准;
【网景公司最终被收购,其的失败很大程度上是微软IE浏览器造成的。微软采取操作系统捆绑IE浏览器策略,firefox(开放源码)传承,gecko内核,也是五大主流浏览器之一;】
Javascript语言依旧有一些设计缺陷;而对于浏览器而言,浏览器发布时候就确定了Javascript的版本,目前面临的是处理兼容问题,很多用户依旧在使用ie6这种很老的浏览器,尽量兼容到ie8;
。。。。。。过多也不做阐述了,接下来更多去回归到这门语言的本身~ ~ ~
2、Javascript是一种弱类型(动态)、多范式的解释性脚本语言;
同时还有三大特性:解释性,单线程,ECMA标准;
同步、异步的区别:计算机中的概念与生活中的概念正好相反,计算机中所谓同步:不同时进行,异步:同时进行,例如在浏览器渲染网页的过程中,加载html结构的同时,css文件和js文件同时进行加载;(加载即为下载)
单线程:同一时间内只做一件事,在javascript中同一时间可以实现多个效果的展示,涉及到js执行队列问题,js执行时候采用“轮转时间片”的方法进行,不同效果之间进行快速切换;(轮转时间片类似于“吃饭问题”)
ECMA标准:严格按照此标准执行,目前是ECMAScript 6标准(简称ES6){2015年6月正式发布了}谈到javascript的版本,指代的即为ECMA标准;
Javascript严格区分大小写,
3、javascript分为三部分:ECMAScript(原生js)、DOM、BOM;接下来先学习ECMAScript;
ECMAScript内容:
1、引入js:页面级(head内、body内、body外)和外联式, 不可以既使用页面级,也使用外联式(如果混合使用,外联式起作用,切不要混合使用);
2、js变量用var来声明,变量声明规则:(1).变量由字母、数字、下划线、$构成,首字母不能是数字;(2).关键字、保留字不能作为变量名(所谓保留字:如今虽然不是关键字,之后有可能成为关键字);(3).变量名遵循小驼峰规则;
【定义变量=变量声明+变量初始化(赋值)var a; //变量声明 a = 10; //变量初始化 var a=10; //定义变量 】
3、数据类型:(先对其有个基础认知)
原始值:Number String Boolean undefined null;
引用值:数组、对象、function (date RegExp Math等等js有很多引用值);
原始值存放于栈区(stack),其是不可改变的值(定义后值便不可以改变),变量赋值的时候要注意,后期有很多应用场景,字符串拼接时也有用到;[stack: 后进先出] var a = 6; var b = a; a = 10; console.log(b);//6; a=10;的时候由于原始值定义后不可改变,其会新开辟空间,将原来的空间抹掉(名字抹掉,内存空间二次覆盖才会消失) ,a,b互不影响,压根内存就没什么联系;
引用值内容存放于堆区,地址存放于栈区,地址指向堆区,地址相同指向同一块内存空间;[heap: 先进后出]
var arr = [1,2]; var arr1 = arr; arr.push(3); console.log(arr1);//[1,2,3] 方法添加直接添加到数组中了【补充:聚焦点在方法添加元素,后续学到push()方法,其是会改变原数组,内部还有更深入的机制】
var arr = [1,2]; var arr1 = arr; arr = [1,3];console.log(arr1);//[1,2] 相当于是新开辟了一块内存空间,一个数组名只能对应一个地址,一个地址只能指向一块空间,该地址指向了新存储空间;
(1).Number:数字类型(不区分整型和浮点型,统一用Number表示,其他语言数字类型是整型,js中是浮点型) [用到的数字都是Number类型,infinity(1/0), -infinity(-1/0) NaN(0/0)], [数学规则运算]
(2).String : 单引号、多引号括起来的任意文本;
(3).Boolean:true 、false;
(4).undefined: 未定义(声明变量但未赋值); not a defined(压根就没有声明);
(5).null: 空(大多数情况表示占位符)
(6). var arr = [1,2,3,4,5,6,false,true,{},[]]; (弱类型语言的好处,同一数组中的数组元素可以是不同数据类型,强类型语言确定数据类型后数组元素的类型也就确定了,后续前后端数据传输中更为便捷)
4、运算符:最终得到的都是结果,布尔值或者数值;
(1).算术运算符:最基本都是从左到右运行; + - * / % ++ -- ;
1/0: Infinity Number; 正无穷大
-1/0: -Infinity Number; 负无穷大
0/0: NaN Not a Number ,当无法计算结果时用NaN
(2).比较运算符: > < >= <= == != (=== !==) 比较的目的是判断对错,结果为布尔值;
[1].console.log(3>2);//true; console.log(3>"4");//false 隐式转换为number类型比较;
[2].若是字符串,则是逐位ASCII码进行比较,console.log("1">"2");//false; console.log("10">"2")//false; 字符串一零和字符串2比较,显然1的ASCII码小于2的ASCII;[ASCII码表表示的是7位二进制数的大小0000000,也就是128个,主要解决的是一些字符需要转换为二进制编码,常用的便是A:65,a:97,0:48; ASCII码扩展表表示8位二进制的大小00000000,0~255个,unicode编码(万国码),为每一种语言的每一个字符都设定了统一的唯一的二进制码,16位二进制的大小,65525个,范围几乎囊括所有字符,应该没有甲骨文等古文字];
[3]."==" 隐式转换为Number()判断,=== 绝对等于,以上所谈皆是针对原始值,若是引用值则不同,创建的每一个引用值都有独自的地址指向自己的存储空间; 【=== 原始值中每个数都会恒等,引用值和NaN除外】
1 == "1" //true; 1==="1" //false;
undefined == null; //true; 控制台中测试发现undefined>0,false; undefined<0,false; undefined=0,false; null>0,false; null<0,false; null=0,false; 但测试发生undefined==null;但undefined === null;//false 绝对不相等;
{}=={};//false; {}==={}//false; []==[]//false; []===[]//false; 引用值比较时内存空间不同;
NaN == NaN; NaN === NaN; // 都为false,NaN和谁都不相等,唯一能判断NaN的方法isNaN(NaN);//true;
parseInt('1a')==1; //true;
绝对等于 === 绝对不等于!== 两者的长度都为3
(3).逻辑运算符: && || ! 用处极大,常用在语句判断中,输出的结果为值;
【undefined , null, NaN, "" 0 , false 六个值的布尔值都为false,其余都是true】;
[1]&&运算符: 先判断第一个表达式转换为布尔值的结果,若结果为真,就直接输出第二个值,若第一个表达式的布尔值为false,则输出第一个值;【输出的是值,而非true/false,true/false只是判断是否继续进行判断】同理三个/n个表达式都是如此判断;2 && false && 0 ;//false;
[2].||运算符: 先判断第一个表达式转换为布尔值的结果,若为真就返回该值,若为假就继续判断,若是两个数布尔值都为false,则返回最后一个值(终究还是要返回一个值);同理三个/n个表达式都是如此判断; 0 || false; //false; 0 || false || 1;//1;
补充:【&&中的“全真即为真,一假即为假”,这种现象是根据最后输出值的布尔值得出的,底层判断的逻辑就是上述,后续if语句中的条件判断中也遵循上述,但没必要那么判断,直接理解成并且即可,||理解为或者即可,其他情况还遵循上述更易于理解;】【无论是字符串、数字、还是比较表达式、函数、语句都可以看作是一个表达式】
【使用场景很广泛: &&运算符有短路语句的作用,2>1&& document.wirte("a");若是前面语句成立,才执行后面语句;后端往前端传入数据时使用其进行判断 data && fn(data); 若是data 是空的或者undefined,则不执行后面的语句,类似于if判断;||运算符:处理兼容性很灵活,div.onclick = function(e){ var event = e|| window.event; } 】
[3]. !运算符 :先转化为布尔值再取反;var a = !123; /false; var a = ! !"";//false;
& | 与运算或运算,短路与短路或,二进制进行计算,在实际开发中几乎不用;
(4).赋值运算符:= += -= *= /= %=
(5).条件运算符(三目):变量=条件?值1:值2;
(6).位运算符:&、| 、~ 、^(异或) << 左移 >> 右移
5、语句:
(1).if 语句:if语句和switch语句要灵活使用,后者可以灵活规避掉一些“耦合”问题;【if条件判断聚焦点是true/false,来确定是否执行后面的语句】
条件语句补充: switch语句,break,continue的使用;【break/continue都是关键字,break终止循环,其必须写在循环语句中,即使是嵌套的语句也OK,单独写在其他语句中会报错】
while(1){i++; console.log(i); if(i > 100){ break;}} 不会报错;下面直接写在非循环语句中会报错;
(2).循环语句:for循环 for(var i=0; i<10; i++){}.弄清楚其的执行顺序后,括号内的语句第一句可以放到循环体外,第三句可以放在执行体内,所以括号内可省略;
while循环:底层机制就是for循环,括号内无前后语句,只有中间的语句; do while循环,计算开发中几乎不使用;
6、typeof()方法,返回数据类型,可以返回6个值,number string boolean undefined object function; 基本上引用值都返回object对象, var num = {} ,空对象, var num = null,最早是代替空对象占位的(不等同于空对象),虽然是原始值,但返回依旧是object,有历史遗留问题;
(1). typeof ()返回的格式就是字符串“”;双引号内显示具体返回的类型;(可都是小写)
(2).typeof()方法 ,也可以写成是typeof abc,(不加括号,直接加空格);
(3).typeof(a);// 变量a没有声明但不会报错,结果为“undefined”, 字符串,【唯一一个未声明不报错】
延生:typeof(typeof(a)); //"string" 未经声明不会报错,返回字符串"undefined",typeof("undefined");
typeof(NaN);//"number" typeof(null):// "object" typeof(undefined)://"undefined"
typeof(1 =="1");//"boolean" typeof(NaN == NaN);// "boolean" 【其只能返回6个字符串值,细心】
7、类型转换:聚焦点是原始值之间的类型转换;
(1).显示类型转换:
[1].Number(); 转换为数字,Number(null);// 0 Number(undefined);//NaN Number("a");//NaN,看着能转换为数字的才转换,Number("123abc");//NaN; 并没有砍断原则;
[2].parseInt();转换为整型数字,parseInt(123.6);//没有四舍五入取整数部分即可; 其的作用主要是解析字符串的,parseInt(123.6abc);//NaN; parseInt(string,radix);// 首个参数必填,第二个为进制,选填,基低为2~36,此数据就是以该基低为进制的数,转换为10进制;小于2/大于36,返回NaN;[常见使用场景:parseInt("100px");//100; 砍断原则针对的是字符串]
[3].parseFloat(); parseFloat("123.92abc");//123.92
[4].Boolean(); 转换为布尔值,布尔值只有true/false; 所谓的0/1只是计算机二进制的表示(元器件的开关)或者布尔值转为数字类型,不要混淆;
[5].String(); 转换为字符串,toString();方法的使用也可以转换为字符串[打点方式调用,后续会讲到,该方法是Object根对象的方法,所有对象都有该方法,undefined和null不是对象,其没有此方法],toStirng(radix); 把10进制的数转换为该参数进制;【除上述两种方法可转换为字符串,还可以使用+""; 任何数与空串拼接都会隐式转换为字符串类型】
(2).隐式类型转换:其内部都是调用的显示类型转换方法;
[1].isNaN(); 此方法判断传入的数据是否为NaN,结果为布尔值;隐式先调用Number();再判断;console.log(isNaN('abc'))//true;console.log(isNaN(null));//false;console.log(isNaN(undefined));//true
[2].++/--、+/-(正/负)、减乘除求余:隐式调用Number();进行转换;
[3].+ 连接符 :隐式调用String(); 只要连接符有字符串,其会将所有的数都转换为字符串来进行拼接
[4].&& || ! : 隐式调用Boolean();
[5]. > < >= <= : 比较运算符隐式转换为Number(); 结合比较运算符的规则,"3">"2"两个都是字符串逐位比较ASCII码;
(3).不发生类型转换: === !==;绝对等于,绝对不等于;【NaN是特殊,注意引用值】
(4).特性无规则,系统定义的:undefined == null; //true; 控制台中测试发现undefined>0,false; undefined<0,false; undefined=0,false; null>0,false; null<0,false; null=0,false; 但测试发生undefined==null;但undefined === null;//false 绝对不相等;
8、toFixed(num);//小数点后保留num位数字(四舍五入) num范围0~20,不写默认为0; var numv = 123.6788; numv.toFixed();//124; numv.toFixed(3); //123.679;
补充: