JavaScript基础篇
一. 简介
1.1.定义
javascript是一门动态弱类型的解释型编程语言,增强页面动态效果,实现页面与用户之间的实时动态的交互。
js语言分为三个部分,具体细化为三大对象
js本地对象 : 基于js的核心语法(ECMAScript)
ECMAScript => European Computer Manufacturers Association 欧洲计算机制造商协会
js的DOM对象 : 基于文档对象模型 (控制html,css) document object model
js的BOM对象 : 基于浏览器对象模型 (控制浏览器) browser object model
1.2.注释
JavaScript中代码注释:
- 单行: //
- 多行 : /* */
1.3 引入文件
1. 引入外部文件
<script type="text/javascript" src="JS文件"></script>
2. 存放在HTML的<head>或<body>中
<script> // alert("js的第一种引入方式") // 浏览器弹出 // console.log("js的第一种引入方式") // 控制台打印 // document.write("js的第一种引入方式") // 页面显示 </script>
3. 第三种引入方式 事件
<div onclick="alert('hello world')"> 点我 </div>
4. 第四种引入方式 行内 (不推荐)
<a href="javascript:alert('hello world2')">点我</a>
二 变量
需要注意的是:局部变量必须以 var 开头申明,如果不写 var 则为全局变量
<script type="text/javascript"> // 全局变量 name = 'nick'; function func(){ // 局部变量 var age = 18; // 全局变量 gender = "man" } </script>
注:需要注意变量提升,就是把变量位置放到函数体的最上方
三 、数据类型
数据类型:分为两大类
基本数据类型(原始类型) + 引用数据类型(复杂类型)
- 基本数据类型: Boolean , Number , String , null , undefined
- 引用数据类型: Object [Array , function , Date , RegExp]
本质上一切皆是对象
3.1 Boolean 布尔类型
var a = true var a = false console.log(a,typeof(a))
3.2 Number数字类型
var a = 0b10 var a = 0o10 var a = 0x10 var a = 100 var a = 3.15 var a = 3.15e3 // Infinity 无限大 var a = 3.9e99999999999999999999999999999999999999999999999999 // -Infinity 负无限大 var a = -3.9e99999999999999999999999999999999999999999999999999 console.log(a,typeof(a))
NaN Number类型中特殊的关键字 => not a number
NaN注意点:
1.NaN 和 数字不能参与运算
2.除了NaN!=任何值为真,剩下的比较都是假的
var a = 100 - "abc" var a = NaN + 1 var a = NaN == NaN var a = NaN != NaN var a = NaN != 1 console.log(a,typeof(a))
3.3 .字符串类型
// 1.单引号 var a = 'hello js' console.log(a , typeof(a)) // 2.双引号 var a = "hello \\n js" console.log(a , typeof(a)) // 3.反引号 (1.支持跨行 2.解析变量) // `${变量名}` 解析变量语法 var name = "安妮宝贝" var str = `你在么${name} 你在干什么 想我了没有 ` console.log(str, typeof(str))
3.4 Object 对象类型
3.4 .1字典
(1)、定义空对象(对象)
var obj = {}
(2)js对象(字典)
var obj = {"a":1,"b":2,"c":3}
(3)添加/修改对象
obj["a"] = 100 obj["d"] = 300 console.log(obj,typeof(obj)) console.log(obj instanceof Object)
3.4.2 [数组]
(1)定义空对象(数组)
var arr = []
(2)js对象(数组)
var arr = [1,2,3,4]
(3)添加/修改对象
arr[0] = 100 arr[4] = 3000 console.log(arr,typeof(arr)) console.log(arr[6]) console.log(arr instanceof Array , 333)
3.4.3 [function函数]
function func(){ console.log("func ... ") } func() console.log(func instanceof (Array,Number,Function) , 333444)
3.5 特别的关键字 null , undefined
// null 空(等价python中的None) var a = null; console.log(a ,typeof(a)); // undefined 未定义的 var b; var b = undefined ; console.log(b, typeof(b)) ;
四、强制转换
4.1 Number(parseInt parseFloat Number)
// 1.强转整型:parseInt 数字开头即可转换 , 布尔型转换不了 var n = 1234 var n = "ppppp" // NaN var n = "9999" // 9999 var n = "99pppp" // 99 var n = "pp12" // NaN var n = "109.34" // 109 var n = "109.123asdfasd2" // 109 var n = "asdfasd2109.123" // NaN var n = [] // NaN var n = {} // NaN var n = true // NaN var res = parseInt(n) console.log(res,typeof(res)) // 2.强转浮点型:parseFloat 数字开头即可转换 , 布尔型转换不了,可保留小数 var n = 1234 // 1234 var n = "ppppp" // NaN var n = "9999" // 9999 var n = "99pppp" // 99 var n = "pp12" // NaN var n = "109.34" // 109.34 var n = "109.123asdfasd2" // 109.123 var n = "asdfasd2109.123" // NaN var n = [] // NaN var n = {} // NaN var n = true // NaN var res = parseFloat(n) console.log(res,typeof(res)) // 3.Number 类型转换 可以转换布尔类型,也可以转换纯数字字符串 var n = false // 0 var n = true // 1 var n = "123" // 123 var n = "123.123" // 123.123 var n = "123sdf" // NaN var res = Number(n) console.log(res,typeof(res))
4.2 强制转换 - String
// 单纯的在数据两边套引号,表达字符串 var str = 1000; var str = 3.434 var str = [] var str = {} var str = undefined var str = null var str = NaN var res = String(str) console.log(res , typeof(res))
4.3 强制转换 - Boolean
// 布尔值为假的7种情况 var a = 0; var a = 0.0 var a = '' var a = false; var a = null; var a = NaN var a = undefined // 注意点 var a = [] // 真的 var a = {} // 真的 var res = Boolean(a) console.log(res , typeof(res))
五、自动类型转换
Number Boolean String 三者之间的转化
// 1. Number + Boolean var res = 10 + true //11 "number" var res = 19.76 + true //20.76 "number" var res = 10 + 3.4 // 13.4 "number" console.log(res , typeof(res)) // 2.Number + Boolean + String // 对于字符串的自动转换,+号的作用是拼接 var res = true + "122" // true122 string var res = 100 + "199" // 100199 string var res = 33 + 44 + "10" // 7710 string var res = 33+ "11" + 88 // 331188 string console.log(res , typeof(res)) //3.除了+号,其他的符号都可以参与运算 var res = 100 - "199" // -99 "number" var res = 100 / false // Infinity "number" var res = 3 * "5" // 15 "number" var res = 3 * "abc" // NaN console.log(res ,typeof(res))
六、运算符
// (1) ++ -- 递增 递减 // num++ 先赋值在自增 var num = 10 var res = num++; console.log(res,num) // ++num 先自增在赋值 var num = 10 var res = ++num console.log(res,num) // num-- 先赋值在自减 var num = 10 var res = num-- console.log(res,num) // ++num 先自减在赋值 var num = 10 var res = --num console.log(res,num) // (2) === !== (全等于,不全等于) 严格比较两样东西: (1) 比较值的大小 (2)比较值的类型 var res = "1" === 1 var res = "1" !== 1 console.log(res) // (3) && => and || => or ! => not var num = 10 if(3<num && num < 5){ console.log("ok1") } if(num < 3 || num >= 10){ console.log("ok2") } var num = 0 if(!num){ console.log("ok3") } // (4) 三元(目)运算符 ?: // var res = 表达式?真值:假值 var age = 18; var res = age >= 18?"成年人":"青少年" console.log(res,typeof(res))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1> 如果两个值类型不同则返回false 2> 如果两个值类型相同,值相同,则返回true,否则返回false 3> 如果两个值引用同一个对象,则返回true,否则,返回false console.log([] === []);//false console.log({} === {});//false var a = {}; b = a; console.log(a === b);//true
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
对象类型和原始类型比较: 1> 对象类型会先使用valueOf()转换成原始值,如果结果还不是原始值,则再使用toString()方法转换,再进行比较(日期类只允许使用toString()方法转换为字符串) 2> 在对象转换为原始值之后,如果两个操作数都是字符串,则进行字符串的比较 3> 在对象转换为原始值之后,如果至少有一个操作数不是字符串,则两个操作数都将通过Number()转型函数转换成数字进行数值比较 注:如果一个值是null,另一个值是undefined,则返回true; console.log(null == undefined);//true 如果一个值是null,另一个值是0,则返回tfalse; console.log(null == 0);//false 空字符串或空格字符串会转成0 console.log(null == []);//false console.log(null == '');//false console.log([] == ' ');//false,相当于'' == ' ' console.log([] == '');//true,相当于'' == '' console.log(0 == '');//true
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
数字和字符串比较: 1> 如果操作值是对象,则这个对象将先使用valueOf()转换成原始值,如果结果还不是原始值,则再使用toString()方法转换 2> 在对象转换为原始值之后,如果两个操作数都是字符串,则按照unicode字符的索引顺序对两个字符串进行比较 3> 在对象转换为原始值之后,如果至少有一个操作数不是字符串,则两个操作数都转换成数字进行比较 console.log('B' > 'a');//false console.log('b' > 'a');//true console.log(9 > '2');//true
七、数据类型的创建时的注意事项
var x1 = new Object(); // 一个新的 Object 对象 var x2 = new String("abcd"); // 一个新的 String 对象 var x3 = new Number(); // 一个新的 Number 对象 var x4 = new Boolean(); // 一个新的 Boolean 对象 var x5 = new Array(); // 一个新的 Array 对象 var x6 = new RegExp(); // 一个新的 RegExp 对象 var x7 = new Function(); // 一个新的 Function 对象 var x8 = new Date(); // 一个新的 Date 对象 console.log(x1,typeof(x1)) console.log(x2,typeof(x2)) // object var ceshi = "abcd" // string // 比较值的大小 var res = ceshi == x2 // 严格比较 : 1.大小 2.类型 var res = ceshi === x2 console.log(res) // 推荐使用后者,速度更快,不会出现逻辑错乱 (推荐) var x1 = {}; // 新对象 var x2 = "abcd"; // 新的原始字符串 var x3 = 0; // 新的原始数值 var x4 = false; // 新的原始逻辑值 var x5 = []; // 新的数组对象 var x6 = /()/ // 新的正则表达式对象 var x7 = function(){}; // 新的函数对象 var ceshi = "abcd" var res = ceshi == x2 var res = ceshi === x2 console.log(res)
八、流程控制
8. 1、条件语句
8.1.1 if 语句
var wangyongjuan = "富婆"; // 1.单项分支 if(wangyongjuan == "富婆"){ console.log("意味着捐很多钱") } // 2.双向分支 var wangyongjuan = "清纯的小女生"; if(wangyongjuan == "富婆"){ console.log("意味着捐很多钱") }else{ console.log("被捐很多钱") } // 3.多项分支 var age = 1 if(0 < age && age < 10){ console.log("儿童时代") }else if(10 <= age && age < 18){ console.log("青少年时代") }else if(18<=age && age < 40){ console.log("壮年时代") }else if(40 <= age && age < 90){ console.log("广场舞时代") }else{ console.log("入土时代") } // 4.巢状分支 var youfang = true; var youche = true; if(youfang){ if(youche){ console.log("富婆,老子要嫁给你~") }
8.1.2、 Switch 语句
// 获取星期几 var date = new Date() console.log(date) var res = date.getDay() console.log(res , typeof(res)) res = "1" // switch 属于严格类型比较: (1)大小 (2) 类型 switch(res){ case 1 : console.log("星期一") case 2: console.log("星期二") break; case 3: console.log("星期三") break; case 4: console.log("星期四") break; case 5: console.log("星期五") break; case 6: console.log("星期六") break; default: console.log("星期日") break; }
8.2 循环结构
JavaScript中支持四种循环语句,分别是:for、for in、while、do-while 、for-of
8.2.1 for 循环
for(var i = 1;i<=100;i++){ console.log(i) } // 跳过55 for(var i = 1;i<=100;i++){ if(i == 55){ continue; } console.log(i) }
8.2.2 while 循环
var i = 10 while(i <=20){ if(i == 18){ break; } console.log(i) i++
}
8.2.3 for in 循环
// ###3.for(var i in Iterable){} 作用: 遍历数据 // arr : 默认获取的是索引 var arr = ["耿择时","家营和","孙翔宇","张银","王生父"] for(var i in arr){ console.log(i) console.log(arr[i]) } console.log("<===========3===========>") // obj : 默认获取是键 var obj = {"gzs":"耿择时","jyh":"家营和","sxy":"孙翔宇"} for(var i in obj){ console.log(i) console.log(obj[i]) }
8.2.4 for of 循环
// ###4.for(var i of Iterable){} 作用: 遍历数据 // arr : 默认获取的是数组中的值 var arr = ["耿择时","家营和","孙翔宇","张银","王生父"] for(var i of arr){ console.log(i) } // obj for(var i of Iterable)无法对obj进行遍历 error // var obj = {"gzs":"耿择时","jyh":"家营和","sxy":"孙翔宇"} // for(var i of obj){ // console.log(i) // } // var i of/in Iterable 都可以处理数组和字符串 for(var i of "abcdefg"){ console.log(i) }
九、函数Function
9.1 函数定义
// ### 一函数 // ### 1. 普通函数 // 方式一 存在预加载机制,提前把函数加载到内存中,在运行代码 func1() function func1(){ console.log("我是func1") } // 方式二 匿名函数 (匿名函数没有预加载机制,必须先定义在调用) var func2 = function(){ console.log("我是func2") } func2() // 方式三 不推荐 (必须先定义在调用) // var func3 = new Function("alert(1213);document.write(1234);console.log(55667)"); // console.log(func3,typeof(func3)); // func3() // 方式四 箭头函数 (ES6新增了解) function ceshi(x,y){ return x+y } var res = ceshi(1,2) console.log(res) var ceshi = (x,y) => {return x+y;} console.log(ceshi(3,9)) // 方式五 闭包函数 function outer(){ var father = "王健林" function inner(){ // console.log("你的爸爸是",father) console.log(`你的爸爸是${father}`) } return inner } var func = outer() func() // inner
9.2 函数参数
函数传参的个数可以小于实际需传参的个数,没传参的默认为undefined
参数传多默认不起作用
function man(name,age) { console.log(name,age); } man("nick",18); //nick 18 man("nick"); //nick undefined man("nick",18,19); //nick 18
arguments 可接收所有参数,返回一个数组
function man() { console.log(arguments); } man("nick",18); //["nick", 18] man("nick"); //["nick"] man("nick",18,19); //["nick", 18, 19]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// ###二 函数的参数 // 注意点: js中的函数不能像python,函数名可以作为第一类对象使用; // 1.不会报错,区分与python function func_new1(a,b,c){ console.log(a,b,c) } // func_new(1,2,3) func_new1() console.log(111) // 2.不会报错,区分与python function func_new2(){ } func_new2(1,2,3,4) // js中的 形参/实参: /* 形参:(1) 普通形参(位置) (2) 默认形参 实参:普通实参(位置) */ function func_new22(a,b=10){ console.log(a,b,"<====3333==>") } func_new22(bb="sdf",cc="sfdsf") // 关键字参数无效 // arguments 计算累加和 function func_new3(){ // js中arguments 相当于 python的*args收集参数 ,打包成可迭代对象 console.log(arguments) var total = 0 for(var i of arguments){ console.log(i) total += i } return total } var res = func_new3(1,2,3,5,6,7) console.log(res)
9.3 函数的调用
function func(){ console.log("函数在运行1...") } // 1.正常调用 func(); // 2.函数立即执行 (普通函数) (function func(){ console.log("函数在运行2...") })(); // 3.函数立即执行 (匿名函数) (function(){ console.log("函数在运行3...") })(); // 4.函数立即执行 !function(){ console.log("函数在运行4...") }(); ~function(){ console.log("函数在运行5...") }(); +function(){ console.log("函数在运行6...") }(); -function(){ console.log("函数在运行7...") }();
9.3 函数的作用域与作用域链
引用:
https://blog.csdn.net/yueguanghaidao/article/details/9568071
Javascript压根没有块级作用域,而是函数作用域.
所谓函数作用域就是说:-》变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。
var name = 'nick'; (function Main(){ console.log(name);//undefined if(1){ var name = 'jenny'; } console.log(name);//jenny })(); console.log(name);//nick //输出结果第一个为undefined //声明需提前(Hoisting),在JavaScript引擎“预编译”时进行,函数在被执行之前,会将其中的变量全部声明,而不赋值
作用域链
每个构造函数都有一个内部对象指针,指向原型对象,而原型对象也包含一个指向构造函数的指针。如此层层递进,形成作用域链条
var name = 'nick'; function Main() { function F1(){ var name = 'jenny'; console.log(name);//jenny } function F2() { console.log(name);//nick } F1(); F2(); } Main(); // 从内到外的优先级寻找 // F2() 的作用域链为 F2()-->Main()
当F1执行时,将创建函数F1的执行环境(调用对象),并将该对象置于链表开头,然后将函数Main的调用对象链接在之后,最后是全局对象。然后从链表开头寻找变量name,很明显
name是"jenny"。
但执行F2()时,作用域链是: F2()->Main()->window,所以name是”nick"
下面看一个很容易犯错的例子:
<html> <head> <script type="text/javascript"> function buttonInit(){ for(var i=1;i<4;i++){ var b=document.getElementById("button"+i); b.addEventListener("click",function(){ alert("Button"+i);},false); } } window.οnlοad=buttonInit; </script> </head> <body> <button id="button1">Button1</button> <button id="button2">Button2</button> <button id="button3">Button3</button> </body> </html>
当文档加载完毕,给几个按钮注册点击事件,当我们点击按钮时,会弹出什么提示框呢?
很容易犯错,对是的,三个按钮都是弹出:"Button4",你答对了吗?
当注册事件结束后,i的值为4,当点击按钮时,事件函数即function(){ alert("Button"+i);}这个匿名函数中没有i,根据作用域链,所以到buttonInit函数中找,此时i的值为4,
所以弹出”button4“。