1. JavaScript初体验

  1. 在 HTML 中,JavaScript 代码必须位于<script></script> 标签之间。

    <script>
    	alert('这是我们的第一个js代码');
    </script>
    

    注释:旧的 JavaScript 例子也许会使用 type 属性:<script type="text/javascript">

    注释:type 属性不是必需的。JavaScript 是 HTML 中的默认脚本语言。

  2. <body>或者<head>中的JavaScript

    脚本可被放置与 HTML 页面的 <body><head> 部分中,或兼而有之。

    • <body>中的JavaScript

      <!DOCTYPE html>
      <html>
          <head>
            	<title>body中的JavaScript</title>
        	</head>
          <body> 
              <script>
                     alert('body中的JavaScript');
              </script>
          </body>
      </html>
      

      body 部分中的脚本: 当页面被加载时执行的脚本放在HTML的body部分。放在body部分的脚本通常被用来生成页面的内容。

    • <head>中的JavaScript

      <!DOCTYPE html>
      <html>
          <head>
              <script>
                  alert('<head>中的JavaScript');
              </script>
          </head>
          <body>
          </body>
      </html>
      

      head 部分中的脚本: 需调用才执行的脚本或事件触发执行的脚本放在HTML的head部分中。当你把脚本放在head部分中时,可以保证脚本在任何调用之前被加载。

    • body 和 head 部分可同时有脚本:文件中可以在body和head部分同时存在脚本

      <html>
          <head>
            <script>
            		alert(111);
            </script>
          </head>
          <body>
            <script>
            		alert(222);
            </script>
          </body>
      </html>
      

      思考:head和body中同时存在script文件会执行哪个?

    • 总结:js文件放到哪里更好?

      • 浏览器对html页面内容的加载是顺序加载,也就是在html页面中前面先加载。当浏览器加载html文件并解析到<head>时,<body>并没有被解析,浏览器会等到<head>中的js部分执行完再加载页面。
      • 如果把javascript放在head里的话,则先被解析,但这时候body还没有解析。(常规html结构都是head在前,body在后)如果head的js代码是需要传入一个参数(在body中调用该方法时,才会传入参数),并需调用该参数进行一系列的操作,那么这时候肯定就会报错,因为函数该参数未定undefined
      • 从JavaScript对页面下载性能方向考虑:由于脚本会阻塞其他资源的下载(如图片等)和页面渲染,直到脚本全部下载并执行完成后,页面的渲染才会继续,因此推荐将所有的<script>标签尽可能放到<body>标签的底部,以尽量减少对整个页面下载的影响。
  3. 引入外部脚本文件

    • JS程序不仅可以直接写在HTML文档中,也可以放在JavaScript文件中。后缀名是.js。使用任何文本编辑器都可以编辑。
    • JS文件不能够单独运行,需要使用 <script>标签导入到网页中。
    • 定义src属性的<script>标签不应该再含有JavaScript代码,否则只会下载并执行外部JavaScript文件,嵌入代码被忽略。
    1)创建一个js文件,名称为first.js
    2) 引入js文件
        <html>
            <head>
                <title></title>
            </head>
            <body>
              <script src='first.js'></script>
            </body>
        </html>
    

    注意:在外部文件中放置脚本有如下优势:

    • 分离了 HTML 和js代码
    • 使 HTML 和 JavaScript 更易于阅读和维护
    • 已缓存的 JavaScript 文件可加速页面加载

    思考:内部js代码和外部引用哪个优先级更高?

  4. 延迟执行JS-defer

    • <script>标签有一个布尔型属性defer,这个属性的用途是表明脚本在执行时不会影响页面的构造,也就是说,脚本会被延迟到整个页面都解析完成后再运行。
    • 因此在script元素中设置defer属性,相当于告诉浏览器立即下载,但是延迟执行
    • 如果页面中有多个延迟脚本,那么第一个延迟脚本会先于第二个延迟脚本执行
    • 适用于外部JS文件,不适用于script标签包含的脚本
    1)创建一个js文件,名称为first.js
    2) 引入js延迟文件
      <!DOCTYPE html>
      <html lang="en">
            <head>
                <meta charset="UTF-8">
                <title>Document</title>
                <script src="./first.js" defer></script>
                <script>
                    alert("head引入js")
                </script>
            </head>
            <body>
                <script>
                    alert("body末尾引入js")
                </script>
            </body>
      </html>
    
  5. 异步加载JS文件-async

    • 在默认情况下,网页都是同步加载外部 JavaScript文件的,在引入外部js文件时会阻塞dom的执行,为此在html4.01为script标签引入了async属性

    • 现在可以为<script>标签设置 async属性,让浏览器异步加载 Javascript文件,即表示应该立即下载脚本,但不应妨碍页面汇总的其它操作。只对外部脚本文件有效。

    • 因为是下载完立即执行,不能保证多个加载时的先后顺序,因此确保异步脚本之间互不依赖

      1)创建一个js文件,名称为first.js
      2)引入js文件
          <!DOCTYPE html>
          <html lang="en">
              <head>
                  <meta charset="UTF-8">
                  <meta name="viewport" content="width=device-width, initial-scale=1.0">
                  <title>Document</title>
                  <script src="a.js" async></script>
              </head>
              <body>
                 这是测试async的小案例,一jiao wulijiaojiao
              </body>
          </html>
      
  6. 扩展:async&defer

    • 没有设置任何属性的script

      HTML文件将被解析,直到脚本文件被下载为止,同时将停止解析,发起请求去提取script文件(如果是外部文件)。下载并执行完成后将在恢复解析HTML。

      03

    • 设置了defer属性

      设置defer属性会在HTML解析的同时下载script,并在完成HTML解析和script下载之后执行该文件,同时设置了defer的脚本会按照他们在文档里面出现的顺序执行。

      04

    • 设置了async属性

      设置async属性会在HTML解析期间下载script文件,并在完成下载后暂停HTML解析器以执行该文件。

      05

2. JavaScript 输出

JavaScript 能够以不同方式“显示”数据:

  • 使用 window.alert() 写入警告框
  • 使用 document.write() 写入 HTML 输出
  • 使用 innerHTML 写入 HTML 元素
  • 使用 console.log() 写入浏览器控制台
  1. alert

    您能够使用警告框来显示数据:

    <!DOCTYPE html>
    <html>
      <body>
          <script>
            	//和alert是一样的,后续window对象时候讲解
          		window.alert('故事里的小黄花');
          </script>
      </body>
    </html> 
    
  2. document.write

    1. 可以向HTML输出流中插入你传入的内容,浏览器会按着HTML元素依次顺序依次解析它们,并显示出来。
    <!DOCTYPE html>
    <html>
      <body>
          <script>
          		document.write('从出生那年就飘着');
          </script>
      </body>
    </html> 
    
    1. 需要注意的是,如果在文档加载完成后(即HTML输出已完成),再使用document.write()方法来要求浏览器来解析你的内容,则浏览器就会重写整个document,导致最后的这个document.write()方法输出的内容会覆盖之前所有的内容
    <!DOCTYPE html>
    <html>
    	<body>
    		<h6>淡黄的长裙</h6>
    		<h6>蓬松的头发</h6>
    		<button onclick="document.write('<h1>什么玩意儿</h1>')">试一试</button>
    	</body>
    </html>
    
  3. innerHTML

    id 属性定义 HTML 元素。innerHTML 属性定义 HTML 内容:

    <!DOCTYPE html>
    <html>
    	<body>
    		<p id="demo"></p>
    		<script>
    			document.getElementById("demo").innerHTML = '我们的开始,是漫长的电影';
    		</script>
    	</body>
    </html> 
    
  4. console.log

    在浏览器中,您可使用 console.log() 方法来显示数据。

    请通过 F12 来激活浏览器控制台,并在菜单中选择“控制台”。

    <!DOCTYPE html>
    <html>
    	<body>
    		<p id="demo"></p>
    		<script>
    			console.log('苍茫的天涯是的爱');
    		</script>
    	</body>
    </html> 
    

3. JavaScript语句

  1. JavaScript 语句

    JavaScript 语句由以下构成:值、运算符、表达式、关键词和注释。

    //我是一个注释,我属于js语句的一部分,我也是狠重要的
    var age = 1 + 17;
    
  2. 分号;

    a = 1;
    b = 2;
    c = a + b;
    

    如果有分号分隔,允许在同一行写多条语句:

    a = 1; b = 2; c = a + b;
    
  3. js的代码的行长度和折行

    为了达到最佳的可读性,程序员们常常喜欢把代码行控制在 80 个字符以内。

    可以在文本字符串中使用反斜杠对代码行进行换行

    <!DOCTYPE html>
    <html>
    	<body>
    		<script>
    			document.write('我一路向北 \
    			离开有你的季节');
    		</script>
    	</body>
    </html> 
    

    不能像这样折行

    <!DOCTYPE html>
    <html>
    	<body>
    		<script>
    			document.write \ 
    			("你好世界!");
    		</script>
    	</body>
    </html> 
    
  4. js空白字符

    js会忽略多个空格。您可以向脚本添加空格,以增强可读性

    这两行是相等的:

    var name = "emo";
    var name="emo"; 
    

    在运算符旁边( = + - * / )添加空格是个好习惯:

    var x = y + z;
    
  5. js代码块

    JavaScript 可以分批地组合起来。代码块以左花括号开始,以右花括号结束。代码块的作用是一并地执行语句序列。

    function myFirst() {
        alert('听妈妈的话别让她受伤');
        alert('想快快长大才能保护她');
    }
    

4. JavaScript注释

  • 单行注释

    单行注释以 // 开头。

    任何位于 // 与行末之间的文本都会被 JavaScript 忽略(不会执行)。

    <!DOCTYPE html>
    <html>
    	<body>
    		<script>
    			// 我是一个注释
    			document.write("乘着风游荡在蓝天边");
    		</script>
    	</body>
    </html> 
    
  • 多行注释

    多行注释以 /* 开始,以 */ 结尾。

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset='utf-8'>
    	</head>
    	<body>
    		<script>
    			/* 
    				祭司神殿征战弓箭是谁的从前,
    				喜欢在人潮中你只属於我的那画面,
    				经过苏美女神身边,我以女神之名许愿,
    				思念像底格里斯河般的漫延,当古文明只剩下难解的语言,
    				传说就成了永垂不朽的诗篇
    			*/
    			document.write("乘着风游荡在蓝天边");
    		</script>
    	</body>
    </html> 
    
  • 在行末使用注释

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset='utf-8'>
    	</head>
    	<body>
    		<script>
    			document.write("乘着风游荡在蓝天边"); //繁华如三千东流水,我只取一瓢爱了解
    		</script>
    	</body>
    </html> 
    

5. JavaScript变量

思考:下列代码有什么问题?

		<script type="text/javascript">
				console.log(123456789012345678901234567890);
				console.log(123456789012345678901234567890);
				console.log(123456789012345678901234567890);
				console.log(123456789012345678901234567890);
				console.log(123456789012345678901234567890);
				console.log(123456789012345678901234567890);
				console.log(123456789012345678901234567890);
		</script>
  1. js变量

    定义:值可以被修改的量叫做变量

    格式:定义一个变量:var x = 1;

    x 叫做变量名,1 叫做字面量。

    说明:

    • 变量相当于容器,值相当于容器内装的东西,而变量名就是容器上贴着的标签,通过标签可以找到变量,以便读、写它存储的值
    • ECMAScript 的变量是松散类型(弱类型,动态类型)的,所谓松散类型就是可以用来保存任何类型的数据
  2. 声明变量

    在 js中,声明变量使用 var 语句。

    案例1:在一个 var 语句中,可以声明一个或多个变量,也可以为变量赋值,未赋值的变量初始化为 undefined(未定义)值。当声明多个变量时,应使用逗号运算符分隔。

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset='utf-8'>
    	</head>
    	<body>
    		<script>
    			var a;  //声明一个变量
    			var a,b,c;  //声明多个变量
    			var b = 1; //声明并赋值
    			console.log(a);  //返回 undefined
    			console.log(b);  //返回 1
    		</script>
    	</body>
    </html> 
    

    案例2:在 js中,可以重复声明同一个变量,也可以反复初始化变量的值。

    <!DOCTYPE html>
    <html>
    	<head>
    		<meta charset='utf-8'>
    	</head>
    	<body>
    		<script>
    			var a = 1;
    			var a = 2;
    			var a = 3;
    			console.log(a);
    		</script>
    	</body>
    </html> 
    

    友情提示:

    ​ 在非严格模式下,JavaScript 允许不声明变量就直接为其赋值,这是因为 JavaScript 解释器能够自动隐式声明变量。隐式声明的变量总是作为全局变量使用。

    ​ 在严格模式下,变量必须先声明,然后才能使用。

  3. 变量的命名规范

    • 构造变量名称(唯一标识符)的通用规则是:

      • 名称可包含字母、数字、下划线和美元符号
      • 名称必须以字母开头
      • 名称也可以 $ 和 _ 开头(逗比写法)
      • 名称对大小写敏感(Animal和 animal 是不同的变量)
      • 保留字(比如 JavaScript 的关键词)无法用作变量名称

      提示:JavaScript 标识符对大小写敏感。

    • js标识符

      系统征用的有特殊功能的单词.

      15

      • 标识符指的是变量、函数、属性的名字,或者函数的参数。

      • 标识符命名规范

        • 第一个字符必须是一个字母、下划线(_)或一个美元符号($),其他字符可以是字母、下划线、美元符号或数字

        • 不能含有空格 不能以关键字或保留字命名

        • 保留关键字

          06

          *标记的关键字是 ECMAScript5 中新添加的。

        • 应该避免使用 JavaScript 内置的对象、属性和方法的名称作为 Javascript 的变量或函数名:

          07

    • 命名规范

      标识符命名要做到顾名思义。

      起一个有意义的名字,尽量做到看一眼就知道是什么意思(提高代码可 读性) 比如: 名字 就定义为 name , 定义学生 用 student

      a = "zhangsan"  # bad
      name = "zhangsan"  # good
      b = 23   # bad
      age = 23 # good
      

      遵守一定的命名规范。

      • 驼峰命名法,又分为大驼峰命名法和小驼峰命名法

      16

      • 小驼峰式命名法(lower camel case): 第一个单词以小写字母开始;第二个单词的首字母大写,例如:myName、aDog
      • 大驼峰式命名法(upper camel case): 每一个单字的首字母都采用大写字母,例如:FirstName、LastName.
      • 下划线 user_name
  4. 赋值变量

    • 使用等号=运算符可以为变量赋值,等号左侧为变量,右侧为被赋的值。
    <!DOCTYPE html>
    <html>
    	<head>
          这是一个赋值变量的一个案例
    	</head>
    	<body>
    		<script>
    			var name = 'Barry';
    			console.log(name);
    		</script>
    	</body>
    </html> 
    
    • 变量提升

      JavaScript 在预编译期会先预处理声明的变量

      <!DOCTYPE html>
      <html>
      	<head>
      		<meta charset='utf-8'>
      	</head>
      	<body>
      		<script>
      			console.log(a_name);
      			a_name = 'Barry'
      			console.log(a_name);
      			var a_name;
      		</script>
      	</body>
      </html> 
      

      注意:声明变量放在最后,赋值操作放在前面。由于 JavaScript 在预编译期已经对变量声明语句进行了预解析,所以第一行代码读取变量值时不会抛出异常,而是返回未初始化的值 undefined。第三行代码是在赋值操作之后读取,故显示为Barry。JavaScript 引擎的解析方式是:先解析代码,获取所有被声明的变量,然后再一行一行地运行。 这样,所有声明的变量都会被提升到代码的头部,这就叫作变量提升。

    • 练习1:看看结果是什么?

      <!DOCTYPE html>
      <html>
      	<head>
      		<meta charset='utf-8'>
      	</head>
      	<body>
      		<script>
      			console.log(a);
      			var a = 100;
      			console.log(a);
      		</script>
      	</body>
      </html> 
      
    • 练习2:将两个变量a,b的值交换,var a = 1; var b = 2;

      方案1:

      <!DOCTYPE html>
      <html>
      	<head>
      		<meta charset='utf-8'>
      	</head>
      	<body>
      		<script>
      			var a = 1,
      				b = 2,
      				tmp;
      			tmp = a;
      			a = b;
      			b = tmp;
      			console.log(a);
      			console.log(b);
      		</script>
      	</body>
      </html> 
      

      方案2:

      <!DOCTYPE html>
      <html>
      	<head>
      		<meta charset='utf-8'>
      	</head>
      	<body>
      		<script>
      			var a = 1,
      				b = 2;
      			a = a + b;
      			b = a - b;
      			a = a - b;
      			console.log(a);
      			console.log(b);
      		</script>
      	</body>
      </html> 
      

6. JavaScript的变量类型

JavaScript的数据类型分为两种:

  • 值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、未定义(Undefined)、空(Null)、Symbol。

    注:Symbol 是 ES6 引入了一种新的原始数据类型,表示独一无二的值。

  • 引用数据类型:对象(Object)、数组(Array)、函数(Function)。

  1. 字符串

    字符串可以是引号中的任意文本。您可以使用单引号或双引号:

    • var name = "张三"
    • var name = '李四'

    特殊书写方式-俗称:屌丝写法

    • var name = '王二"麻子"'
    • var name = "你是'小淘气'"
    • 不允许var name = '田七"
    • 不允许var name = "田七'
    • 不允许var name = ""田"七"
    • 不允许var name = ''田'七'
    • 如果某屌丝就想写,可以使用转义字符var name = "\"田\"七"

    思考:两次结果一致吗?

    var name = "谢广坤";
    alert(name);
    alert('name');
    
  2. 数字

    JavaScript 只有一种数字类型。数字可以带小数点,也可以不带:

    • 整数:
      • var a = 1;
    • 浮点数:
      • var a = 1.2;

    科学计数法

    • var a = 123e5; var b = Number.MAX_VALUE
    • var a = 123e-5; var b = Number.MIN_VALUE
  3. 布尔

    布尔(逻辑)只能有两个值:true 或 false。

    • var b = true
    • var b = false
  4. Undefined

    • var u;
  5. null

    • var n = null
    • 类型是object,用来表示一个空的对象

7. JavaScript的变量类型高级

  1. 字符串

    JavaScript字符串(String)就是由零个或多个Unicode字符组成的字符序列。零个字符表示空字符串。

    • 字符串字面量/字符串直接量

      • 字符串必须包含在单引号或双引号中
      • 如果字符串包含在双引号中,则字符串内可以包含单引号;反之,也可以在单引号中包含双引号
      • 在ECMAScript 3中,字符串必须在一行内表示,换行表示是不允许的,如果要换行显示字符串,可以在字符串中添加换行符(\n)
      • 在ECMAScript 5中,字符串允许多行表示.实现方法:在换行结尾处添加反斜杠(\).反斜杠和换行符不作为字符串直接量的内容
      • 在字符串中插入特殊字符,需要使用转义字符,如单引号,双引号等
      • 字符串中每个字符都有固定的位置.第1个子符的下标位置为0,第2个字符的下标位置为1...···以此类推,最后一个字符的下标位置是字符串长度减1
      <!DOCTYPE html>
      <html>
      	<head>
         
          </head>
      	</head>
      	<body>
      		<script>
      			var str1 = '09328"4yrc091708)("*&(^&(*&T';
      			var str2 = "kajhx  askjh &*(";
      			var str3 = '9287O&*b';
      			var str4 = "小王他妈妈说:'他要把翠花嫁给我'";
      			console.log(str4);
      
      			var str5 = "今天天气\n真好"
      			console.log(str5);
      
      			var str6 = "今天天气\
      				真好";
      			console.log(str6);  
      		</script>
      	</body>
      </html> 
      
    • 转义字符

      • 转义字符是字符的一种间接表示方式。在特殊语境中,无法直接使用字符自身

        var str = "请看\"这个是一个双引号";
        console.log(str);
        
      • 如果在一个正常字符前添加反斜杠,JavaScript会忽略该反斜杠

        <!DOCTYPE html>
        <html>
        	<head>
        		<meta charset='utf-8'>
        	</head>
        	<body>
        		<script>
        			var str = "小明妈妈说:\"今天天气真好\"";
        			console.log(str);
        			var str2 = "小明妈妈说:\"\今\天\天\气\真\好\"";
        			console.log(str2);
        			var str3 = "看我斜杠:\\"
        			console.log(str3);
        		</script>
        	</body>
        </html> 
        
    • 字符串操作

      • 借助String类型的原型方法,可以灵活操作字符串(后面各章节中详细介绍)

      • 在JavaScript中,可以使用加号(+)运算符连接两个字符串

      • 使用字符串的length属性获取字符串的字符个数(长度)

      • 在ES5中,字符串可以作为只读数组使用,可以通过中括号运算符添加下标访问某一个值。下标从0开始,最大位置的下标是length-1

        <!DOCTYPE html>
        <html>
        	<head>
        		<meta charset='utf-8'>
        	</head>
        	<body>
        		<script>
        			var str = "老师说";
        			var say = "你好啊";
        			console.log(str+say);
        			console.log(str + 666);
        			console.log(str + 888);
        			console.log(1 + 1);
        			console.log("1" + 1);
        			console.log(1 + "1");
        			var str1 = "今天是个好天气123 b5";
        			console.log(str1.length);
        			console.log(str1[0]);
        			//获取最后一个字符
        			console.log(str1[str1.length-1]);
        		</script>
        	</body>
        </html> 
        
    • String方法

      String方法是可以将其他类型转换成字符串类型

      <!DOCTYPE html>
      <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <title>Title</title>
                </head>
                <body>
                    <script>
                        //1.null类型的转换
                        console.log(String(null));//字符串的 'null'
      
                        //2.undefined转换
                        console.log(String(undefined));//字符串的'undefined'
      
                        //3.number类型的转换
                        //转换规则:普通数字直接变成字符串  其他进制先转换成10进制然后在转换成相应的字符串 无穷大无穷小NaN都直接变成字符串
                        console.log(String(123));//'123'
                        console.log(String(-123));//'-123'
                        console.log(String(4E-5));//'0.00004'
                        console.log(String(Infinity));//'Infinity'
                        console.log(String(-Infinity));//'-Infinity'
                        console.log(String(12.3));//'12.3'
                        console.log(String(NaN));//'NaN'
      
                        //4.布尔值的转换
                        console.log(String(true));//'true'
                        console.log(String(false));//'false'
                    </script>
                </body>
      </html>
      
    • toString方法

      • 我们的代码中有+(加号)运算符的情况下,它在这种情况下(字符串 + 其它什么东西),会调用toString()方法,将其它类型的东西转化为字符串,再和原始字符串拼接成一个字符串
      • 除了null和undefined之外,其他的类型(数值、布尔、字符串)都有toString()方法,它返回相应值的字符串表现(并不修改原变量)。
      • 每个对象都有一个toString()方法。
      • 当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。
      <!DOCTYPE html>
      <html lang="en">
            <head>
                <meta charset="UTF-8">
                <title>Title</title>
            </head>
            <body>
                <script>
                    console.log((1).toString());     // "1"
                    console.log(true.toString());    // "true"
                    console.log(null.toString());    // Uncaught TypeError: Cannot read property 'toString' of null
                    console.log(undefined.toString());// Uncaught TypeError: Cannot read property 'toString' of null
                </script>
            </body>
      </html>
      
  2. 数字

    数字(Number)也称为数值或者数

    当数字直接出现在程序中时,被称为数值直接量。在 JavaScript程序中,直接输入的任何数字都被视为数值直接量。

    JavaScript 中的所有数字都是以 64 位浮点数形式存储,包括整数。例如,2 与 2.0 是同一个数。

    • 浮点数溢出

      执行数值计算时,要防止浮点数溢出。例如,0.1+0.2 并不等于 0.3。

      num = 0.1+0.2; //0.30000000000000004

      这是因为 JavaScript 遵循二进制浮点数算术标准(IEEE 754)而导致的问题。这个标准适合很多应用,但它违背了数字基本常识。

      解决方法:浮点数中的整数运算是精确的,所以小数表现出来的问题可以通过指定精度来避免。例如,针对上面的相加可以这样进行处理。

      a = (1+2)/10; //0.3

      这种处理经常在货币计算中用到。例如,元可以通过乘以 100 而转成分,然后就可以准确地将每项相加,求和后的结果可以除以 100 再转换回元

    • 特殊数值

      08

      • Infinity

        • 计算超出范围会得到无穷大(infinity)或者无穷小(-infinity)

        • 分母为0会构成无穷大Infinity 或负无穷大-Infinity

        • 关于Infinity的运算, 无法计算 加减乘除一个数字都是Infinity,Infinity和Infinity计算,加法乘法为Infinity,其他为NaN

        • Infinity和自身相等 其他比较正常

          <!DOCTYPE html>
          <html lang="en">
                  <head>
                      <meta charset="UTF-8">
                      <title>Title</title>
                  </head>
                  <body>
                      <script>
                          // 分母为0会构成无穷大Infinity 或负无穷大-Infinity
                          var num6 = 5/0;
                          console.log(num6);//Infinity
          
                          var num7 = -5/0;
                          console.log(num7);//-Infinity
          
                          console.log(typeof (Infinity));//无穷大和无穷小都是属于number类型
          
                          // 关于Infinity的运算, 无法计算 加减乘除一个数字都是Infinity,Infinity和Infinity计算,加法乘法为Infinity,其他为NaN
                          console.log(Infinity + 1);//Infinity
                          console.log(Infinity - 1);//Infinity
                          console.log(Infinity - 1000000000000000000000);//Infinity
                          console.log(Infinity - Infinity);//NaN
                          console.log(Infinity * Infinity);//Infinity
                          console.log(Infinity + Infinity);//Infinity
                          console.log(Infinity / Infinity);//NaN
          
                          //Infinity和自身相等  其他比较正常
                          console.log(Infinity > 1);//true
                          console.log(Infinity < 1);//false
                          console.log(Infinity == 1);//false
                          console.log(Infinity > Infinity);//false
                          console.log(Infinity == Infinity);//true
                          console.log(Infinity < Infinity);//false
                          console.log(Infinity > -Infinity);//true
                      </script>
                  </body>
          </html>
          
      • NaN

        • NaN,即非数值(Not a Number)是一个特殊的数值

        • 这个数值用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)

        • NaN特点:无论和谁比较都是fasle 无论和谁计算都是NaN

          <!DOCTYPE html>
          <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <title>Title</title>
                </head>
                <body>
                    <script>
                        var num8 = "红浪漫"-1;
                        console.log(num8)//NaN
          
                        // NaN特点:无论和谁比较都是fasle  无论和谁计算都是NaN
                        console.log(NaN+1);//NaN
                        console.log(NaN>1);//fasle
                        console.log(NaN==1);//fasle
                        console.log(NaN<1);//fasle
                    </script>
                </body>
          </html>
          
      • isNaN

        • isNaN方法检测一个值是不是非纯数字 , 如果非纯数字就返回true 如果是纯数字就返回false

          <!DOCTYPE html>
          <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <title>Title</title>
                </head>
                <body>
                    <script>
                            document.write(isNaN(123));
                            document.write(isNaN(-1.23));
                            document.write(isNaN(5-2));
                            document.write(isNaN(0));
                            document.write(isNaN("Hello"));
                            document.write(isNaN("2005/12/12"));
                    </script>
                </body>
          </html>
          
      • 最大值最小值

        在js中数字也是有最大值和最小值的支持的,如果超过最大值或最小值,就可能计算有误

        // 在js中数字也是有最大值和最小值的支持的,如果超过最大值或最小值,就可能计算有误
        console.log(Number.MIN_VALUE);//5e-324  支持数字的最小值
        console.log(Number.MAX_VALUE);//1.7976931348623157e+308 支持数字的最大值
        
      • 正无穷负无穷

        <!DOCTYPE html>
        <html lang="en">
            <head>
                <meta charset="UTF-8">
                <title>Title</title>
            </head>
            <body>
                <script>
                    console.log(Number.POSITIVE_INFINITY);
                    console.log(Number.NEGATIVE_INFINITY);
                </script>
            </body>
        </html>
        
  3. 布尔

    布尔类型仅包含两个固定的值:truefalse。其中true代表真,false代表假。

    在一些判断等操作中,需要使用布尔值

    <!DOCTYPE html>
    <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script>
                  //1、null
                  console.log(Boolean(null));//false
                  //2.undefined
                  console.log(Boolean(undefined));//false
                  //3.number
                  //数字转布尔值   非0为true  0为false NaN为false
                  console.log(Boolean(123));//true
                  console.log(Boolean(-123));//true
                  console.log(Boolean(0));//false
                  console.log(Boolean(1.23));//true
                  console.log(Boolean(NaN));//false
                  console.log(Boolean(Infinity));//true
                  //4.string
                  //空为false  非空为true
                  console.log(Boolean("123"));//true
                  console.log(Boolean(""));//false
                  console.log(Boolean("    "));//true
              </script>
          </body>
    </html>
    
  4. Undefined

    变量被声明了,但没有赋值时,就等于undefined

    //打印a的时候,找到a了 但是找不到a的值,所以返回一个undefined
    var a;
    console.log(a);
    console.log(a+1);//undefined+1  计算不了
    
    //不声明b,直接使用b,js直接报错  ReferenceError(引用错误): b is not defined
    //说明完全没有找到b这个变量 代码报错停止运行
    console.log(b)
    
  5. null

    • null 类型是第二个只有一个值的数据类型,这个特殊的值是 null。
    • 从逻辑角度来看,null 值表示一个空对象指针,而这也正是使用 typeof 操作符检测null时会返回"object"的原因
  6. 扩展:

  1. Undefined派生自Null,两者都是表示空缺值,转换成布尔值都是假值,可以相等
  2. 但是Undefined和Null属于两种不同的类型
  3. Undefined隐含着意外的空值,而Null隐含着意料之中的空值。因此设置一个变量、参数为空的时候,建议使用null而不是undefined

8. JavaScript判断数据类型

友情提示:

基本数据类型:Undefined、Null、Boolean、Number、String,Symbol

引用数据类型 :Object

  1. typeof

    typeof可以识别出基本类型boolean,number,undefined,string,symbol,但是不能识别null。不能识别引用数据类型,会把null、array、object统一归为object类型,但是可以识别出function。

    所以typeof可以用来识别一些基本类型

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <script>
            var bool = true;
            var num = 1;
            var str = 'abc';
            var und= undefined;
            var nul = null;
            var s1 = Symbol();
    
            console.log(typeof bool); //boolean
            console.log(typeof num);//number
            console.log(typeof str);//string
            console.log(typeof und);//undefined
            console.log(typeof nul);//object
            console.log(typeof s1); //symbol
        </script>
    </body>
    </html>
    
  2. instanceof

    instanceof不能识别出基本的数据类型 number、boolean、string、undefined、null、symbol。

    但是可以检测出引用类型,如array、object、function,同时对于是使用new声明的类型,它还可以检测出多层继承关系。

    其实也很好理解,js的继承都是采用原型链来继承的。比如Dog instanceof Animal ,其实就是看objA的原型链上是否有A的原型,而A的原型上保留A的constructor属性。

    所以instanceof一般用来检测对象类型,以及继承关系.

    <!DOCTYPE html>
    <html lang="en">
            <head>
                <meta charset="UTF-8">
                <title>Title</title>
            </head>
            <body>
                <script>
                    var bool = true;
                    var num = 1;
                    var str = 'abc';
                    var und= undefined;
                    var nul = null;
                    var s1 = Symbol();
    
                    console.log(bool instanceof Boolean);// false
                    console.log(num instanceof Number);// false
                    console.log(str instanceof String);// false
                    console.log(und instanceof Object);// false
                    console.log(nul instanceof Object);// false
                    console.log(s1 instanceof Symbol);// false
                </script>
            </body>
    </html>
    
  3. constructor

    null、undefined没有construstor方法,因此constructor不能判断undefined和null。

    <!DOCTYPE html>
    <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script>
                  var bool = true;
                  var num = 1;
                  var str = 'abc';
                  var und= undefined;
                  var nul = null;
                  var s1 = Symbol();
    
                  console.log(bool.constructor === Boolean);// true
                  console.log(num.constructor === Number);// true
                  console.log(str.constructor === String);// true
                  console.log(s1.constructor === Symbol);//true
              </script>
          </body>
    </html>
    
  4. toString

    此方法可以相对较全的判断js的数据类型。

    <!DOCTYPE html>
    <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script>
                  var bool = true;
                  var num = 1;
                  var str = 'abc';
                  var und= undefined;
                  var nul = null;
                  var s1 = Symbol();
    
                  console.log(Object.prototype.toString.call(bool));//[object Boolean]
                  console.log(Object.prototype.toString.call(num));//[object Number]
                  console.log(Object.prototype.toString.call(str));//[object String]
                  console.log(Object.prototype.toString.call(und));//[object Undefined]
                  console.log(Object.prototype.toString.call(nul));//[object Null]
                  console.log(Object.prototype.toString.call(s1)); //[object Symbol]
              </script>
          </body>
    </html>
    
  5. 总结:至于在项目中使用哪个判断,还是要看使用场景,具体的选择,一般基本的类型可以选择typeof,引用类型可以使用instanceof。

9. JavaScript数据类型转换

  1. Number方法

    Number()方法 将其他类型转换成number类型 Number方法会返回一个转换后的值

    <!DOCTYPE html>
    <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script>
                  // 1、Number转  数字转数字  还是原来的值
                  console.log(Number(666));
                  // 2、字符串转数字
                  console.log(Number(""));//0 空字符串-->0
                  console.log(Number("   "));//0 都是空格的字符串-->0
                  console.log(Number("123"));//0 纯数字的字符串-->相对应的数字
                  console.log(Number("1a23"));//0 非纯数字的字符串-->NaN
    
                  //3、布尔值转数字
                  console.log(Number(true));//1  true-->1
                  console.log(Number(false));//0  false-->0
    
                  // 4、undefined转数字
                  console.log(Number(undefined));//NaN  undefined-->NaN
    
                  // 5、null转数字
                  console.log(Number(null));// 0   null--->0
              </script>
          </body>
    </html>
    
  2. parseInt

    parseInt是一个全局方法,它可以把值转换为整数

    • 第1步,先解析位置0处的字符,如果不是有效数字,则直接返回 NaN。
    • 第2步,如果位置0处的字符是数字,或者可以转换为有效数字,则继续解析位置1处的字符,如果不是有效数字,则直接返回位置0处的有效数字。
    • 第3步,以此类推,按从左到右的顺序,逐个分析每个字符,直到发现非数字字符为止。
    • 第4步,parseInt()将把前面分析合法的数字字符全部转换为数值并返回。
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
        </head>
        <body>
            <script>
                console.log(parseInt(123));//123
                console.log(parseInt("a123"));//NaN
                console.log(parseInt("1a123"));//1
                console.log(parseInt("10a23"));//10
                console.log(parseInt("100px"));//100
                console.log(parseInt(12.3));//12
                console.log(parseInt(null));//NaN
                console.log(parseInt(true));//NaN
            </script>
        </body>
    </html>
    
  3. parseFloat

    parseFloat()也是一个全局方法,它可以把值转换成浮点数,即它能够识别第一个出现的小数点,而第二个小数点视为非法。解析过程和parseInt相同。

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
        </head>
        <body>
            <script>
                console.log(parseFloat(123));//123
                console.log(parseFloat(12.3));//12.3
                console.log(parseFloat("12.3.3"));//12.3
                console.log(parseFloat("a12.1"));//NaN
            </script>
        </body>
    </html>
    
  4. 运算符转换

    如果变量乘以1,则变量会被JS自动转换成数值,如果无法转换成合法数值,则返回NaN

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
        </head>
        <body>
            <script>
                /*如果说变量乘以1  变量就会被自动隐式转换为数字类型,如果转不了就变成NaN*/
                var a = "1";
                console.log(a * 1);//number类型的  1
                var b = "1a";
                console.log(b * 1);//NaN
    
                /*减法也可以*/
                var c = "1";
                console.log(c - 0);//number类型的  1
                var d = "1a";
                console.log(d - 0);//NaN
    
                /*除1也可以*/
                var e = "1";
                console.log(e / 1);//number类型的  1
                var f = "1a";
                console.log(f / 1);//NaN
            </script>
        </body>
    </html>
    

10. JavaScript运算符

JS中为我们定义了一套对数据进行运算的运算符,共定义了47个运算符。

1. 算数运算符

09

说明:

  • 递增(++)和递减(--)运算就是通过不断地加1或减1,然后把结果赋值给左侧,以实现改变自身结果的一种简洁方法

  • 递增和递减在运算之前都会试图转换值为数值类型,如果失败则返回 NaN。

  • 根据位置不同,可以分为4种运算方式

    • 前置递增(++n):先加一,再赋值
    • 前置递减(--n):先减一,再赋值
    • 后置递增(n++):先赋值,再加一
    • 后置递减(n--):先赋值,再减一
  • 一元运算符:一个操作数 ++ --

    前++(--)或者后++(--)都是自身+1(-1)再给自身赋值

    对于a,前++(--)和后++(--)都是自身+1(-1)再赋值给自己

    对于b,前++(--),a先+1(-1)赋值给自己后再参与后面的计算。后++(--),要看后面的算式是否再次用到a,如果用到,才把之前的后++(--)算上。

<!DOCTYPE html>
<html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
      </head>
      <body>
          <script>
              // 无论是  ++a;  还是 a++;  都是让 a每次加1,如果两个代码都是独立运行,那么两个代码没有区别
              var a = 1;
              a ++;//a++是让a  每次加1
              a ++;//a++是让a  每次加1
              a ++;//a++是让a  每次加1
              console.log(a);

              var b = 1;
              ++ b;//让b每次加1
              ++ b;//让b每次加1
              ++ b;//让b每次加1
              ++ b;//让b每次加1
              console.log(b);

              //c++不是单独运行的时候,也就是有赋值操作的时候,那么是先执行赋值,然后再去加1
              //c++ 就是先赋值 后加1
              var c = 2;
              var d = c ++;
              console.log(c);
              console.log(d);

              //++c  先加一 后赋值
              var c = 2;
              var d = ++ c;
              console.log(c);
              console.log(d);
          </script>
      </body>
</html>

练习:

  1. var a = 1;
    var b = ++a;
    console.log(a);
    console.log(b);
    
  2. var a = 1;
    var b = a++;
    console.log(a);
    console.log(b);
    
  3. var a = 1;
    var b = ++a + a;
    console.log(a);
    console.log(b);
    
  4. var a = 1;
    var b = ++a + ++a + a;
    console.log(a);
    console.log(b);
    
  5. var a = 1;
    var b = a + ++a + 1 + a + ++a;
    console.log(a); 
    console.log(b); 
    
  6. var a = 1;
    var b = a + a + ++a + 1 + a + ++a
    console.log(a);
    console.log(b);
    
  7. var a = 1;
    var b = a++ + 1 + a++;
    console.log(a);
    console.log(b);
    
  8. var a = 1;
    var b = a++ + a++ + a + 1 + a++ + 1;
    console.log(a);
    console.log(b);
    
  9. var a = 1;
    var b = a++ + ++a + a + a++;
    console.log(a);
    console.log(b);
    
  10. var b = ++a + a++ + a++ + a + ++a + a++ + a;
    console.log(a);
    console.log(b);
    

  1. <!DOCTYPE html>
    <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script>
                  var a = 1;
                  b = a++ + (a++) + 1 + (++a) + (a++) + (++a) + a + (++a);
                  console.log(a);
                  console.log(b);
              </script>
          </body>
    </html>
    
#### 2. 赋值运算符

![10](.\img\10.png)

#### 3. 字符串运算符

+ 运算符也可用于对字符串进行相加(concatenate,级联)。

```html
a = "hello";
b = "red romance";
c = a + " " + b; 
  • += 赋值运算符也可用于相加(级联)字符串:

    a = "ok ";
    a += "three man! go go go"; 
    
  • 相加两个数字,将返回和,但对一个数字和一个字符串相加将返回一个字符串:

    x = 7 + 8;
    y = "7" + 8;
    z = "Hello" + 7;
    

4. 比较运算符

11

5. 逻辑运算符

&& 当多个条件时,必须所有条件都是true,整个结果才是true,只要有一个条件时false,整个结果就是false

|| 当多个条件时,只要有一个条件是true,整个结构就是true,只有所有条件都是false时,整个结果才是false

! 取反

12

6. 逗号运算符

逗号运算符是二元运算符,它能够先执行运算符左侧的操作数,然后再执行右侧的操作数,最后返回右侧操作数的值。

var a = 1,b = 2,c = 3,d = 4;

等价于

var a = 1;
var b = 2;
var c = 3;
var d = 4;

练习:观察结果

a = (b = 1,c = 2);
console.log(a);
console.log(b); 
console.log(c); 

a = b = 1,c = 2;
console.log(a);  
console.log(b);  
console.log(c);  

7. 特殊情况:比较不同的类型

如果将字符串与数字进行比较,那么在做比较时 JavaScript 会把字符串转换为数值。空字符串将被转换为 0。非数值字符串将被转换为始终为 false 的 NaN。

13

8. 案例练习

  • 优先级

17

  • 任意数据类型和NaN做数学运算,结果都是NaN,但是注意只要是字符串在和任意数据类型做相加+的运算,都是字符串拼接。
    字符串类型的数据:在进行数学运算(- * / %)时,会先将自身隐式转换(Number)成数值类型再进行计算
    在进行+操作时,是字符串的拼接

    console.log('2' - '1');
    console.log('2' - 1);
    console.log('2' * 1);
    console.log('2' / 3);
    猜测一下取余结果的符号和除数,被除数哪个有关?
    console.log('2' % 3);
    console.log('2' + '1');
    console.log('1' + 3);
    console.log('2' - '嘿嘿');
    console.log('1' - '2abc');
    console.log('嘿嘿' + '1a'); 
    console.log('嘿嘿' + NaN);
    console.log('嘿嘿' + 5 * '6'); 
    console.log(('嘿嘿' + 5) * '6'); 
    
  • 布尔类型的数据:在进行数学运算(+ - * / %)时,会先将自身隐式转换(Number)成数值类型再进行计算

    console.log(true + true); 
    console.log(true + 5); 
    console.log(true + '8'); 
    console.log(true - '8');
    console.log(false - 3);
    console.log(false - 3 * '哈哈');
    
  • 未定义类型的数据:在进行数学运算(+ - * / %)时,会先将自身隐式转换(Number)成数值类型再进行计算

    console.log(undefined + undefined);
    console.log(undefined + 1);
    console.log(undefined + '5' + '哈哈');
    
  • 空类型的数据:在进行数学运算(+ - * / %)时,会先将自身隐式转换(Number)成数值 类型再进行计算

    console.log(null + true); 
    console.log(null + 5);
    console.log('null' + (null - 3) + undefined);
    
  • 任意数据类型在进行关系运算时,会先将自身隐式转换(Number)成数值,在进行比较字符串与字符串之间的比较< > <= >=,比较的是ascii码,一位一位的去比

    console.log(5 > 3);
    console.log(5 > '3');
    console.log('5' < true);
    console.log(5 > '6哈哈');
    console.log('a' < 'ab');
    console.log('ac' > 'ab');
    console.log('ab' < 'bz');
    // console.log(NaN < NaN)
    console.log('100' < 'a');
    console.log('5' == 5);
    console.log(1 == true);
    console.log(1 === true);
    console.log(0 == false);
    console.log(null < 1);
    
    //特殊的
    console.log(null == 0);
    console.log(null == ' ');
    console.log(null == '');
    console.log(null == false);
    console.log(null == undefined);
    
  • 练习题

    console.log(undefined + null * '-10' + 100 > 90); 
    
    console.log(null * undefined + null + '嘿嘿');
    
    console.log(true + 'undefined' - undefined + '5');
    
    console.log((5 + true > true) + 5 > true);
    
    console.log(!true - '5' + 8 + parseInt('4嘿嘿'));
    
    console.log((!false - !null) * parseInt('3.14') + '');
    
  • 规则: 数学运算转Number, 字符串与任意类型数据相加都是拼接

    ​ 关系运算转Number,字符串与字符串转Ascii码

    ​ 逻辑运算转Boolean

    短路表达式:

    ​ && 与 如果前面的表达式结果是true,返回的是后面表达式的数据,如果前面的表达式结果是false,直接返回数据

    ​ || 或 如果前面的表达式是ture,直接返回数据,如果前面的表达式是false,返回的是后面表达式的数据

    ​ ! 取反

    console.log(5 > 3 && 5 > 4);
    var a = 5 > 3 && 5 > 4 && 5 > 6;
    console.log(a);
    console.log(5 > 3 && 5 < 4 && 5 > 6);
    console.log(5 > 3 || 5 > 6);
    console.log(5 < 3 || 5 < 6 || 5 < 8);
    console.log(5 && 8);
    console.log(Boolean(5) && Boolean(8));
    console.log(null && '红浪漫');
    console.log(5 + 3 && 5 + 4);
    console.log(true == 5 > 3);
    console.log('' && NaN);
    console.log(' ' && NaN);
    console.log('红浪漫' && 10 + false && '张三');
    
    console.log(' ' && 10 + '红浪漫' && 5 > null);
    
    console.log(' ' && 10 - '红浪漫' && 1.3245644564464 + 2.14335334533553 + 32.433433533535);
    
    console.log(5 || 3);
    
    console.log(' ' || 10 + '红浪漫' || 5 > null);
    
    console.log('' || 10 - '红浪漫' || 5 > null);
    
    var b;
    console.log(5 - undefined || 10 + undefined * null || 5 * b);
    
    console.log(!(5 > 3));
    console.log(!5);
    console.log(!'哈哈');
    console.log(!undefined);
    console.log(!5 > 3);
    
    console.log(!'' + 5 + !null); 
    
    console.log(5 || 3 && '哈哈');
    console.log((5 || 3) && '哈哈');
    
    var f;
    console.log(!'红浪漫' + NaN || !10 + null * '5' && '8' * !f);
    
    console.log(' ' + true && !('红浪漫' - 8) || ' ' - 1 && !undefined + null); 
    
    console.log(!Number(' ') + true && Boolean('红浪漫') - 8 || ' ' - 1 && !undefined+ !(5+ 3));
    
    
posted on 2021-04-17 11:41  文种玉  阅读(91)  评论(0编辑  收藏  举报