1.什么是JavaScript
1.1概述
JavaScript简称JS,是一种具有函数优先的轻量级、解释型或即时编译型的编程语言。
是一门世界上最流行的脚本语言。
一个合格的后端人员,必须精通JavaScript。
1.2历史
https://blog.youkuaiyun.com/kese7952/article/details/79357868
ECMAScript它可以理解为是JavaScript的一个标准
最新版本已经到ES6,但是大部分浏览器还只停留在支持ES5代码上。存在开发环境—-线上环境,版本不一致的问题
2.快速入门
2.1引入JavaScript
-
内部标签
<script> alert("hello")</script>
-
外部引入
<script src="js/js.js"></script>
-
测试代码
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><!--第一种方式,内部引用 --><script> /** * script标签内写JavaScript代码,script标签必须成对出现。 */ alert("hello")</script><!--第二种方式,外部引用--><script src="js/js.js"></script></body></html>
2.2浏览器控制台调试
在页面上可以按F12调出控制台,可以在这里输出当前页面的变量值(或者写脚本),非常方便。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5c1YgY8B-1658538220645)(E:/Typora/Typroa/kuangstudyb1e7c268-cdb2-42bf-ae16-04c5768e6db2.png)]
2.3.数据类型
2.3.1快速入门
-
因为JS是弱语言,里面不用声明类型。
-
统一用
var
来声明变量 -
在ES6新增加了
let
和const
来声明变量。 -
测试代码:
<!--JavaScript严格区分大小写!--> <script> // 1. 定义变量 变量类型 变量名 = 变量值; // 注:在JavaScript中不存在变量类型,一切的变量都叫var,对于var并没有一个固定的变量类型的限制 var score = 71;// 此时score就是一个数字类型的变量 var name='qqqdweob';// 此时name就是一个字符串类型的变量 // alert(score); // 2. 条件控制 if (score>60 && score<70){ alert("60~70") }else if(score>70 && score<80){ alert("70~80") }else{ alert("other") } </script>
2.3.2Number
JavaScript不区分浮点数和整数,统一用Number表示,以下都是合法的Number类型:
//--- numbervar a = 1;a = 123//整数a = 123.1//浮点数a = -99//负数a = NaN//not a number,当无法计算结果时用NaN表示a = 1.2345e3//科学计数法表示1.2345X1000,等同于1234.5InFinity//InFinity表示无限大,当数值超过了JavaScript的Number能表示的最大值时表示为InFinity
2.3.3字符串
//--- 字符串var b = "abc";b = 'cba';
2.3.4布尔值
一个布尔值只有true、false两种值,要么是true,要么是false,可以直接用true、false表示布尔值,也可以通过布尔运算计算出来:
//--- 布尔值var c = true;c = false;true; // 这是一个true值 false; // 这是一个false值 2 > 1; // 这是一个true值 2 >= 3; // 这是一个false值
2.3.5运算符
- 逻辑运算符
//--- 逻辑运算符&& //两个都为真,结果为真|| //一个为真,结果为真! //真即假,假即真
-
比较运算符
//--- 比较运算符= //赋值运算法== //等于(类型不一致,值一样,也会判断为true 即判断1=='1')=== //绝对等于(类型一样,值一样,结果为true)
当我们对Number做比较时,可以通过比较运算符得到一个布尔值:
2 > 5; // false 5 >= 2; // true 7 == 7; // true
实际上,JavaScript允许对任意数据类型做比较:
false == 0; // true false === 0; // false
须知:
-
由于JavaScript的设计缺陷,不要使用比较,始终坚持使用=比较
-
NaN,not a number,当无法计算结果时用NaN表示,与所有的数值都不相等,包括自己
NaN === NaN; //false
-
只能通过isNaN()来判断这个数是不是NaN
2.3.6浮点数问题
(1/3)===(1-2/3) //结果为false
尽量避免使用浮点数进行运算,存在精度问题
Math.abs(1/3-(1-2/3))<0.00000001 //结果为true
2.3.7null和undefined
-
null 空;
它和 0 以及空字符串 “ “ 不同, 0 是一个数值, “ “表示长度为0的字符串,而 null 表示“空”。
-
undefined 未定义
-
大多数情况下,我们都应该用 null 。 undefined 仅仅在判断函数参数是否传递的情况下有用。
2.3.8数组
- Java的数组必须是相同类型的对象。JS中不需要这样!
- 数组是一组按顺序排列的集合,集合的每个值都称为元素。
- JS的数组可以包括任意数据类型。例如:
[1, 2, 3.14, 'Hello', null, true];
上述数组包含6个元素。数组用 [] 表示,元素之间用 , 分隔。
- 数组的元素可以通过索引来访问。请注意,索引的起始值为 0 :
var arr = [1, 2, 3.14, 'Hello', null, true]; arr[0]; // 返回索引为0的元素,即1 arr[5]; // 返回索引为5的元素,即true arr[6]; // 索引超出了范围,返回undefined
- 在浏览器的控制台打印,取数组下标:如果越界了,就会undefined——未定义
2.3.9对象
- 对象是大括号,数组是中括号
- 每一个属性之间使用逗号隔开,最后一个不需要加逗号
- JavaScript的对象是一组由键-值对组成的无序集合,例如:
var person = { name: 'Bob', age: 20, tags: ['js', 'web', 'mobile'], city: 'Beijing', hasCar: true, zipcode: null };
- JS对象的键都是字符串类型,值可以是任意数据类型。上述 person 对象一共定义了6个键值对,其中每个键又称为对象的属性,例如, person 的 name 属性为 ‘Bob’ , zipcode 属性为 null 。
- 取对象的值,我们用 对象变量.属性名 的方式:
person.name; // 'Bob' person.zipcode; // null
2.3.10变量
-
变量在JS中就是用一个变量名表示
-
变量名是大小写英文、数字、 $ 和 _ 的组合,且不能用数字开头
-
变量名也不能是JS的关键字,如 if 、 while 等
-
申明一个变量用 var 语句,比如:
var a; // 申明了变量a,此时a的值为undefined-未定义var $b = 1; // 申明了变量$b,同时给$b赋值,此时$b的值为1 var s_007 = '007'; // s_007是一个字符串var Answer = true; // Answer是一个布尔值true var t = null; // t的值是null
-
变量名也可以用中文,但是,请不要给自己找麻烦。
-
变量的赋值:
在JS中,使用等号 = 对变量进行赋值。可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量,但是要注意只能用 var 申明一次,例如:
var a = 123; // a的值是整数123 a = 'ABC'; // a变为字符串
-
这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。例如Java是静态语言,赋值语句如下:
int a = 123; // a是整数类型变量,类型用int申明 a = "ABC"; // 错误:不能把字符串赋给整型变量
- 和静态语言相比,动态语言更灵活,就是这个原因。
- 请不要把赋值语句的等号等同于数学的等号。
2.4.严格检查模式
- JS在设计之初,为了方便初学者学习,并不强制要求使用var声明变量,这个设计错误带来的后果是:如果一个变量没有通过var声明就被使用,那么该变量就自动被声明为全局变量。
i=10;//现在是全局变量
- 在同一个页面的不同的JS文件中,如果都不用 var 声明,而恰好都使用了变量 i ,将造成变量 i 互相影响,产生难以调试的错误结果。
- 使用 var 声明的变量则不是全局变量,它的范围被限制在该变量被声明的函数体内,同名变量在不同的函数体内互不冲突。
- 为了修补JS这一严重设计缺陷,ECMA在后续规范中推出了strict模式,在strict模式下运行的JS代码,强制通过 var 声明变量,未使用 var 声明变量就使用的,将导致运行错误。
- 启用strict模式的方法是在JavaScript代码的第一行写上:
'use strict';
-
这是一个字符串,不支持strict模式的浏览器会把它当作一个字符串语句执行,支持strict模式的浏览器将开启strict模式运行JS。
-
调试自己的浏览器是否能支持strict模式:
'use strict';//如果浏览器支持strict模式,下面的代码将报ReferenceError错误;abc='hello world';console.log(abc);
-
运行结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G4rfRC1f-1658538220648)(file:///C:/Users/DELL/AppData/Roaming/Typora/typora-user-images/image-20220105191254451.png)]
-
-
代码部分:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><!--前提:Idea,设置支持ES6语法'use strict';严格检查模式,预防JS随意性导致产生的一些问题必须写在script标签内的第一行!局部变量建议都使用let去定义--><script> 'use strict'; let a = 1;</script></body></html>
3.数据类型
3.1字符串
-
正常字符串我们使用单引号、双引号包裹
console.log('a');console.log("a");
-
注意转义字符 \
'i\'m\"ok\"!';console.log('i\'m\"ok\"!')i'm"ok!
\ '\n 表示换行
\t 表示制表符
字符 \ 本身也要转义,所以 \\ 表示的字符就是 \
'\x41'; // 完全等同于 'A';
ASCII字符可以以 \x## 形式的十六进制表示'\u4e2d\u6587'; // 完全等同于 '中文';以用 \u#### 表示一个Unicode字符
- 多行字符串
//tab上面 esc键下面,此处为反引号
var msg= `hello
world
你好呀
你好ya`
console.log(msg)
helloworld
你好呀
你好ya
-
模板字符串
let name ="zhangsan"; let age =154; let msg =`你好呀,${name}`//此处为反引号 console.log(msg) 你好呀,zhangsan
-
字符串长度
var student="student" console.log(student.length) 7 console.log(student[0]) s
-
字符串的可变性——不可变
var student="student" student[0]=11 console.log(student) student
-
大小写转换
//注意:这里是方法,不是属性了 var student="student" student.toUpperCase() STUDENT student.toLowerCase() student
-
字符串查找
var student="student" console.log(student.indexOf('t')) 1 console.log(student.indexOf('u')) 2
-
截取
var student="student"student.substring(1)//从第一个字符串截取到最后一个字符串tudentstudent.substring(1,3)//下标几到下标几tustudent.substring(0)student
3.2数组
JavaScript的 Array 可以包含任意数据类型,并通过索引来访问每个元素。
var arr=[1,2,3,4,5,6]//通过下标取值和赋值arr[0]1arr[0]=11
-
1.长度
var arr=[1,2,3,4,5,6] arr.length 6
-
注意;假如给iarr.length赋值,数组大小就会发生变化;
如果赋值过小,元素就会丢失
var arr=[1,2,3,4,5,6] arr.length 6 arr.length=10 10 console.log(arr) (10) [1,2,3,4,5,6,empty*4] arr.length=33 console.log(arr)(3)[1,2,3]
-
-
2.获得下标索引——indexOf()
var arr=[1,2,3,"1","3"] arr.indexOf(3) 2 arr.indexOf("3") 4//注意:字符串的"1"和数字的1是不一样的
注意:字符串的"1"和数字的1是不一样的
-
3.数组截取——slice()
截取数组的一部分,返回一个新的数组.类似于string中的substring()
var arr=[1,2,3,4,5,6] arr.slice(3) (3) [4,5,6]
-
4.元素操作
-
对尾部元素的操作
push():压入到尾部;
pop():弹出尾部的一个元素
var arr=[1,2,3,4,5,6] arr.push("a","b")//尾部压入"a","b"数组长度变为8 8 arr(8) [1,2,3,4,5,6,"a","b"] arr.pop()//弹出尾部的一个元素 "b"//弹出"b" arr(7) [1,2,3,4,5,6,"a"]
-
对头部元素进行操作
unshift():压入到头部;
shift():弹出头部的一个元素;
var arr=[1,2,3,4,5,6] arr.unshift("a","b")//"a","b"压入到头部 8 arr(8) ["a","b",1,2,3,4,5,6] arr.shift() "a" arr(7) ["b",1,2,3,4,5,6]
-
-
5.排序 ——sort()
var arr=["c","b","a"] arr.sort() (3) ["a","b","c"]
-
6.元素反转——reverse()
var arr=["a","b","d"] arr.reverse() (3) ["d","b","a"]
-
7.concat():把当前的数组和另一个数组连接起来,并返回一个新的数组
var arr = ['A', 'B', 'C']; arr.concat([1, 2, 3]); (6) ['A', 'B', 'C', 1, 2, 3]//注意:concat()并没有修改当前数组,只是返回了一个新的数组 console.log(arr) (3) ['A', 'B', 'C']
-
8.连接符join()——把当前 Array 的每个元素都用指定的字符串连接起来,然后返回连接后的字符串:
打印拼接数组,使用特定的字符串连接
var arr = ['A', 'B', 'C', 1, 2, 3] arr.join('-'); 'A-B-C-1-2-3'
注意:如果 Array 的元素不是字符串,将自动转换为字符串后再连接。
-
9.splice()——splice() 方法是修改 Array 的“万能方法”,它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素
会改变原来的数组
var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle']; // 从索引2开始删除3个元素,然后再添加两个元素: arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite'] arr;['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle'] // 只删除,不添加:arr.splice(2, 2); ['Google', 'Facebook'] arr; ['Microsoft', 'Apple', 'Oracle'] // 只添加,不删除: arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何arr; ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
-
10.多维数组——如果数组的某个元素又是一个Array,则可以形成多维数组
var arr=[[1,2,3],[200,900,877],'-']//上述Array包含3个元素,其中头两个元素本身也是Array//通过索引取到500这个值arr[0][2]3arr[1][1]900arr[2]'-'
3.3、对象
-
JavaScript的对象是由若干键值对组成的
var 对象名 = { key: 'value', key: 'value', key: 'value' } //定义一个对象名为person的对象,有6个属性 var person = { name: '小明', birth: 1990, school: 'No.1 Middle School', height: 1.70, weight: 65, score: null }
-
在JavaScript中,{………}表示一个对象,键值对描述该对象的具体属性XXX:XXXX,多个属性之间使用逗号隔开,最后一个属性不加逗号!
在JavaScript中所有的键都是字符串,值都是任意对象!
-
对象操作
//定义 let person = { name : "张三", tags : ['吃饭','睡觉','打豆豆'] } //由于JavaScript的对象是动态类型,则可以自由的给一个对象添加或删除属性
1.对象赋值
-
person.name = "张三" "张三" //取值 person.name "张三" //取一个不存在的对象属性,不会报错!会显示::undefined
2.动态的删减属性
-
-
2.1删除属性
-
delete person.name true
-
2.2添加属性 ( 直接给新的属性添加值即可 )
person.sex='男' //取值 person.sex'男'
-
3.判断属性值是否在这个对象中:XXX in XXX
'age'
in persontrue
true
//继承
'toString' in person
ture
4.判断一个属性是否是这个对象自身拥有的
hasOwnProperty()
person.hasOwnProperty("tostring")
falseperson.hasOwnProperty("sex")
true
3.4、流程控制
// if 判断
var age = 3;
if (age >= 18) {
alert('adult')
}
else if (age >= 6) {
alert('teenager')
}
else {
alert('kid')
}
// while循环
var a = 3
while(a < 10){
a ++;
console.log(a);
}
4,5,6,7,8,9,10
//避免while死循环
while(true){
alert(123)}
//do..while循环
var n = 0;
do { n = n + 1;
}
while (n < 100)
n 100
// for循环
for(let i = 0; i < 10; i++){
console.log(i);
}
0,1,2,3,4,5,6,7,8,9,10
//forEach循环
var age=[12,22,33,4,100,23,67,88];
//函数
age.forEach(function(value){
console.log(value)
}
12,22,33,4,100,23,67,88
//for in 可以把一个对象的所有属性依次循环出来
var person = {
fame:"John",
lname:"Doe",
age:25
};
var text = "";
var x;
for (x in person) {
text += person[x] + " ";}'John Doe 25 '
// for in 遍历下标(索引)
var arr=[3,4,5]
for(var x in arr){
console.log(x)}
0,1,2
//for in 遍历得到值
var arr=[3,4,5]
for(var x in arr){
console.log(arr[x])}
3,4,5
//通过for of遍历值
var arr=[3,4,5]
for(var x of arr){
console.log(x)}
3,4,5
3.5Map和Set
ES6中增加了Map和Set
-
Map是一组键值对结构,具有极快的查找速度
//假设要根据同学的名字查找对应的成绩,如果用Arry实现,需要两个Array var names = ['Michael', 'Bob', 'Tracy']; var scores = [95, 75, 85]; //需要先在names中找到对应的位置,再从scores取出对应的成绩,Arry越长,耗时越长
如果用Map实现,只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢
var map = new Map([['tom',90],['bob',87],['haha',60]]); var name = map.get('tom'); console.log(name);90
-
Map的相关操作方法
let map = new Map([['1',"小明"],['2',"小华"],['3',"张三"]]); map.get('3'); 张三//删除元素 map.delete('1'); mapMap(2) {'2' => '小华', '3' => '张三'}// //存在就修改,不存在就添加 map.set('6',"kuangstudy"); Map(3) {'2' => '小华', '3' => '张三', '6' => 'kuangstudy'} //遍历 mapfor (let x of map){ console.log(x); } (2) ['2', '小华'] (2) ['3', '张三'] (2) ['6', 'kuangstudy'] //是否存在 key'Adam'map.has('Adam') false
由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉:
var m = new Map(); m.set('Adam', 67); m.set('Adam', 88); m.get('Adam'); 88
-
-
Set:与Map类似,也是一组key的集合,但不存储value,在Set中没有重复的key
-
Set是无序不重复的集合
var s1 = new Set(); // 空 Set var s2 = new Set([1, 2, 3]); // 含1, 2, 3
-
重复元素在 Set 中自动被过滤:
var s = new Set([1, 2, 3, 3, '3']); s; // Set {1, 2, 3, "3"}//注意:数字3和字符串"30"是不同的元素
-
Set的相关操作方法
var set = new Set([1, 2, 3]); //通过 add(key) 方法可以添加元素到 Set 中,可以重复添加,但不会有效果:set.add(4); set; Set {1, 2, 3, 4} set.add(4); set; //仍然是 Set {1, 2, 3, 4} //遍历 setfor (var x of set){ console.log(x)}1,2,3,4 //通过 delete(key) 方法可以删除元素: var s = new Set([1, 2, 3]); s.delete(3); s; Set {1, 2}
3.6 Iterable
遍历 Array 可以采用下标循环,遍历Map 和 Set 就无法使用下标。
-
遍历集合
var a = ['A','B','C']; var s = new Set(['A','B','C']); var m = new Map([[1,'x'],[2,'y'],[3,'z']]); for (var x of a){ //遍历Arry console.log(x)} ABC for (var x of s) { // 遍历Set console.log(x); } ABC for (var x of m) { // 遍历Map console.log(x[0] + '=' + x[1]); } 1=x2=y3=z
-
更好的方式是直接使用 iterable 内置的 forEach 方法,它接收一个函数,每次迭代就自动回调该函数
//以 Array 为例a.forEach(function (element, index, array) { // element: 指向当前元素的值 // index: 指向当前索引 // array: 指向Array对象本身 console.log(element + ', index = ' + index); });
-
forEach() 方法是ES5.1标准引入的,需要测试浏览器是否支持。
-
Set 没有索引,因此回调函数的前两个参数都是元素本身:
var s = new Set(['A','B','C']);s.forEach(function (element,sameElement,set){ console.log(element)})ABC
-
Map 的回调函数参数依次为 value 、 key 和 map 本身:
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]); m.forEach(function (value, key, map) { console.log(value);});xyz
4. 函数
方法:对象 (属性,方法)
函数:
方法和函数本质上是一样的,只是放置的位置不一样
4.1 定义函数
定义方式一
绝对值函数
function abs(x){
if(x >=0){
return x;
} else{
return -x;
}
}
一旦执行到return代表函数结束,返回结果!
如果没有执行return,函数执行完也会返回结果,结果就是undefined
定义方式二
var abs = function(x){ if(x >= 0){ return x; }else{ return -x; }};
function(x){………}这是一个匿名函数,将结果赋值给abs,通过abs可以调用函数!
方式一和方式二等价!
调用函数
调用函数时,按顺序传入参数即可:
abs(10)10abs(-22)22
- 由于JavaScript传入任意多个参数也不影响调用,因此传入的参数比定义的参数多也没有问题,虽然函数内部并不需要这些参数:
abs(10, 'blablabla');// 返回10 abs(-9, 'haha', 'hehe', null); // 返回9
- 传入的参数比定义的少也没有问题:
abs()//返回NaN//此时ans(x)函数的参数x将收到undefined,计算结果为NaN
- 假如参数不存在如何规避?——手动抛出异常来判断:
function abs(x) { if (typeof x !== 'number') { throw 'Not a number'; } if (x >= 0) { return x; } else { return -x; } }
arguments
-
arguments 是JavaScript中免费赠送的关键字,只在函数内部起作用,并且永远指向当前调用者传入的所有参数
-
利用 arguments ,可以获得调用者传入的所有参数。也就是说,即使函数不定义任何参数,还是可以拿到参数的值
-
实际上 arguments 最常用于判断传入参数的个数
abs(-10,-12,-13); //只有定义了的参数才会生效 // arguments:代表传递进来的所有参数,是一个数组 function abs(x){ for(let i of arguments){ console.log(i); } if(x >= 0){ return x; } else{ return -x; } }
rest参数
-
ES6引入了rest参数,主要用以获取除了已定义的参数之外的参数
function foo(a, b, ...rest) { console.log('a = ' + a); console.log('b = ' + b); console.log(rest); }foo(1, 2, 3, 4, 5); // 结果: // a = 1 // b = 2 // Array [ 3, 4, 5 ] foo(1); // 结果: // a = 1 // b = undefined // Array []
-
rest参数只能写在最后,前面用 … 标识,从运行结果可知,传入的参数先绑定 a 、 b ,多余的参数以数组形式交给变量 rest ,所以,不再需要 arguments 就获取了全部参数。
4.2变量的作用域
变量的作用域
-
在JavaScript中,用var声明的变量实际上是有作用域的
-
在函数体内声明的变量,在函数体外不可以访问
'use strict' function foo() { var x = 1; x = x + 1; } x = x + 2; // ReferenceError: x is not defined//无法在函数体外引用变量x
-
访问不存在的变量名会报 xxx is defined
function abs(x) { var a = 1; } a = a +2; //报错:ReferenceError:a is not defined
-
如果两个函数使用了相同的变量名,只要在各自的函数内部,就不冲突;换句话说,不同函数内部的同名变量相互独立,互不影响;
function qj(){ var x = 1; x =x + 1;} function qj2(){ var x = 'A'; x = x + 1;}
-
内部函数可以访问外部函数的成员,反之则不行!
function qj(){ var x = 1; //内部函数可以访问外部函数的成员,反之则不行 function qj2(){ var y = x + 1; //2 } var z = y + 1; //Uncaught ReferenceError: y is not defined}
-
假设,内部函数变量和外部函数变量重名
function qj() {
var x = 1;
function qj2() {
var x = 'A';
console.log('inner'+x);
}
console.log('outer'+x);
qj2();}qj()
//返回的结果:outer1innerA
假设在JavaScript中 函数查找变量从自身函数开始,由“内”向“外”查找,假设外部存在这个同名的函数变量,则函数会屏蔽外部函数的变量。
变量提升
-
JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部:
'use strict'; function foo() { var x = 'Hello, ' + y; console.log(x); var y = 'Bob'; }foo(); //结果:Hello, undefined //说明 y 的值为 undefined //这正是因为JavaScript引擎自动提升了变量 y 的声明,但不会提升变量 y 的赋值。
-
对于上述foo()函数,JavaScript引擎看到的代码相当于:
function foo(){ var y; var x = 'Hello,' + y; console.log(x); y = 'Bob'; }
-
由于JavaScript这一特性,我们在函数内部定义变量时,要严格遵守规范:在函数内部首先申明所有变量。最常见的做法是用一个var声明函数内部用到的所有变量:
function foo() { var x = 1, // x初始化为1 y = x + 1, // y初始化为2 z, i; // z和i为undefined // 其他语句: for (i=0; i<100; i++) { ... } }
4.3 全局对象 window
-
实际上,JavaScript默认有一个全局对象 window ,全
局作用域的变量实际上被绑定到 window 的一个属性:
'use strict'; var course = 'Learn JavaScript'; alert(course); // 'Learn JavaScript' alert(window.course); // 'Learn JavaScript
因此,直接访问全局变量course 和访问 window.course 是完全一样的
-
因此,顶层函数的定义也被视为一个全局变量,并绑定到 window 对象:
'use strict'; function foo() {